A payment can be paid and still unfinished
A pending refund and a dispute can race, giving the customer two credits while a single mutable status erases which movement occurred.
7 min read
A payment can be marked paid while the money is still moving—or has not moved at all. At checkout, “paid” may mean that the browser has returned payment credentials, the cardholder has authenticated, or the issuer has approved an authorization. Those are different events. The W3C Payment Request API’s complete() call closes the browser’s payment interface; the response still has to be processed or validated by the merchant. EMVCo likewise places cardholder authentication before the card network’s usual authorization process. 12
Even capture is not the end. A captured card payment continues into clearing and settlement. Later, a refund can send value back through a new flow, while a dispute can reverse some or all of the transaction’s value. 569 “Paid” is therefore a useful customer-facing summary, but a dangerous system-of-record state.
Paid is a projection
The durable object is not a boolean. It is a payment intent: a record that a specific order should collect a specific amount in a specific currency. That intent may survive several attempts, customer actions and network responses. Public payment APIs expose this shape directly; for example, Stripe’s PaymentIntent can require a payment method, confirmation, customer action or capture, and can also be processing, canceled or succeeded. 3
Those states describe progress toward collection. They do not describe every later movement of money. A compact model looks more like this:
intent → authorization → capture → clearing → settlement
with branches from authorization to expiry or void, and from a captured or settled payment to refund or dispute.
The word “paid” must therefore be a projection over this model. For an order service, it may mean “safe to fulfil.” For a treasury view, it may mean “included in a settled payout.” For customer support, it may mean “the original charge succeeded, but a refund is pending.” One label cannot answer all three questions without hiding risk.
Authorization reserves; capture collects
An authorization asks whether the issuer will approve the transaction. Approval may place a hold on the customer’s funds, but it does not itself remove those funds. Braintree’s public lifecycle documentation separates Authorized from Submitted for Settlement; PayPal similarly describes an authorization as a pending transaction with a hold, followed later by capture. 46
That gap is useful: a merchant can verify inventory before capture, and some wait until physical goods ship before submitting for settlement. 46 But the gap also has a clock. Authorizations expire, capture can still be subject to risk and money availability, and a later capture may require reauthorization. 4
Partial capture makes a single paid flag even less defensible. The authorized amount, captured amount and remaining capturable amount can differ. Network records must still be linked: Mastercard’s public rules require identifiers from approved authorizations to appear in clearing records so issuers can match them and release excess holds. 5 Reliability depends on preserving that lineage, not merely preserving the latest label.
Capture starts another journey
Capture is an instruction to collect. It is not proof that funds have reached the merchant’s bank account. In Braintree’s documented lifecycle, a transaction moves from submitted for settlement to settling and then settled; only at settlement does the money move through the merchant account and onward to the bank account. 6
Clearing and settlement solve different problems. Clearing establishes and matches the obligations between participants. Settlement discharges them. The Bank for International Settlements defines final settlement as an irrevocable transfer of credit across accounts at a defined settlement institution. 7 That definition is much narrower than “nothing else can ever happen to this purchase.”
There is another boundary after settlement: payout. Processor reporting can associate many balance transactions with one payout, and an itemized reconciliation report may be treated as a settlement file. 12 So “the transaction settled” and “the merchant can identify the bank deposit containing it” are separate operational facts.
This is where reconciliation becomes part of the state model. The system should be able to connect the intent, attempt, authorization, capture, network reference, balance entry and payout. Otherwise a successful checkout can still become an unexplained bank difference.
Refunds and disputes do not rewind time
A refund should not mutate the original payment into “not paid.” The charge happened; the refund is a new money movement with its own amount, identifier and status. That distinction matters for partial refunds and for asynchronous failure. Stripe documents refund states that can require customer action, remain pending, succeed, fail or be canceled; it also notes that a bank or issuer can return a refund that it cannot process. 8
A dispute is a different branch again. It is initiated through the issuer’s dispute process, not the merchant’s refund path. Visa defines a dispute as the reversal of all or part of a transaction’s value by the issuer to the acquirer and, usually, onward from the merchant bank to the merchant. 9
These branches can race. A customer may dispute a charge while a refund is pending, creating a risk of two credits for one purchase. Stripe explicitly documents this case. 8 A model with one mutable status tends to collapse the evidence just when operations needs it most. Separate refund and dispute records preserve who initiated each movement, how much it covers and what outcome is still pending.
The dangerous state is “unknown”
Payment failures are often failures of observation. A capture request reaches the processor, the processor completes it, and the response is lost to a timeout. Retrying with a new identity may capture twice; declaring failure may invite the customer to pay twice. PayPal’s idempotency guidance uses this exact shape: a timed-out capture can be retried with the same request identifier so the latest state is returned without capturing again. 11
The same ambiguity appears after the synchronous API call. Webhooks are evidence of state changes, but they are not a perfectly ordered log. Stripe says webhook events are not guaranteed to arrive in generation order and may be delivered more than once. 10 A handler that blindly applies “the latest event received” can move a payment backwards or repeat fulfilment.
The safer pattern is monotonic where the domain allows it and explicit where it does not. Deduplicate events. Retrieve the authoritative object when an event arrives without required context. Record provider timestamps and event identifiers, but apply transitions according to domain rules. A late authorization event must not overwrite a recorded capture; a second refund event must not create a second refund.
Unknown is therefore a real state, not an exception message. It means the outcome of an external side effect has not yet been established. Recovery should reconcile by stable identifiers before it retries the side effect.
Model the money, then choose the words
A reliable payment record needs several related state machines rather than one grand status. The intent answers what the business is trying to collect. Each attempt records how that intent was tried. Authorization records issuer approval and the amount reserved. Capture records the amount submitted for collection. Settlement and payout records explain when value became available and where it landed. Refund and dispute records describe later, potentially overlapping claims on the original value.
Amounts deserve the same care as states. Store authorized, captured, refunded and disputed amounts independently. Derive “fully refunded” from the sums; do not erase the capture. Keep currency with every monetary amount, and retain the identifiers that connect lifecycle messages. Mastercard’s matching requirements and processor payout reports both depend on those links surviving across systems. 512
Then define projections for each audience. A checkout UI might show “Payment confirmed.” Fulfilment might require “captured” for cards but “settled” for a delayed-notification method. Support might show “Paid; refund pending.” Finance might show “Captured; not yet reconciled to payout.” The language becomes honest because the underlying model can answer the narrower question.
There may never be one universal terminal state. A settled payment can later be refunded or disputed; a won dispute can restore funds; accounting records must retain the history either way. 89 The engineering goal is not to make payments final sooner. It is to know which kind of finality has been reached, which transitions remain possible, and which evidence supports the answer.
“Paid” can stay. It just cannot stand alone.
Sources
- Payment Request API — World Wide Web Consortium (W3C). https://www.w3.org/TR/payment-request/ (opens in a new tab)
- EMV® 3DS for E-Commerce — EMVCo. https://www.emvco.com/wp-content/uploads/2022/09/Quick-Resource_EMV-3DS-for-E-commerce_SEP21_EU.pdf (opens in a new tab)
- The PaymentIntent object — Stripe. https://docs.stripe.com/api/payment_intents/object (opens in a new tab)
- Authorize a payment and capture funds later — PayPal Developer. https://developer.paypal.com/v5/checkout/auth-capture (opens in a new tab)
- Transaction Processing Rules — Mastercard. https://www.mastercard.com/content/dam/public/mastercardcom/na/global-site/documents/transaction-processing-rules.pdf (opens in a new tab)
- Transaction Lifecycle — Braintree, PayPal. https://developer.paypal.com/braintree/articles/get-started/transaction-lifecycle (opens in a new tab)
- Report on Netting Schemes (Angell Report), Glossary of Terms — Bank for International Settlements. https://www.bis.org/cpmi/publ/d02.pdf (opens in a new tab)
- Refund and cancel payments — Stripe. https://docs.stripe.com/refunds (opens in a new tab)
- Dispute Resolutions — Visa. https://www.visa.com/en-us/support/business/dispute-resolution (opens in a new tab)
- Receive Stripe events in your webhook endpoint — Stripe. https://docs.stripe.com/webhooks (opens in a new tab)
- Idempotency — PayPal Developer. https://developer.paypal.com/reference/guidelines/idempotency/ (opens in a new tab)
- Reporting and reconciliation — Stripe. https://docs.stripe.com/plan-integration/get-started/reporting-reconciliation (opens in a new tab)