Trust Gateway
Home/Guides/Fulfilment
TRUST GATEWAY GUIDE

UPI Payment Succeeded but Delivery Failed: Recover the Order Without Charging Twice

Separate verified payment from shipment, email or digital delivery so a failed worker can retry the benefit without starting another charge.

A payment can be verified while your application fails to send a licence, email, booking confirmation or shipping request. Treat that as a delivery incident, not a failed payment. Asking the customer to pay again makes the problem worse and can create a duplicate charge.

Track payment and fulfilment separately

Your local purchase should have a payment state and a fulfilment state. For example, payment may be verified while fulfilment is queued, processing, completed or needs review. Keep the saved gateway order ID, exact payable amount and verified time. The gateway reports on its payment order; it cannot know whether your email provider delivered a message or your warehouse printed a label.

Do not overwrite a verified payment with “pending” merely because a downstream worker crashed. That destroys the evidence support needs. The payment status guide explains gateway states; add your own delivery states beside them.

Commit a single delivery task

After authenticated order status confirms the saved order and exact amount, use a database transaction to mark the purchase paid and create one delivery task. A unique key based on the gateway order ID or local purchase ID prevents repeated webhooks and manual checks from enqueuing duplicates. If possible, use an outbox record written in the same transaction so a process crash between “paid” and “queued” cannot lose the job.

The delivery worker should be idempotent too. Before issuing access or shipping another item, check whether the fulfilment record already exists. When an external provider supports idempotency keys, reuse a stable key for retries. A successful payment may legitimately trigger several notifications; those notifications should converge on one business outcome.

Retry the failed step, not the payment

Separate transient failures from permanent ones. A mail provider timeout may merit a bounded retry; an invalid address needs customer correction. Store attempts, timestamps and error categories while keeping API keys and personal data out of broad logs. After retry limits, move the task to staff review with the purchase ID and verified payment reference.

If your application sent a request to an external fulfilment provider but did not receive a response, check that provider's state before repeating the action. The delivery might already exist. The same uncertain-outcome principle applies to payment creation and fulfilment.

Tell the buyer the truth

Show “Payment received; delivery is being completed” when payment is verified and delivery is still pending. Give the buyer a support reference and a clear way to contact you. Do not display “payment failed” or a new Pay button for that purchase. If the delay exceeds your stated timeframe, have a human investigate and follow your published resolution policy.

For a digital licence, keep the key assigned to one purchase and allow secure re-display or re-send rather than generating a new key on every page refresh. For physical goods, ensure a retry cannot create a second shipment. The licence delivery guide covers one specific implementation.

Rehearse the failure path

  • Kill the worker after marking payment verified but before delivery.
  • Return an email-provider timeout after the message was accepted.
  • Deliver the same verified event twice.
  • Let a customer reload the success page repeatedly.
  • Correct a permanent address error and retry only the delivery.

Reconcile paid-but-unfulfilled purchases daily and measure their age. This turns a silent failure into a support queue while preserving the original payment record.