Webhooks connect an observed payment to your fulfillment logic. Because that connection can activate a subscription, release a download or mark an order paid, the receiving endpoint must authenticate events and remain correct when deliveries are delayed or repeated.
Authenticate the event before reading its meaning
A public webhook URL can receive requests from anyone. Your handler should verify authenticity before it trusts fields such as status, amount or merchant order number.
bestuPay signs the raw JSON request body with HMAC-SHA256 and the site's Webhook Secret. Recalculate the digest and compare it with the X-BestuPay-Signature header using a timing-safe comparison.
- Read and preserve the raw request bytes
- Keep the Webhook Secret on the server
- Reject missing or invalid signatures
Make processing idempotent
Reliable webhook systems retry delivery when an endpoint times out or returns an error. The same valid event can therefore arrive more than once, even after your first attempt succeeded.
Store the event ID in a table with a uniqueness constraint and perform the order update in the same transaction. If the ID already exists, acknowledge the retry without repeating fulfillment.
- Use the event ID as the deduplication key
- Protect the key with a database uniqueness rule
- Make external fulfillment repeat-safe where possible
Validate business fields
A valid signature proves that the event came from the expected sender, but your application still needs to validate that it belongs to the expected order.
Compare the merchant order number, payment ID, status and amount with the local record. Fulfill only the status your integration defines as successfully paid, and route exception states for review.
- Match the event to an existing local order
- Check currency and expected amount
- Reject impossible state transitions
Respond quickly and move slow work aside
Webhook delivery should not wait for email providers, inventory systems or other slow dependencies. Verify and persist the event, enqueue downstream work and return an HTTP 2xx response after acceptance.
If processing fails before the event is safely stored, return an error so delivery can be retried. Monitor repeated failures and provide a server-side status reconciliation path.
- Keep the synchronous handler small
- Record the processing result and error context
- Alert on repeated delivery failures
Test the failure paths
A webhook integration is not complete after one successful test. Send duplicate events, invalid signatures, old events and out-of-order status changes to verify that fulfillment remains correct.
Rotate the secret in a controlled test, confirm logs do not contain credentials and document how operators reconcile an order if the receiving application was unavailable.
- Test duplicates and timeouts
- Redact secrets from logs
- Document manual reconciliation without bypassing verification