How to route payments without charging twice

Build explainable, recoverable payment routing around eligibility, transaction state and idempotency.

Routing matches an eligible transaction to a suitable provider. It is more than a list of APIs to retry, and it should not send potentially chargeable requests to several providers concurrently to chase approval rates.

Filter for eligibility first

Start with whether the merchant and provider are approved for the business, then check country, currency, method, merchant category, limits, 3DS and credential support. API access is not permission to process an unapproved merchant through another account.

Tokens have a scope. One PSP’s token is not necessarily usable at another. Cross-provider use needs a supported vault, network token or migration arrangement, with clear PCI responsibilities. Do not copy raw card details to every provider.

Rank only the eligible providers

Compare approval, cost, latency, settlement, liquidity use and risk within the actual market and business segment. Begin with simple, explainable rules and adjust weights when there is enough evidence.

Do not compare headline approval rates from different customer populations. Record the segment, sample size and time window. Include outages, maintenance and throttling in health checks. Trial new rules on limited traffic with clear stop and rollback conditions.

Multiple attempts, one amount due

Separate the order, payment intent and provider attempts. The order represents the business, the intent controls the amount due and an attempt records each provider submission. Use a stable request identifier and follow that provider’s idempotency contract.

Provider idempotency does not extend across providers. A key at provider A cannot prevent a charge at B. Local locking or atomic state control must constrain active attempts on the same intent. Validate business references, amounts, currencies and provider references in asynchronous callbacks.

A timeout means unknown: query first

A response can time out after the bank has approved the payment. Switching immediately to B can produce two charges when A’s late success arrives.

A clear recovery sequence is to record an unknown result, query A using the original reference and reconcile callbacks and reports. Start another attempt only when the rules allow it and the previous attempt has been confirmed failed, cancelled or otherwise safely ended. Persistently unknown outcomes need investigation, not a cosmetic failure status.

If multiple charges do occur, record the exception and follow the applicable reversal or refund procedure, checking posted funds and fees. Disabling a frontend button does not provide financial consistency.

Decline reasons determine whether to retry

Distinguish hard declines, correctable conditions, authentication requirements, network failures and unknown results. A stolen-card or closed-account decline should not trigger blind cycling through providers. Insufficient funds is not permission for unlimited retries. Follow network, issuer and provider rules for timing, limits and indicators, and offer another method where appropriate.

Record the rule version, eligibility decisions, selection reason, decline reason, attempt identifiers, provider references and latency without exposing full card data or security codes. Assess final success together with duplicate charges, refunds, fraud and disputes to judge whether routing actually helps.

Continue with authorization and 3DS and fraud, disputes and chargebacks, or discuss payment channel integration. FuturePay and its developer documentation provide official capability references; the actual implementation must follow the relevant product contracts and rules.

Have a real use case in mind? Let’s talk.