IDEAS. SYSTEMS. POSSIBILITIES.
Insights4 min read

Payment Webhooks: Keep One Purchase From Becoming Two Orders

A payment notification can arrive more than once. Protect order fulfilment with verified payment status, duplicate checks and a recovery plan.

AI-generated conceptual flat lay of repeated payment notifications, a checked order ledger and one shipping parcel on a green desk.
Original AI-generated concept image illustrating duplicate notifications and one fulfilled order; not a customer scene or official product screenshot.

In brief

Verify payment on the server, make repeated notifications harmless, and record each fulfilment step. Safe retries and reconciliation help a confirmed purchase reach the right outcome without repeating work unnecessarily.

1. Confirm payment on the server

A customer pays once, but the warehouse receives two packing requests. Another pays successfully, closes the browser and never receives access to their purchase. These are useful scenarios to test before launching checkout.

A webhook is a notification sent from one system to another. For payments, it can tell your website that something has changed. A thank-you page should not be the only trigger for delivering an order: a customer might lose their connection before returning to your website.

Stripe’s Checkout guidance uses webhooks for reliable fulfilment and tells developers to retrieve the Checkout Session and inspect its payment status. Some payment methods confirm later, so completing checkout does not always mean payment is confirmed.

Define the release rule explicitly: which verified status allows goods, account access or a booking to be delivered? Check that the payment belongs to the expected order and matches its amount and currency. Keep payment status separate from delivery status so staff can see what remains unfinished.

    2. Make repeated notifications harmless

    Stripe documents that webhook events may be delivered more than once and need not arrive in their original order. Your website should verify webhook signatures before acting and track processed event identifiers.

    Add a second safeguard around the business action itself. The same purchase should not create another packing request simply because a different event or recovery job reaches it.

    Ask your developer how the system handles two requests arriving simultaneously. A simple check-then-create sequence can allow both requests through. A database-enforced unique reference or atomic status change can protect the fulfilment operation. Choose a reference tied to the intended action, such as the order’s initial shipment, rather than blocking every future action for that customer.

      3. Separate receiving from doing

      Keep the webhook receiver focused: verify the notification, store it durably or place it in a durable queue, then acknowledge receipt promptly. Perform slower tasks in a worker that can resume after a failure.

      Updating your order record, reserving stock and requesting courier collection are separate steps. Record each step’s outcome instead of treating the entire journey as one invisible operation.

      If the courier accepts a request but your connection drops before its response arrives, blindly sending another request could create another collection. Check the courier’s supported lookup or duplicate-protection mechanism first. If its outcome cannot be established safely, send the order for review.

        4. Use idempotency where the API supports it

        Idempotency means a repeated request can be recognised as the same intended operation.

        Stripe supports idempotency keys for API requests, with behaviour that depends on the API version. Keys also have retention rules, so they are not a permanent substitute for your own order records.

        Use the same key when retrying the same operation, following the provider’s documentation. Do not assume a payment API’s idempotency key also protects your warehouse, email or accounting integration. Each external action needs its own duplicate-handling plan.

          5. Test recovery and reconcile unfinished orders

          Before launch, ask your team to demonstrate the failure scenarios below.

          Then add reconciliation: regularly compare confirmed payments with internal orders and fulfilment records. Flag paid-but-unfulfilled purchases and uncertain delivery outcomes for a named person to review. Recovered work should pass through the same safeguards as live notifications.

          If your checkout connects several operational tools, our Custom Software Development and Web Development services are relevant starting points. Start with one practical requirement: every confirmed purchase should have a traceable fulfilment outcome, without repeating work unnecessarily.

          The implementation checklist here is MIRA CODE’s engineering guidance. Provider-specific behaviour is drawn from the official Stripe documentation below, checked on 2 November 2026.

          • The same payment notification arriving twice.
          • Two workers handling the same purchase together.
          • A delayed payment confirmation.
          • A service failing halfway through fulfilment.
          • A successful external action followed by a lost response.

          Further reading

          CONNECT THE IDEA TO YOUR BUSINESS

          Custom Software DevelopmentWeb Development

          A GOOD PLACE TO START

          An idea worth talking about?

          Tell us what you want to build, connect
          or make easier to run.