Concepts

Authorization and capture

Authorization is the operation that reserves funds on a payment method without moving them, and capture is the separate, later operation that actually moves the reserved funds.

Authorization is the operation that reserves funds on a customer's payment method without moving them, capture is the separate operation that actually moves the reserved funds, and the gap between the two is a business decision your application makes on purpose, not an implementation detail to collapse away.

Real-world scenarios that require the gap

The gap between authorization and capture is not a workaround; it exists because the moment a customer agrees to pay is frequently not the moment the merchant knows the final, correct amount to charge, or is even certain the service will be delivered at all.

In every case, collapsing the two operations into one “charge the card” step either takes money the merchant is not yet entitled to, or forces the merchant to re-authorize repeatedly while it waits for a fact it does not have yet.

Where the money is, and what the customer sees

At authorization, no money moves. The issuer places a hold against the customer’s available balance or credit limit for the authorized amount, which is why an authorization is also called a hold. The customer typically sees this as a pending line on their account — reserved, but not yet a posted transaction, and it can disappear entirely if it is never captured and its hold expires.

At capture, money actually moves from the customer’s issuer toward the merchant’s payment processor, and the transaction becomes a posted charge the customer sees as final. This is also the point at which the amount is fixed: capturing for a different amount than was authorized is the “partial capture” or “over-capture” case described below, not a correction you make after the fact to the authorization itself.

The practical consequence for an application’s data model is that “the customer has agreed to pay” and “the merchant has been paid” are two different facts, true at two different times, and a data model that only records one of them cannot answer honest questions about either.

Authorization expiry

An authorization does not last forever. Because it reserves a customer’s available funds without moving them, an issuer or network limits how long that reservation can sit uncaptured before it is released back to the customer — otherwise a merchant could hold money hostage indefinitely without ever completing the sale.

The general rule an application must design around: every authorization has a finite lifetime, and an application that tries to capture an authorization after it has expired must handle that as a real failure mode — typically by re-authorizing, if the customer’s payment method and consent still allow it, rather than assuming the original hold is still good.

The exact length of that lifetime is provider- and network-dependent, and this page deliberately does not state one as an industry-wide fact. Finxture’s own authored successful-payment flow uses a seven-day expiry window for its authorization, which is a reasonable illustrative default for local testing — not a claim about what any real card network or provider enforces. Confirm the actual window against current provider documentation before relying on it in production.

Partial capture, over-capture, and void versus refund

Real capture is rarely “capture the exact authorized amount, once.” Three related but distinct behaviors sit alongside the basic flow:

Neither of these is implemented as a runnable scenario in Finxture today — partial-capture and multicapture currently exist only as planned catalog entries — but this section is the concept those two future scenarios will be built against, so their eventual behavior is defined here once rather than reinvented per scenario.

Voiding an authorization and refunding a capture are different operations with different customer-visible effects, and the difference matters. Voiding (also called reversing) an uncaptured authorization releases the hold before it expires on its own; because no money ever moved, the customer never sees a posted transaction at all — at most a pending hold disappears sooner than it otherwise would have. Refunding, by contrast, only applies to money that has already been captured: it returns funds after they moved, which the customer sees as a distinct posted credit, often on a different statement cycle than the original charge. An application that “refunds” an authorization that was never captured is describing an operation that has no funds to act on; the correct operation in that case is a void.

The data model: why four entities, not one status field

The temptation, especially early on, is to model a payment as a single row with a status column that walks through values like pending, authorized, and paid. This collapses under the very first case above: a hotel that authorizes once and might need to retry authorization on a declined card, then captures a different amount than it authorized, has history that one status column cannot represent — you can tell where the payment ended up, but not how it got there, and you cannot tell which specific authorization a given capture belongs to once there has been more than one attempt.

The data model needs four distinct kinds of entity, not one:

  1. The payment — the durable record of what the customer owes, identified independently of any single attempt to collect it.
  2. The payment attempt — one attempt to complete that payment. A payment can have more than one attempt (a declined card followed by a retry with a different payment method is still one payment, but two attempts), so the attempt needs its own identity, separate from the payment it belongs to.
  3. The authorization — a hold placed during one attempt, carrying its own status, its own requested and captured amounts, and its own expiry.
  4. The capture — money actually moved against one specific authorization, with its own status and amount, distinct from the authorization it draws against.

This mirrors the canonical model: a payment resource references the payment_attempt resources attempting to complete it, and each attempt carries its own arrays of authorization and capture operations (plus authentication operations, for flows like 3-D Secure, which are outside this article’s scope). An authorization can have more than one capture against it (the multicapture case above), and a capture always references exactly the one authorization it draws against — never the payment or attempt directly.

The standard failure is collapsing the payment and the payment attempt into one entity. Once that happens, there is no way to represent “this specific attempt’s authorization was declined” without it looking like the whole payment failed, and no way to represent a successful retry without either losing the record of the earlier failed attempt or inventing a second payment for what is, to the customer, one purchase. Keeping the payment and its attempts as separate entities is what lets an application answer “did the customer pay?” (a property of the payment) and “what actually happened when we tried to collect it?” (a property of its attempts) as two different, both correct, questions.

What the notification stream looks like

A payment moving through authorization and capture produces four canonical state transitions, each with its own event: authorization.succeeded and payment.authorized when the hold is placed, then capture.succeeded and payment.succeeded when the funds move. Two events per stage because the transition changes two resources at once — the attempt’s nested authorization or capture operation, and the payment’s own status — and each resource gets its own event so a consumer watching either resource in isolation still sees a complete, self-consistent history.

The one thing an integration must not assume is that a provider reports this one-for-one. A provider is free to fold more than one canonical transition into a single event it emits, or to omit an event a different provider would send for the same underlying change, and that grouping is a provider-specific fact rather than a canonical one — it belongs on the provider switcher of a page describing a specific scenario, not here. The practical rule: build a handler around “what changed on the resource,” derived from whatever events actually arrive, rather than around counting events and assuming a fixed number always arrive per business transition.

The same at-least-once delivery guarantee that makes duplicate webhook delivery a normal fact of life for any of these events also means their arrival order is not guaranteed — a fact this page deliberately does not go further into, since it is a delivery concern rather than an authorization-and-capture one.

What to test

Whatever the data model above, a payment integration’s automated tests should specifically exercise:

What goes wrong

An application that treats authorization and capture as one step cannot delay charging until a hotel stay ends, an order ships, or a marketplace payout is due, and once it does need that delay it typically discovers only during reconciliation that money it assumed was safely reserved actually expired uncaptured.

Updated 2026-08-02