Cookie settings
Flow AssemblyPLATFORM / CAPABILITIES / EVENTS

Build the question.
Then design the flow.

Transfer operations

Treat payment submission and outcome as separate facts

Build a state model that preserves uncertainty after a request is accepted or interrupted.

In this article

Build a state model that preserves uncertainty after a request is accepted or interrupted.

A payment request can leave your application before its final outcome is known. That gap is a normal design problem, not an excuse to show success prematurely or ask the customer to start again. Model the request lifecycle separately from the payment lifecycle so that uncertainty has a safe place to live.

Read the response at the right level

Moov’s events and statuses guide states that a successful HTTP response does not by itself establish payment success. It describes asynchronous responses and subsequent retrieval or event updates. It also distinguishes completion from later reversal. Your application should preserve these differences instead of translating every accepted request into “paid.”

Create an internal record before initiating the external operation. Give it a durable business purpose, intended amount, participant references, and a unique intent identifier. Then record each observation about the request and provider object. If communication stops, you still know what the user intended and where the uncertainty began.

Define evidence-based transitions

For each user-facing label, state the evidence required to enter it and the actions allowed while it is displayed. “Submitted” might mean the application recorded an attempt; “processing” might require an identified provider object. The exact mapping must follow the current contract. These labels are product vocabulary, not replacements for the provider’s raw state.

Keep raw observations available to authorized operators. A simplified customer view is useful, but deleting detailed state in favor of one friendly word makes incidents harder to investigate. Preserve the observation time and source, distinguish event time from processing time, and retain a history of meaningful changes.

Fictional worked example: the browser closes

At fictional Elm Tickets, a customer submits a $65 purchase and closes the browser before the page updates. The first design assumes a lost browser session means a failed payment. Its retry button would create a fresh purchase attempt whenever the customer returns.

The revised design finds the existing payment intent and recovers its recorded provider reference. If the outcome remains unresolved, the customer sees a waiting state and a reference they can use with support. The application does not create another movement merely because the browser failed to display the previous result.

In the tabletop exercise, an operator later observes an authoritative update and the order view changes accordingly. This is a fictional workflow discussion, not a report of an executed test. The $65 amount is arbitrary; the same uncertainty exists for larger or smaller payments.

Distinguish age from failure

A payment remaining unresolved longer than your expected interval deserves investigation, but age alone does not prove failure. Define an operational threshold that creates a review task. The task should ask an operator to recover current information, identify the rail and relevant details, and decide the next permitted action. It should not automatically fabricate a final outcome.

Likewise, decide how later changes affect fulfillment and accounting. If an order has already been fulfilled, a subsequent payment exception may require a separate business case rather than rewriting the historical order as if it never existed. An event history helps the team explain both what was known at the time and what changed afterward.

State-model checklist

  • Create a durable internal intent before the external request.
  • Separate request delivery from payment outcome.
  • Require evidence for every user-facing transition.
  • Preserve raw provider status and meaningful history.
  • Recover existing attempts after timeouts or browser interruption.
  • Use age thresholds for investigation, not invented failure.
  • Define how later exceptions affect fulfillment and accounting.

Do not overclaim finality

This article does not define every rail-specific status or promise when a payment becomes irreversible. Implement the current official response contract, consult the relevant rail documentation, and have business owners approve fulfillment rules. The useful deliverable is an explicit state model in which “we do not know yet” triggers recovery rather than a misleading success message or an unnecessary second payment.

Continue the workflow

Have a public source that changes this analysis? Suggest a correction. Please don’t send pay statements, tax forms, health or identity records, bank details or account credentials.