Skip to main content
Bastion Research
Bastion Research Insights

Payment Operations

Payment Retries: Why a Timeout Is Not a Failed Payment

How to handle uncertain payment outcomes without creating duplicates: stable references, provider checks, webhook deduplication and operational recovery.

Bastion Research 7 min read Published Updated
On this page
One payment instruction with a recovery arrow and clock connects through a verification lens to a single confirmed result.
Resolve an uncertain outcome under the original instruction before creating another payment.

A customer submits a payment. The application waits for a response, then displays an error. The customer presses the button again. An operator, seeing the same error, also tries to help.

There may now be three attempts to solve one problem. If the provider accepted the first instruction before the connection timed out, another submission can create a second payment.

The missing response is a communication failure. It does not establish what happened to the money. A useful payment workflow keeps that uncertainty visible, gives every attempt a stable identity and provides a controlled way to discover the outcome.

This article sets out a practical design and evaluation approach. The examples are illustrative; the rules for a particular integration must come from that provider's contract and tested behaviour.

Separate rejection from an unknown outcome

Imagine a business sending an illustrative GBP 2,500 supplier payment. Its application records the instruction and sends it to the provider. The provider accepts it, but the response never reaches the application.

Two records now describe different parts of the same event. The local application knows that it attempted submission. The provider knows that it accepted an instruction. Until those records are connected, marking the operation as failed would overstate what the application knows.

Use separate outcomes for confirmed rejection, confirmed acceptance and an unresolved submission. The exact state names matter less than the actions they permit.

Evidence availableWhat the workflow should establish next
The instruction failed local validation before any provider call.Correct the input; no external payment was attempted.
The provider returned a documented, definitive rejection.Record the reason and follow the provider's correction or resubmission rules.
The connection timed out after submission may have begun.Resolve the original attempt before creating another instruction.
The provider confirms acceptance but settlement is pending.Continue tracking that payment; acceptance alone does not prove settlement.
A status lookup returns no record.Check the lookup scope, visibility delay and provider guarantees before treating absence as final.

An HTTP status alone may be insufficient to decide whether a payment can be resent. Document how each integration interprets responses, transport failures and status lookups. A generic retry policy should not override those decisions.

Give the instruction a stable identity

An instruction needs a durable internal identifier before the first external attempt. Link it to the provider account, amount, currency, recipient and external reference used for submission.

A retry of that instruction should preserve its identity wherever the provider supports this. Creating a fresh reference merely because the application restarted can turn recovery into a new payment.

Idempotency is the agreement that repeating an identified request does not repeat its intended effect. Its details are provider-specific. Stripe's idempotent request documentation, for example, describes matching parameters and a retention period after which an old key may no longer protect a request. Do not assume a different payment API has the same rules.

Distinguish a retry from a changed instruction. If the customer changes the recipient or amount, route that change through the appropriate approval and cancellation process. Reusing the original key with different payment details is not a sound way to amend a payment.

Amazon's discussion of idempotent APIs explains why a caller-provided identifier expresses intent more reliably than assuming identical payloads are duplicates. Two legitimate supplier payments can have the same amount and recipient. Their business identities still differ.

Persist enough information to recover after a restart

Recovery should work when the worker that made the request no longer exists. An in-memory flag or an operator's browser session cannot provide that guarantee.

Before submission, persist the instruction and the reference that will be sent. After each attempt, retain the evidence needed to decide what can safely happen next: when it ran, which provider connection it used and the last confirmed outcome. Keep credentials and unnecessary personal data out of that record.

Consider the interruption immediately after the provider accepted the payment but before the local result was saved. The next worker should find an unresolved attempt with its original reference. It can then query the provider or follow its documented idempotent retry procedure.

Concurrency deserves the same treatment. If a scheduled worker and an operator both request recovery, they should not independently submit a payment. Enforce the processing boundary with a durable concurrency mechanism and expose the same recovery action to both paths.

Make repeated notifications harmless

The outbound request is only one place where duplication can occur. A provider notification may be delivered again, or a worker may resume after partially processing it.

