Missing Payment Webhook: A Bounded Status-Recovery Workflow
By PayEurasia Team · 11 October 2026 · 4 min read
Last updated 11 October 2026

Recover a missing payment webhook with controlled provider status checks, durable pending records and safe escalation without duplicate crediting.
Header image: conceptual illustration.
An order remains pending, but the customer says the wallet application showed success. The merchant received no webhook. Repeatedly asking the customer to pay again would turn a delivery problem into a possible duplicate payment.
A status-recovery workflow should find the result of the existing attempt, not create a replacement attempt by default. It needs a durable pending record, a provider-supported lookup, bounded scheduling and an escalation path for uncertainty. It supplements the normal webhook integration; it is not a reason to abandon it.
First distinguish missing delivery from missing processing
Check whether the provider created the expected event, whether delivery reached the endpoint, and whether the merchant worker processed it. A webhook can be absent from the order history even though the receiving endpoint returned success. For example, a queue write may have failed or a worker may be paused.
Search using non-sensitive event and resource identifiers. Compare delivery time, acknowledgment and processing outcome. Do not infer payment failure from an empty webhook log. Likewise, an HTTP success response to a notification establishes delivery, not a successful customer payment.
Keep the pending record recoverable
At initiation, record the order, attempt, provider, merchant-account scope, environment, expected amount and currency, creation time and supported lookup identifier. Maintain separate last-check time, observed provider status, next-check time and exception reason.
A browser closing must not delete that server-side record. Neither should a customer refreshing the order page create a new payment. The status-recovery job should operate on the known attempt and keep a durable record of its decisions.
Define which provider statuses are terminal for the operation and which require action or further processing. Read the provider's method-specific documentation rather than translating every unknown value to failed.
Use a bounded fallback, not continuous polling
Stripe's status guidance recommends webhooks for asynchronous fulfillment and warns that repeated polling is less reliable and can trigger rate limits. A recovery job should therefore target aged unresolved attempts, limit concurrent requests and space checks according to documented limits.
Choose a business-specific age threshold rather than treating an invented number as a provider SLA. Increase the gap between checks where appropriate. Honor rate-limit instructions. Authentication failures require configuration investigation, not an endless loop. A not-found response requires checking environment and account scope before deciding whether the resource genuinely does not exist.
If a provider offers recovery of undelivered events, use its documented mechanism. Stripe's recovery guide describes listing undelivered events and preventing reprocessing. Recovered events must pass the same validation and idempotent processing path as ordinary delivery.
Validate the recovered result before crediting
A successful lookup must identify the expected merchant context and order or payment resource. Verify the successful final provider status, amount and currency before committing an idempotent credit. A signature on an earlier notification does not replace these checks.
SSLCommerz's published integration documentation explicitly requires transaction and amount validation through its Order Validation API. That is a provider-specific requirement, not a universal endpoint that exists for every wallet.
An inconsistent amount, ambiguous order mapping or unrecognized status belongs in manual review. Preserve the observed result and reason for the hold. Do not force a match just to clear a pending queue.
Worked hypothetical recovery
Invented example: A merchant has three unresolved attempts. DEMO-A has an authenticated lookup confirming successful payment for the expected order and BDT 900. DEMO-B is still processing. DEMO-C returns a configuration error because the job used the wrong environment.
A is credited once through the ordinary payment handler. B receives another scheduled check within the merchant's bounded policy. C is escalated to the integration owner; the customer is not instructed to pay again based on the configuration error. When a late webhook for A arrives, it changes neither the credit nor the amount.
The reconciliation process later checks these outcomes against provider records, providing a separate financial control rather than trusting the recovery queue alone.
Recovery acceptance checklist
- Pending attempts remain available after customers leave checkout.
- Lookups use the correct account, environment and documented identifier.
- The job has a concurrency cap, backoff and a maximum automated investigation horizon.
- Successful results use the same validation and crediting path as webhooks.
- Unknown and contradictory results remain visible with an owner and next action.
- Late notifications cannot double-credit a recovered payment.
- Finance can match recovered payments in the reconciliation workflow.
Frequently asked questions
Is no webhook the same as no payment?
No. Delivery and payment execution are separate. Query or reconcile the existing attempt using verified provider records.
When can the customer make a new attempt?
Only after the previous attempt's outcome permits it under the provider and merchant workflow. For bKash or Nagad guidance, a controlled new attempt must wait until the earlier one definitively failed or expired.
Talk to PayEurasia
Working in a high-risk vertical across South Asia? We can probably help.
Request integration →