> ## Documentation Index
> Fetch the complete documentation index at: https://docs.fluz.app/llms.txt
> Use this file to discover all available pages before exploring further.

# Transaction Lifecycle

> How a card purchase travels from the merchant terminal to your ledger — authorization, clearing, settlement, reversals, and refunds — and what Fluz records at each step.

A purchase on a Fluz-issued card is not a single event. It is a conversation between the merchant, the card network, and Fluz that plays out over seconds, hours, or sometimes weeks — and it produces several records on your side before it is finished.

This page explains what happens at each stage, which Fluz records and webhooks each stage produces, and the places where a naive integration gets the arithmetic wrong.

<Note>
  This page covers **open-loop card transactions** — spend on virtual cards Fluz issues onto the card networks. Gift card purchases, deposits, withdrawals, and wallet transfers do not go through this lifecycle; they settle on their own rails. See [Transactions Overview](/features/transactions-details-overview) for the unified ledger that holds all of them.
</Note>

***

## The three stages

| Stage             | What happens                                                                                                     | Whose money moves                            |
| :---------------- | :--------------------------------------------------------------------------------------------------------------- | :------------------------------------------- |
| **Authorization** | The network asks Fluz whether the card can be charged. Fluz checks the card's controls and funding, and answers. | Nothing yet. Funds are **held**, not moved.  |
| **Clearing**      | The merchant submits the final amount. Fluz finalizes the record against the held funds.                         | The hold becomes a real debit.               |
| **Settlement**    | The network moves funds between the acquiring bank and the issuing bank.                                         | Bank to bank. Invisible to your integration. |

Settlement is a banking process that runs behind clearing on the network's own schedule. Fluz represents clearing and settlement as one event — when a transaction is cleared on Fluz, treat it as final.

***

## One purchase, several records

A single purchase can produce an authorization, one or more clearings, and possibly a reversal or a refund. Fluz exposes these through three queries that answer different questions:

| Feed                        | Query                        | What it shows                                                                   |
| :-------------------------- | :--------------------------- | :------------------------------------------------------------------------------ |
| **Card activity**           | `getVirtualCardTransactions` | Spend on one or more cards, with merchant, MCC, FX, and network response fields |
| **Account ledger**          | `getTransactions`            | Every money movement on the account, with balance snapshots after each record   |
| **Declined authorizations** | `getDeclinedTransactions`    | Authorizations that were rejected and never became transactions                 |

Three purchases, and the records each one leaves behind:

```text theme={null}
Acme Hardware — $50.00
├── Authorization        $50.00 debit      held against the card
└── Clearing             $50.00 debit      hold converted, record final

Riverside Hotel — $240.00
├── Authorization       $200.00 debit      pre-auth at check-in
├── Incremental auth     $75.00 debit      incidentals added mid-stay
└── Clearing            $240.00 debit      final folio, less than authorized

Acme Hardware — $50.00, later refunded
├── Authorization        $50.00 debit
├── Clearing             $50.00 debit
└── Refund               $50.00 credit     separate record, not a reversal
```

<Warning>
  **A refund is a new record, not an edit to the old one.**

  Refunds arrive as their own `REFUND` transaction. Nothing about the original `PURCHASE` record changes — its amount stays where it was. If your system reduces the original purchase when a refund lands, you will double-count the credit. Reconcile at the record level; never mutate the original.
</Warning>

***

## Single-message and dual-message flows

How many messages the network sends depends on the merchant and the transaction type. Both flows are normal, and your integration has to handle both.

### Single-message

The network sends one message that authorizes and clears at the same time. Common for PIN debit, ATM withdrawals, and transit. There is no pending window — the transaction is final almost immediately.

```mermaid theme={null}
sequenceDiagram
    autonumber
    participant M as Merchant
    participant N as Card network
    participant F as Fluz
    participant Y as Your integration

    M->>N: Purchase, $25.00
    N->>F: Authorize and clear
    F->>F: Spend controls + funding check
    F-->>N: Approved
    N-->>M: Approved
    F->>Y: TRANSACTION_CREATE
    F->>Y: TRANSACTION_UPDATE (cleared)
```

### Dual-message

The network sends an authorization first, and the merchant submits the clearing later — typically the same night, but up to several days for hotels, car rentals, and travel. The gap between the two is the pending window, and it is where most reconciliation bugs live.

