Authenticate before changing an order
Follow the gateway's documented verification method for callbacks. A signature may cover selected canonical fields rather than the raw JSON body; reproduce the exact documented input with the correct secret and compare the result safely. Never accept a browser-submitted “paid” flag as a webhook. Compare the event's order reference and amount with your stored order.
Make updates idempotent
Callbacks can be retried when the sender does not receive a response. Use a unique event ID or a stable combination of provider reference and status to detect repeats. In one database transaction, record the event and transition the order only if it has not already reached that state. Fulfilment should happen once even if the same notification arrives several times.
Respond and investigate
Return a success response after your database accepts the event. Move slow work such as email or fulfilment to a queue if available. Log enough context to diagnose failures, but exclude API secrets and full sensitive payment data. If verification is uncertain, leave the order pending and reconcile through the status API or merchant record.
