Payment timeouts and unknown statuses: what to do when a provider does not answer
A timeout means you do not know what happened, not that the payment failed. The provider may have completed it after the connection dropped. Hold the order as pending, tell the customer you are checking, and do not start a new payment. Retry only with the same idempotency key, then confirm by webhook or a status check. If a payment turns out approved after you gave up on it, reverse it. Anything still unknown goes into a reconciliation queue with a named owner.
In 30 seconds
- A timeout is an unknown result, so treat it as pending until a webhook or status check confirms the outcome.
- Starting a new payment attempt before the first is resolved is how a timeout turns into a duplicate charge.
- Keep a queue of unknown payments with an owner, and clear it against provider records.
- 9 sources cited
On this page8 sections
A provider that declines a payment has given you an answer. A provider that says nothing has not. When a request times out, your system has to act without knowing whether the customer’s bank approved, refused or never saw the payment. The instinct is to show an error and let the customer try again. That is how a technical blip turns into a double charge and a support ticket.
This article explains what an unknown status means, why not to show failure too early, where duplicate charges come from, how to run status checks, what to do when an approval arrives late, and how to reconcile what is left. It assumes you already use idempotency keys and webhooks; our article on webhooks and idempotency covers how they work.
What does an unknown payment status mean?
It means you sent a request and have no usable result. Stripe’s documentation describes the case well: a connection can close before your client receives a response, and restoring connectivity does not tell you whether the original request succeeded. You might not know whether Stripe received or executed it. The same page says to treat a 500 error as indeterminate, because the operation might have had side effects even though you received an error.
A timeout can happen at more than one point:
| Where the answer was lost | What may have happened |
|---|---|
| Between you and your provider or orchestrator | The request may never have arrived, or it may have completed in full |
| Between the orchestrator and the provider | The provider may have the payment while your layer has no result |
| Between the provider and the acquirer or issuer | The provider may still be waiting, and can report late |
Separate this from a payment that is pending by design. Adyen describes Pending as a payment received with no final status yet, common with asynchronous methods. With OXXO in Mexico, for example, the customer pays later, in a store. Pending is an answer. Unknown is the absence of one.
Why is a timeout not a failed payment?
Because the money can still move. Gr4vy’s guide says it plainly: a timeout does not automatically mean the payment has failed, only that the connection dropped before a definitive response arrived. Razorpay documents one form of this, the late authorised payment. It says less than 0.5% of total payments are late authorised, and that other gateways face the same interruptions. That is one provider’s figure, not an industry benchmark.
Even a success code is not always final. Adyen says a 200 response means it processed the request, not necessarily that the payment or modification succeeded, with the outcome arriving by webhook.
Showing failure too early has three costs:
- The customer sees an error while their bank shows a hold or a charge, and contacts their bank or your support team.
- The customer pays again, and now two payments exist.
- You cancel the order, then the approval arrives, and you hold money for nothing.
Our article on decline messages at checkout deals with payments that really were refused. An unknown status needs different wording.
What should the customer see?
Say what you know. Adyen’s guidance for its Received and Pending codes is to tell the shopper you have received the order and are waiting for the final payment status. That works for unknown results too.
| Your state | What to show | What to do with the order |
|---|---|---|
| Unknown, just timed out | “We are confirming your payment. Please do not pay again.” | Hold as pending; keep stock reserved if you can |
| Provider reports pending | “We have your order and are waiting for the payment to complete.” | Hold as pending |
| Confirmed approved | Normal confirmation | Fulfil |
| Confirmed refused | Clear decline message, with another way to pay | Release, or keep the basket open |
| Still unknown after your limit | “We could not confirm this payment. You will not be charged for this order.” Say this only if you can make it true | Cancel, and reverse anything that later appears |
Razorpay frames the choice by what you sell. If you can deliver later, mark the order as pending and fulfil once the payment is authorised. If you cannot, treat the order as cancelled and tell the customer. A limited-stock item may fall into the second group, and an ordinary parcel into the first.
Keep the customer on a page that updates itself, send an email when the result is known, and make sure your support team can see the same status. Disable the pay button once it has been pressed.
How does a retry turn into a duplicate charge?
Three paths lead there.
A new request with a new key. Stripe says not to retry with a new idempotency key until you have resolved the original outcome, because a new key can start a second operation. Retries with the same key and parameters are safe, within limits. Gr4vy draws the same line: reuse the key after a gateway timeout, and use a new one only for a genuine customer retry on the same order.
The customer pressing pay again. Your idempotency key protects a repeated request, not a second payment the customer chose to make. If your checkout creates a fresh attempt, the key does not help. Tie attempts to the order, and block a new one while an earlier one is unresolved.
A second provider. Moving an unanswered payment to the next route looks like resilience. Mastercard’s guidance for its Send product says not to send the transaction through another channel or payment system after a timeout. Our outage playbook makes the same point: hold anything with an unknown outcome instead of rerouting it. An explicit rejection is different from silence, and your failover design should treat them differently.
There is a trap in orchestration too. Gr4vy says that where a provider connection supports idempotency, the transaction stays in processing while it retries in the background. Without that support, the transaction ends as failed with a timeout code, later results are not applied, and you should check the payment service before charging the customer again. Ask every layer in your stack which behaviour applies.
Duplicates have a price. Visa’s rules allow an issuer to raise a dispute when a single transaction was processed more than once with the same credential, on the same date and for the same amount. Our guide to chargeback management covers how those count against you.
Example figures, for illustration only. A store takes 80,000 card payments a month and 0.2% time out, or 160. If a quarter of those had actually completed and customers paid again, 40 customers are charged twice. At USD 70 each, that is USD 2,800 to return, plus 40 support tickets and possible disputes.
How should status checks work?
Webhooks first, status checks as the backstop. Gr4vy recommends webhooks because they give the final state without repeated polling, with polling as the fallback. Stripe says to prepare webhook handlers for objects your integration never received in an API response, and to put a local identifier in each request so you can match them.
A workable order for one unanswered payment:
- Mark it unknown. Store your order reference, amount, currency, provider and time. Never overwrite it with failed.
- Wait for a webhook. Give it a short window.
- Retry the same request, if the provider supports it. Use the same key and parameters. Do not change the amount.
- Check status by your reference. Back off between checks, with random jitter, so you do not add load during an incident.
- Stop at your limit. Move the payment to the reconciliation queue with an owner.
- Decide once. Fulfil, cancel or reverse, then record who decided and why.
Published limits differ, so read each provider’s documentation.
| Provider | What it says | Key limit or schedule |
|---|---|---|
| Stripe | Retry with the same key within 24 hours; after that, reconcile and contact support if unresolved | Keys kept for at least 24 hours |
| Adyen | Safe to retry a timed-out request with the same key | Keys valid for 7 to 14 days |
| Mastercard Send | Wait 40 seconds, then GET status with back-off | After 30 minutes, use research tools or daily reports |
| Gr4vy | Poll with exponential back-off and jitter | Report anything unknown for more than 24 hours |
Mastercard Send is a push payment product, so treat its schedule as a good example, not a card acceptance rule. It also warns that too many requests in a short time can trigger rate limiting, which is the last thing you want during an incident.
What if the approval arrives after you gave up?
Undo it properly. Visa’s rules say an acquirer must process a reversal if the acquirer, merchant or acceptance device did not receive an authorisation response. Where an approved payment is not completed, a merchant must submit an authorisation reversal within 24 hours of the cancellation or of the customer deciding to pay another way. For point-of-sale transactions outside Europe, Visa’s rules also say a transaction must not time out in less than 15 seconds, and that a merchant receiving an approval after a timeout must reverse it. That rule is worded for POS, so ask your provider how it treats online payments.
Providers handle this in different ways. Adyen’s classic API has a technical cancel that works from your own reference when a timeout has left you without its payment reference, valid for 24 hours after authorisation, though that endpoint is no longer supported for new integrations. Razorpay automatically refunds late-authorised payments that are not captured, within 5 working days excluding bank processing time. Find out which applies to you, and whether a held amount clears by itself.
How do you reconcile unknown payments?
Treat them as their own work queue. Every item needs a status, an age and an owner. Gr4vy suggests a report of transactions unknown for more than 24 hours, then a support ticket with your identifier, amount and time for each.
Run the queue daily and match three things: your order, the provider’s record and the settlement file. A payment that appears in a settlement report is a completed payment, whatever your system says. Our guide to payment reconciliation across PSPs sets out the matching model. Stripe notes that during incident recovery it attempts to reconcile failed operations and sends webhook events for anything created, but says this is not guaranteed to resolve every operation, so plan for late events and for gaps.
After any incident, review the numbers: how many payments went unknown, how many later proved approved, how many were reversed, and how long they stayed open. Those figures tell you whether your timeouts and waiting periods are right.
How does Omno help with unknown payment statuses?
Omno keeps a full transaction trail for each payment: every attempt, cascade step, provider response and webhook. That gives support and finance one place to see what was sent, to whom, and what came back when a status is in doubt. In routing, if a provider is unavailable or rejects the request, the payment moves to the next provider in the rule until one accepts. The reporting and analytics page shows what the trail contains.
Key facts
- Stripe's documentation says restoring connectivity does not tell you whether the original request succeeded (Stripe docs, 2026).
- Stripe limits retries of an unresolved operation to 24 hours with the same key and parameters, then says to reconcile instead (Stripe docs, 2026).
- Mastercard Send's guidance is to wait 40 seconds, then check status with back-off, and use research tools or daily reports after 30 minutes (Mastercard Developers, 2026).
- Razorpay says less than 0.5% of its payments are late authorised (Razorpay docs, 2026).
- An acquirer must process a reversal if the acquirer, merchant or device did not receive an authorisation response (Visa Rules, 2026).
- Visa lets issuers raise a dispute when a single transaction was processed more than once on the same date for the same amount (Visa Rules, 2026).
Changelog
- First published.
Sources
9 references
- Advanced error handling, Stripe
- Timeouts, Gr4vy
- Exception management, Mastercard Developers
- Result codes, Adyen
- API idempotency, Adyen
- API response handling, Adyen
- Cancel, Adyen
- Handle late authorised payments, Razorpay
- Visa Core Rules and Visa Product and Service Rules (24 October 2026), Visa