```mermaid theme={null}
sequenceDiagram
    autonumber
    participant M as Merchant
    participant N as Card network
    participant F as Fluz
    participant Y as Your integration

    M->>N: Authorization request, $50.00
    N->>F: Authorize
    F->>F: Spend controls + funding check
    F-->>N: Approved, funds held
    N-->>M: Approved
    F->>Y: TRANSACTION_CREATE (pending)

    Note over M,F: Hours to days pass

    M->>N: Batch submitted, $54.00 with tip
    N->>F: Clear
    F->>F: Match to authorization, finalize
    F->>Y: TRANSACTION_UPDATE (cleared, $54.00)
```

<Note>
  **The cleared amount can differ from the authorized amount.** Tips, fuel pumps, currency conversion, and partial shipments all produce a clearing that is higher or lower than the original hold. Take the cleared amount as authoritative, and never treat an authorization amount as final.
</Note>

### Where the money sits

The same lifecycle, viewed from the account rather than the network:

```mermaid theme={null}
stateDiagram-v2
    [*] --> Available: Funds in the spend account
    Available --> Held: Authorization approved
    Held --> Available: Reversal or expiration
    Held --> Cleared: Clearing received
    Available --> Cleared: Single-message transaction
    Cleared --> Credited: Refund received
    Credited --> [*]
    Cleared --> [*]
```

***

## What Fluz records at each stage

| Network message     | What it means                                      | Card feed `transactionType` | Ledger `status`     | Webhook                                     |
| :------------------ | :------------------------------------------------- | :-------------------------- | :------------------ | :------------------------------------------ |
| Verification        | A $0.00 or $0.01 probe to confirm the card is live | `PURCHASE`, reversed soon   | `PENDING`, released | `TRANSACTION_CREATE`                        |
| Authorization       | Reserve funds pending a final amount               | `PURCHASE`                  | `PENDING`           | `TRANSACTION_CREATE`                        |
| Authorize and clear | Approve and finalize in one message                | `PURCHASE`                  | `SETTLED`           | `TRANSACTION_CREATE` + `TRANSACTION_UPDATE` |
| Clearing            | Finalize a previously authorized transaction       | `PURCHASE`                  | `SETTLED`           | `TRANSACTION_UPDATE`                        |
| Decline             | The authorization was rejected                     | `DECLINE`                   | *no ledger record*  | `TRANSACTION_DECLINE`                       |
| Reversal            | An authorization released before it cleared        | *hold released*             | record released     | `TRANSACTION_UPDATE`                        |
| Refund              | Value returned after a purchase cleared            | `REFUND`                    | `SETTLED` credit    | `TRANSACTION_CREATE`                        |

<Warning>
  **Two feeds, two status vocabularies.**

  * `getVirtualCardTransactions` returns `transactionStatus` values such as `PROCESSING` and `CLEARED`.
  * `getTransactions` returns `status` values of `PENDING` and `SETTLED`.

  They describe the same lifecycle from two angles. Do not write code that expects one vocabulary in both places. → [How the GraphQL API works](/concepts/graphql)
</Warning>

<Note>
  **A decline is not a transaction.** Declined authorizations never enter the account ledger, so they will not appear in `getTransactions` at any status. Query them through `getDeclinedTransactions` and read the reason from [Decline Codes](/features/decline-codes).
</Note>

***

## Authorization

When the network asks Fluz to approve a charge, Fluz evaluates the request against the card, the account, and the funding behind the card. All of it happens in well under a second, because the network will time out.

<AccordionGroup>
  <Accordion title="What gets checked" icon="list-checks">
    * The card is `ACTIVE` — not locked, expired, past its `lockDate`, or already consumed by a single-use rule
    * The amount fits within `spendLimit` for the card's `spendLimitDuration`
    * The merchant matches the card's brand lock, if the card was issued on a brand-locked program
    * The account holder has passed identity verification
    * The funding sources behind the card can cover the amount
    * The bank program's own limits are not exceeded
  </Accordion>

  <Accordion title="Where the money comes from" icon="wallet">
    A card does not hold a balance of its own. It draws, at authorization time, from the funding stack configured when the card was issued:

    1. The spend account named in `userCashBalanceId`, or the account default
    2. The prepayment (gift card) balance, unless `usePrepaymentBalance: false`
    3. The rewards balance, unless `useRewardsBalance: false`
    4. An external bank account, when `primaryFundingSource` is `BANK_ACCOUNT`

    An authorization that exceeds what those sources can cover is declined, even when the card's `spendLimit` is higher. → [Manage Virtual Card Funding Sources](/Manage-Virtual-Card-Funding-Sources)
  </Accordion>

  <Accordion title="Approved amount vs requested amount" icon="equal-not">
    The network requests an amount; Fluz posts what it approves. On a partial approval the two differ, and the approved amount is what is held. Read the amount from the Fluz record rather than assuming it matches what the merchant asked for.
  </Accordion>

  <Accordion title="Declines" icon="circle-x">
    A declined authorization returns a response code to the merchant and produces a `declineReason` and `declineCategory` on the Fluz side. The most common causes are an amount over the spend limit, a locked card, insufficient funds behind the card, a brand-locked card at the wrong merchant, and CVV or AVS mismatch. → [Decline Codes](/features/decline-codes)
  </Accordion>