Stripe's webhook guidance explicitly discusses duplicate events and event ordering. For any provider, establish its notification contract rather than relying on one delivery in a preferred sequence.

The operational question is whether processing the same external event twice can post the principal, fee or customer notification twice. Deduplicating an HTTP handler is useful only if the underlying business effects are also protected.

Retain the provider event identity where available, link it to the original instruction and apply only valid state transitions. A delayed acceptance event should not silently replace a later confirmed outcome. If two sources disagree, preserve the evidence and route the conflict for investigation.

Give customers and operators a clear next step

A customer-facing status should describe what is known. For an unresolved submission, a message such as “We are checking the payment status. Please do not submit it again” is more useful than an error followed by an active Pay button.

The operator needs more detail: the original instruction, last provider interaction, provider reference, current financial position and permitted recovery actions. Separate Check provider status from Create a new payment. Those actions have different consequences and should be recorded distinctly.

Define how long an unresolved payment may remain unattended and who owns escalation. The customer should not have to repeatedly contact support to keep an investigation moving. The staff interface should show when a check last ran and when the next action is due.

Retries also affect balances. Decide how reservations behave while the outcome is unresolved, and explain that behaviour in the account view. Releasing a reservation merely because an HTTP request timed out can make funds appear available while an external payment is still processing.

Test the interruptions, then verify the money

A successful sandbox payment establishes the happy path. Recovery needs deliberate interruption tests with provider-approved test tools or controlled substitutes.

Include at least these scenarios:

  • The provider accepts an instruction, but the response is lost.
  • The application restarts before persisting the response.
  • Two workers attempt recovery of the same instruction.
  • The same notification arrives twice, followed by an older event.
  • A status lookup temporarily returns no result for an accepted instruction.
  • The provider's idempotency retention window has expired while a case remains unresolved.

For each scenario, inspect the resulting provider record, local instruction, reservations, ledger entries and fees. A green application status is not enough: the test should demonstrate the expected number of payments and accounting effects.

Recovery is complete when the original instruction has an explained outcome. If a separate correcting operation is required, link it to the case and give it its own authority and audit trail. Quietly issuing a replacement hides the distinction that the investigation was meant to resolve.

Bastion platform capabilities

How Bastion fits the evaluation

Bastion's Payments & FX, Core Banking & Ledger and Bank Operations, Reporting & Audit are relevant areas to examine when reviewing a payment workflow.

Bring the provider contract and one uncertain-outcome scenario to a demonstration. Trace the same instruction from submission through recovery and accounting, and record any connector-specific work needed. A capability shown for one provider should be verified separately for another.

Discuss your payment workflow or use the software evaluation guide to define a focused pilot.

Discuss the relevant module.

Modernization

Modernize Banking Software Without Replacing the Core

A better customer journey does not always require a new core. Start with one operation, make system ownership explicit and prove that old and new can work together.

7 min read

Read article
Digital Assets

Digital Gold: One Token, One Ounce, a Physical Foundation

A gold coin can remain in secure storage while its digital representation moves between holders. The useful product connects that convenience to verifiable backing and redemption.

7 min read

Read article
Platform Evaluation

How to Evaluate Banking Software: A Pilot That Tests Real Operations

Turn a banking software evaluation into a practical operating test. Follow one payment through customer actions, approvals, provider responses and reconciliation.

8 min read

Read article
Architecture

Multi-Entity Banking Platforms: What to Share and What to Separate

Shared software can serve several institutions or brands. The architecture must make it clear which entity owns each account, action, provider connection and financial record.

8 min read

Read article
Core Banking

How Ledger and Reconciliation Work Together

Learn how double-entry ledger, payment lifecycle, provider records and reconciliation work together in a modern banking platform.

8 min read

Read article
Architecture

Digital Banking Platform Architecture: How the Main Layers Fit Together

A practical guide to digital banking platform architecture: ledger, payments, integrations, operations, security and AI-assisted customer support.

9 min read

Read article