Webhooks
Event-ийг найдвартай хүлээн авч, payload бүрийн гарын үсгийг шалга.
Webhook нь ямар нэг зүйл болоход — хамгийн чухал нь төлбөр амжилттай болоход —
Wire таны сервер рүү мэдэгдэх боломж олгоно. Зөвхөн checkout redirect-д хэзээ
ч бүү найд; баталгаажуулсан payment_intent.succeeded webhook-г үнэний эх
сурвалж болгон үзэж, server талд баталгаажуул.
1. Endpoint бүртгэх
Нийтийн HTTPS URL руу чиглэсэн webhook endpoint үүсгэ. Гарын үсгийн нууц
(whsec_… угтвартай) нь үүсгэх үед зөвхөн нэг удаа буцаагдана — аюулгүй
хадгал.
ep, err := client.WebhookEndpoints.Create(ctx, &wire.WebhookEndpointCreateParams{
URL: "https://yourshop.mn/webhooks/wire",
EnabledEvents: []string{"payment_intent.succeeded"},
IdempotencyKey: "wh-ep-1",
})
fmt.Println(ep.Secret) // whsec_... — shown only nowep = client.webhook_endpoints.create(
url="https://yourshop.mn/webhooks/wire",
enabled_events=["payment_intent.succeeded"],
idempotency_key="wh-ep-1",
)
print(ep.secret) # whsec_... — shown only nowconst ep = await wire.webhookEndpoints.create({
url: "https://yourshop.mn/webhooks/wire",
enabled_events: ["payment_intent.succeeded"],
idempotencyKey: "wh-ep-1",
});
console.log(ep.secret); // whsec_... — shown only nowcurl https://api.wire.mn/v1/webhook_endpoints \
-H "Authorization: Bearer sk_live_..." \
-H "Idempotency-Key: wh-ep-1" \
-d url=https://yourshop.mn/webhooks/wire \
-d "enabled_events[]=payment_intent.succeeded"Event нь verified ба enabled хоёулаа болсон endpoint руу л dispatch хийгдэнэ. Шинээр үүсгэсэн endpoint нь live event хүлээн авахаас өмнө verify хийгдсэн байх ёстой.
2. Гарын үсгийн header
Хүргэлт бүр WirePayment-Signature header авч явна:
WirePayment-Signature: t=1717000000,v1=5257a869e7ec...t— гарын үсэг үүсгэгдсэн Unix timestamp (секунд).v1— таны endpoint secret (whsec_…)-ээр key хийсэн,"<t>.<rawbody>"string дээрх hex-encoded HMAC-SHA256.
Гараар шалгахдаа: HMAC_SHA256(secret, t + "." + rawBody)-г тооцоолж, hex-encode
хийгээд v1-тэй constant time-аар харьцуул. Timestamp нь таны тэвчээрийн
хязгаараас гадуур байвал хүргэлтийг татгалз (SDK-ууд default-аар 300 секунд).
3. Handler дотроо шалга
Үргэлж raw, задлаагүй request body-гийн эсрэг шалга — эхлээд задалбал байтууд өөрчлөгдөж, гарын үсэг эвдэрнэ.
func handler(w http.ResponseWriter, r *http.Request) {
body, _ := io.ReadAll(r.Body)
event, err := client.Webhooks.Verify(
body,
r.Header.Get(wire.SignatureHeader),
endpointSecret, // whsec_...
)
if err != nil {
http.Error(w, "bad signature", http.StatusBadRequest)
return
}
if event.Type == "payment_intent.succeeded" {
// fulfill the order
}
w.WriteHeader(http.StatusOK)
}import wire
event = client.webhooks.verify(
request.body, # raw bytes
request.headers[wire.SIGNATURE_HEADER],
endpoint_secret, # whsec_...
)
if event.type == "payment_intent.succeeded":
... # fulfill the orderimport { SIGNATURE_HEADER } from "@buildry-wire/wire";
const event = wire.webhooks.verify(
rawBody, // unparsed request body (string or Buffer)
req.headers[SIGNATURE_HEADER.toLowerCase()],
endpointSecret, // whsec_...
);
if (event.type === "payment_intent.succeeded") {
// fulfill the order
}Шилдэг туршлага
2xx-ээр хурдан хариул, дараа нь хүнд ажлыг асинхроноор хий.- Idempotent бай — ижил event нэгээс олон удаа хүргэгдэж болно. Event
id-ээр давхардлыг арилга. - Server талд давхар шалга: үнэ өндөртэй захиалга биелүүлэхээс өмнө PaymentIntent-ийн статусыг API-аар баталгаажуул.