Few payment problems cause as much confusion as pending payments. The customer thinks they paid. Your system thinks they did not. Support is asked "was I charged?" and has no good answer. Someone in operations chases the order by hand.
Pending is not a bug in the payment. It is a gap in your system's knowledge. This article explains why it opens, how to close it and how to make sure it stays closed.
What pending really means
A payment is pending when the final outcome has not reached your system. It can still succeed, fail or expire. The issue is that you do not know which, and neither does the customer.
Pending is normal for some methods. Bank-based and cash-based options are slower by design, and many local methods involve a redirect and a return. It becomes a problem when nothing in your system resolves it.
Why payments get stuck
Most stuck payments come from a handful of causes.
The customer never returns
Many methods send the customer away from your site and back again. If they close the tab, lose signal or switch apps, they never come back to your confirmation page. If you rely on that return to learn the outcome, you never learn it.
A webhook is missed
Providers tell your server the result through webhooks. A webhook can be missed if your endpoint is slow, returns an error, is blocked by a firewall, uses a secret that has changed or was down during a deployment. If you do not recover from that, the payment sits there.
A timeout without recovery
A request to the provider can time out. The payment may have been created, or it may not. If your code treats the timeout as failure, or ignores it, you end up with a payment whose status you do not know.
Authentication is abandoned
For card payments, the customer may start authentication and walk away. The payment is left waiting for a step that will never happen.
Duplicate or out-of-order events
If events arrive twice or in a different order, a naive handler can overwrite a final state with an earlier one. A payment that was captured can look pending again.
Slow settlement methods
Some methods confirm slowly because of how the underlying system works. If your design expects an instant answer, these methods will always look stuck.
How to fix it
The cure is a design that always has a way to learn the outcome. Four elements do most of the work.
1. Model pending explicitly
Give pending its own state and decide what it means for each method. Record when the payment entered it and when you expect it to resolve. Hold stock, a seat or a booking for a sensible period, but do not fulfill the order.
2. Confirm outcomes server to server
Never treat the customer's return to your page as proof of payment. When they come back, ask the provider for the payment's status from your server. When they do not, rely on webhooks and on status checks that you trigger yourself.
3. Handle webhooks safely
- Verify the signature of every event.
- Respond quickly, then process.
- Make processing safe to repeat, so duplicates do nothing harmful.
- Ignore events that would move a payment backward from a final state.
- Log each event with the payment identifier.
4. Run a reconciliation job
This is the safety net. A scheduled job looks for payments that have been pending longer than they should, asks the provider for their current status and updates your records. It also catches payments that the provider has but your system does not.
The job should run often enough to matter and should alert someone when it finds a pattern, such as many payments from one method stuck at once.
Timeouts and retries
When a request times out, do not assume failure and do not blindly retry.
- Use an idempotency key on the original request.
- Check the payment's status with the provider.
- If it exists, continue from its real state.
- If it does not, retry using the same key.
This protects customers from duplicate charges while still recovering from the failure.
What the customer sees
A good pending experience reduces support load more than almost any other fix.
- Tell the customer clearly that the payment is being confirmed.
- Explain what happens next and what they should not do, such as paying again.
- Send a confirmation message when the outcome is known, whichever way it goes.
- Give support staff a view that shows the payment's real state and history.
What to monitor
Pending payments are a health signal. Track:
- The number and age of pending payments, by payment method
- How often the reconciliation job resolves a payment that webhooks missed
- Webhook failures and retry counts
- Orders that were fulfilled without a confirmed payment, and the reverse
A rise in any of these points to a specific cause, and you can fix it before customers notice.
Common mistakes
- Treating a redirect back to your site as proof of payment
- Using the browser as the source of truth
- Retrying without an idempotency key
- Letting a handler move a payment backward from captured to pending
- Having no process for payments that stay pending for days
- Giving support no way to see what happened
Special cases
Bank-based and cash-based methods
These methods confirm on the bank's or a collection point's schedule, not yours. Design them with a longer timeout, tell the customer plainly how long to expect, and give them a way to check the status. Do not treat the delay as a failure.
Subscriptions and recurring payments
A pending renewal can pause access or trigger a retry at the wrong moment. Decide how long you keep service running while a renewal resolves, and make sure a retry never overlaps with an attempt that is still unresolved.
Marketplaces and payouts
When money moves in more than one step, such as a customer payment followed by a payout, a pending payment upstream can hold up everything downstream. Keep each leg's state separate and release funds only on confirmed outcomes.
A walk through one case
Imagine a customer pays by redirect to their bank. They approve the payment, but their phone loses signal before the redirect returns to your site. Your confirmation page never loads.
With a weak design, the order stays unpaid in your system. The customer sees nothing. Support gets a message hours later.
With a sound design, the provider's webhook arrives and your server verifies it, then marks the payment as captured. If the webhook is also missed, the reconciliation job finds the payment pending past its timeout, asks the provider for its status and completes the order. The customer receives a confirmation by email either way. No one had to chase anything.
Where to go next
Pending payments are one of the failure points our payment gateway integration service is designed to prevent. If you are seeing them in a live system, our approval-rate optimization service includes a review of pending-payment handling. You can also read our integration checklist for the full list of what to build.