</AccordionGroup>

### Authorizations that are not purchases

| Type                  | What it is                                                                       | What to do with it                                               |
| :-------------------- | :------------------------------------------------------------------------------- | :--------------------------------------------------------------- |
| $0 / $**0.01 probe**  | A merchant confirming the card is live before storing it or charging it later    | Expect it, and do not count it as spend. It reverses on its own. |
| **Pre-authorization** | A hold placed before the final amount is known — hotels, car rentals, fuel pumps | Expect a clearing at a different amount, often days later.       |
| **Incremental**       | An additional hold stacked on an open pre-authorization                          | Sum the holds; do not treat the second one as a second purchase. |
| **Fuel dispenser**    | A fixed amount set by network rules, unrelated to what is actually pumped        | The clearing carries the real amount.                            |

### Held funds

An approved authorization reduces what the card can still spend without moving money out of the account. Until it clears:

* The card's `remainingBalance` reflects the hold
* The ledger record sits at `PENDING`
* `expectedClearedDate` tells you when to look again

If a clearing never arrives, the hold does not sit there forever — the network's expiration rules release it, and the funds return to the card's available balance. Most authorizations expire within about a week; travel and lodging holds run longer. The exact window is set by the network and the merchant, not by Fluz.

***

## Reversals

A reversal cancels an authorization *before* it clears. The hold is released and the funds return to the card. Reversals can be full or partial.

Common causes:

* The merchant abandoned the sale, or the terminal timed out
* The item was out of stock, or the cardholder cancelled before shipment
* A duplicate authorization was sent
* The authorization expired without a clearing

<Warning>
  **A "reversal" after clearing is really a refund.**

  Once a transaction has cleared there is no hold left to release. Money that comes back after that point arrives as a credit — a separate `REFUND` record — and should be handled as one. The presence of a matching clearing is the dividing line between the two cases.
</Warning>

***

## Clearing and settlement

Clearing is the merchant submitting the final amount, usually as part of an overnight batch. Fluz matches it to the open authorization using the network's reference identifiers and finalizes the record.

Realities to build for:

* **The amount changes.** Tips, fuel, FX, and partial shipments all move the number.
* **There can be more than one clearing.** A split shipment clears in pieces against one authorization, and the pieces can arrive out of order.
* **A clearing can arrive with no authorization.** Networks permit a merchant to force-post in some situations — offline terminals, in-flight purchases, transit fare aggregation. Fluz monitors these, but your ledger has to accept a purchase that appears already cleared with no pending phase.
* **Matching is not guaranteed.** In rare cases the identifiers on a clearing do not line up with the authorization it belongs to, and the clearing appears as its own record.

