Payment Webhooks Out of Order: Preventing Stale Status Updates
By PayEurasia Team · 11 October 2026 · 4 min read
Last updated 11 October 2026

Handle late and concurrent payment webhooks without overwriting verified outcomes. Learn state checks, event deduplication and recovery tests.
Header image: conceptual illustration.
A payment succeeds, the order is credited, and then an older notification arrives describing an incomplete attempt. If the latest-arriving message simply overwrites the order, the merchant can incorrectly reopen a paid order. Concurrent workers can cause the same problem even when messages reach the server in a sensible sequence.
The solution is not to make webhook delivery look perfectly ordered. It is to make the payment record safe when delivery is delayed, duplicated or concurrent. This guide addresses that specific state-management problem rather than the basic setup covered in the merchant webhook guide.
Delivery order is not business order
Stripe documents that events are not guaranteed to arrive in the order they were generated. Its current guidance also warns that snapshot-event creation timestamps have second-level precision: different events can share a timestamp. Sorting on that field is therefore not a reliable business-state rule.
Keep three concepts separate: the time an event occurred, the time the merchant received it, and the verified state of the resource it concerns. Receipt time is useful for diagnosing delivery delays. It does not decide whether the customer has paid.
A payment attempt also has a different lifecycle from its order. An order may have an earlier failed attempt and a later successful attempt. A failure concerning the earlier attempt must not mark the entire order unpaid after the later payment was verified.
Establish the identities before changing state
Persist an authenticated event with the provider, merchant-account scope, environment, event identifier and payment-resource identifier. Resolve that resource to the intended attempt and order. If the mapping is absent or contradictory, place the event in an exception queue rather than attaching it to the nearest-looking order.
Authentication is necessary but insufficient for crediting. Verify the provider-defined successful final status and the expected merchant/account context, order reference, amount and currency. Record crediting idempotently, so repeated signals about one verified payment cannot create additional value.
Deduplicating event identifiers protects against repeated delivery. A separate ledger uniqueness rule protects the financial effect if two different events describe the same payment. These are complementary controls, explained further in the idempotency guide.
Resolve ambiguous transitions against the provider
Define allowed transitions for each provider resource rather than one universal ranking such as failed below pending below successful. Some statuses describe attempts; refunds and disputes describe subsequent operations. A successful original payment can later have a refund without becoming an unsuccessful original attempt.
When an event conflicts with a verified record, retrieve the relevant resource using the provider's supported server-side API. Compare the current authoritative state and linked operation identifiers. If the lookup fails, retain the last verified state, flag the conflict and schedule a bounded investigation. An unavailable lookup is not evidence that the older event is correct.
Avoid a read-then-write race between workers. Use transactional updates or a comparable concurrency control to protect the state decision and its ledger effect. Record why an event was applied, ignored as a duplicate, or held for investigation. Do not log raw sensitive payloads just to obtain that audit trail.
Worked hypothetical sequence
Invented example: Order DEMO-ORDER-A expects BDT 1,500. Attempt A1 is incomplete. Attempt A2 later receives a verified successful status for the correct merchant, amount and currency. The merchant credits the order once against A2.
A delayed failure event for A1 then arrives. Its attempt mapping shows that it is not the resource that paid the order. The team records A1 as failed without reversing A2's credit. A repeated A2 success notification produces no additional credit because the original financial posting already exists.
If a third message claims a different amount for A2, the team does not choose whichever message arrived last. It queries the provider, holds the inconsistency for review and preserves the evidence needed to explain the decision.
Test checklist for stale and concurrent events
- Deliver an incomplete event after a verified success for the same resource.
- Deliver a failed earlier attempt after a successful later attempt for one order.
- Deliver identical events twice, then different events describing one financial effect.
- Start two workers together and confirm that only one credit is committed.
- Make the provider lookup unavailable and verify that the conflict stays unresolved rather than fabricated.
- Deliver a legitimate refund after success and confirm that it creates a separate adjustment.
- Verify unknown resource mappings do not fall back to amount-only matching.
Frequently asked questions
Should we discard every event older than the order update?
No. An older event can still contain relevant information about a separate attempt or operation. Use resource identity and verified state, not a blanket age cutoff.
Does a timestamp prevent duplicate crediting?
No. Timestamp checks, event deduplication and financial-effect uniqueness solve different problems. The ledger must independently prevent a second credit for the same verified payment.
Talk to PayEurasia
Working in a high-risk vertical across South Asia? We can probably help.
Request integration →