Safeguard
Security Guides•

A payment API call timed out. Did the charge go through?

A timeout means the outcome is unknown, not failed. Retry with the same idempotency key, or reconcile first, and never start a second payment blindly.

Safeguard Security Team
4 min read

A timeout does not tell you the payment failed. It tells you that you did not hear back. The safe response is to retry the same request with the same idempotency key, or to look the payment up and reconcile, before you create anything new. A fresh request risks charging twice.

Why a timeout is an unknown, not a failure

Your server sent a request. The provider may have received it, processed it, and sent a reply that never reached you. Or it may never have arrived. From your side the two cases look identical.

Payment provider documentation draws the same line. One provider's error handling guide separates three situations: parameters or authentication are wrong (fix the request), a payment is declined (ask the customer to act), and a connection fails or a request is still executing (retry safely with the same idempotency key and parameters). A server error that leaves the outcome unknown is a fourth case, and the guidance there is to reconcile the request before starting another operation.

What to do, in order

What you seeNext action
Authentication or validation errorFix the key or the request, then send again
Card declinedShow the decline reason and ask for another method
Connection dropped or request still runningRetry with the same idempotency key and same parameters
Server error, outcome unknownLook up the payment, reconcile, then decide

Steps for the unknown case:

  1. Generate the idempotency key before the first attempt and store it with the order, so a retry can reuse it.
  2. On timeout, retry with that same key and identical parameters. The provider compares parameters to the original request and returns an error if they differ.
  3. If retries keep failing, look up the object by the identifier you stored, or by metadata you attached, and read its real state.
  4. Only create a new payment after you have confirmed the first one does not exist or has failed.
  5. Mark the order as pending in your own system until the provider's event or lookup confirms the result.

The idempotency window matters

For that provider's API v1, saved results are kept for at least 24 hours, and keys can be pruned after that. If you reuse a key after pruning, a new request is generated. So a retry job that wakes up two days later should not assume the key still protects you. It should reconcile first.

Idempotency keys should be random enough to avoid collisions, such as a V4 UUID. The same documentation advises against sensitive values like email addresses as keys.

What to tell the customer

Do not show "payment failed" when you do not know. Show something like "we are confirming your payment", keep the cart, and disable the pay button for that order. Then send a confirmation or a clear failure once you know. The wording matters because a customer who sees "failed" will try again, and that is exactly how double charges happen.

Close the loop with webhooks and logs

Webhook events are the second signal. If the provider processed the payment, an event will usually follow even though your original call timed out. Treat the event as one input to reconciliation, not the only one. See how to handle duplicate and replayed webhook events and idempotency keys for payment APIs.

Log every attempt on your side with the order reference, the idempotency key and the outcome class. Your own logs help when the provider cannot log your request, for example when your keys were wrong. Keep card details and personal data out of those logs.

Where Safeguard fits

The payment SDK in your dependency tree is code you ship. Safeguard's SBOM and dependency scanning shows which version you run and flags known vulnerabilities, and you can try a free scan.

Quick check

Should I retry a timed out payment request?

Yes, but with the same idempotency key and identical parameters. That lets the provider return the original result instead of creating a second charge.

How long does an idempotency key stay protective?

In the provider documentation cited below, at least 24 hours for API v1, after which the key can be removed. After that window, reconcile instead of retrying.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.