<Warning>
  **Do not reconcile on network reference identifiers alone.** They are not guaranteed to stay consistent across the life of a transaction, and they are not stable across networks. Store the Fluz `record_id` and `reference_id` against your own order at the time you create it. → [Reconciling against your own system](/features/transactions-details-overview#reconciling-against-your-own-system)
</Warning>

***

## Refunds

A merchant returning value sends a credit back through the network. Fluz posts it as a `REFUND` on the card feed and as a credit on the ledger. It may arrive as an authorization that clears later, or as a clearing on its own.

Two cases that break naive matching:

* **Unlinked refunds.** The network may send the credit with no reference to the original purchase, or with different identifiers. It arrives as a standalone credit with nothing to join it to.
* **Batched refunds.** Several refunds for different original purchases can share network identifiers and arrive grouped.

Because of both, do not assume a one-to-one relationship between refunds and purchases. Reconcile refunds as independent credits against the card, and let the balance be the source of truth.

***

## Foreign currency

A purchase made in another currency clears in USD, with the original amount preserved on the record:

| Field                    | Meaning                                                          |
| :----------------------- | :--------------------------------------------------------------- |
| `originalCurrencyCode`   | ISO 4217 code of the currency the merchant charged in            |
| `originalCurrencyAmount` | The original amount **in minor units** — `6300` HKD is HK\$63.00 |
| `currencyConversionRate` | The rate applied to reach USD. `1.0` for domestic transactions   |

These three fields are returned together — all populated, or all null. Conversion happens at clearing, so a foreign authorization and its clearing commonly differ in USD terms even when the merchant charged the same amount.

***

## Common message sequences

Beyond the two happy paths, these are the sequences worth having test coverage for.

| Sequence                                     | What it is                                                    |
| :------------------------------------------- | :------------------------------------------------------------ |
| `AUTHORIZE_AND_CLEAR`                        | PIN debit, ATM, transit — no pending window                   |
| `AUTHORIZE` → `CLEAR`                        | The standard purchase                                         |
| `AUTHORIZE` → `CLEAR` (higher)               | Restaurant tip added after the card was presented             |
| `AUTHORIZE` → `CLEAR` (lower)                | Partial shipment, or a hotel folio under the pre-auth         |
| `AUTHORIZE` → `AUTHORIZE` → `CLEAR`          | Pre-auth plus incremental auth, cleared once                  |
| `AUTHORIZE` → `CLEAR` → `CLEAR`              | Split shipment, clearing in pieces                            |
| `AUTHORIZE` → `REVERSAL`                     | Sale abandoned before clearing                                |
| `AUTHORIZE` → `REVERSAL` (partial) → `CLEAR` | Part of the hold released, the rest cleared                   |
| `AUTHORIZE` → *(expiry)*                     | No clearing ever arrives; the hold is released on expiration  |
| `CLEAR` with no `AUTHORIZE`                  | Force post — offline terminal, in-flight, transit aggregation |
| `AUTHORIZE` → `CLEAR` → `REFUND`             | Purchase later refunded, in full or in part                   |
| `VERIFICATION` (\$0.00)                      | Card-on-file validation, reversed shortly after               |

***

## Building against the lifecycle

<Steps>
  <Step title="Treat pending and cleared as different things">
    Never show a pending authorization as a completed purchase, and never sum authorizations and clearings together. If you need one number, sum cleared records and show holds separately.
  </Step>

  <Step title="Subscribe to all three transaction events">
    `TRANSACTION_CREATE`, `TRANSACTION_UPDATE`, and `TRANSACTION_DECLINE`. An integration that listens only for creates will show every transaction stuck at its authorization amount forever. → [Webhooks](/fluz-dashboard/webhooks)
  </Step>

  <Step title="Sync on updatedGte, not createdGte">
    A record created as `PENDING` and later cleared changes its updated timestamp, not its created timestamp. A created-date sync silently misses every settlement.
  </Step>

  <Step title="Reconcile balances from snapshots">
    Every ledger record carries the after-state of every balance. Read those fields rather than summing amounts yourself — they already account for fees, cashback, and open holds.
  </Step>

  <Step title="Make handlers idempotent">
    Webhooks retry, and clearings can arrive out of order. Key on the Fluz record identifier and make replay a no-op.
  </Step>
</Steps>

***

## Testing the lifecycle

Staging cards are real card records but are not on a live network, so transactions are injected against them rather than swiped. You can exercise an authorization, a separate clearing, a decline, a reversal, a refund, and a zero-dollar probe — each producing the same records and webhooks as production.

→ [Simulate Virtual Card Transactions](/Simulate-Virtual-Card-Transactions)

***

## Next steps

<CardGroup cols={2}>
  <Card title="Transactions Overview" icon="list" href="/features/transactions-details-overview">
    The unified ledger — what a record contains and how to reconcile it.
  </Card>

  <Card title="Get Virtual Card Transactions" icon="credit-card" href="/features/get-virtual-card-transactions">
    Card-level activity, filters, FX fields, and pagination.
  </Card>

  <Card title="Get Declined Transactions" icon="circle-x" href="/features/get-decline-transactions">
    Authorizations that never became transactions.
  </Card>

  <Card title="Decline Codes" icon="triangle-alert" href="/features/decline-codes">
    Every decline reason and category, and what to do with each.
  </Card>

  <Card title="Simulate Virtual Card Transactions" icon="flask-conical" href="/Simulate-Virtual-Card-Transactions">
    Put a test spend on a staging card and watch the lifecycle run.
  </Card>

  <Card title="Webhooks" icon="webhook" href="/fluz-dashboard/webhooks">
    Subscribe to transaction events, verify signatures, handle retries.
  </Card>
</CardGroup>
