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

# Settlement (handled inside DCS, plus statement queries)

> The how-to reference for the settlement stage: how the five settlement shapes and refunds are handled inside DCS, how to reconcile against the webhook that follows settlement, and how to query statements, line items, asset movements and the posting state of a given ID. For the semantics and mental model of settlement (the two stages of authorization and settlement, the Outstanding bridge, the invariants), see the concept page Transaction Lifecycle · Overview.

## 📄 Guide

Settlement is the **second stage** of the card funding lifecycle: after [authorization](./authorizing-transactions) has frozen the funds, the merchant submits the final amount to the card network, the network and the issuer post the actual amount, and the corresponding hold is released. **Settlement is the mechanism; statements are the queryable view it produces.**

In the DeCard-Managed model, the whole settlement process happens **inside DCS**: on receiving the settlement message from the card network, DCS moves the corresponding statement from **not posted (`NOT_POSTED`)** to **posted (`POSTED`)**, draws down the user's frozen balance, performs the actual deduction and applies the matching asset movement on the user's own account. You never have to track holds yourself or post entries manually after a settlement webhook, which is exactly the convenience the DeCard-Managed model buys you.

The core semantics of settlement is the transition from **outstanding to posted**, expressed by two sets of fields:

* At statement level: the statement `type` moves between `NOT_POSTED` (statement not yet issued) and `POSTED` (statement issued).
* At line item level: `postIndicator` (`1` posted, `0` outstanding) tells you whether each line item has landed in an issued statement.

> The complete definition of the balance model (`free` / `freeze` / `total` and the custody strategies) is in [Account and Asset Model (Ledgering)](../../basic-concepts/ledgering-system).

## Five settlement shapes and refunds

Settlement can take several shapes. Each one below explains how it arises and how DCS internally releases the hold and posts the amount, so you never have to write your own logic per shape.

### Standard settlement

The most common shape: the merchant settles the full authorized amount. On receiving the settlement message, DCS releases the entire authorization hold and posts the authorized amount.

<Frame>
  <img className="block dark:hidden" src="https://mintcdn.com/dcs-0bf7a937/oUoeUKtwWWK2o-Li/imgs/en/diagrams/va-settle-standard-light.svg?fit=max&auto=format&n=oUoeUKtwWWK2o-Li&q=85&s=3d52cf758f24cc52b070dd467f79b7ff" alt="Standard settlement flow" width="712" height="678" data-path="imgs/en/diagrams/va-settle-standard-light.svg" />

  <img className="hidden dark:block" src="https://mintcdn.com/dcs-0bf7a937/oUoeUKtwWWK2o-Li/imgs/en/diagrams/va-settle-standard-dark.svg?fit=max&auto=format&n=oUoeUKtwWWK2o-Li&q=85&s=21fcf5bb9da701113a49ae5eb4c11cc6" alt="Standard settlement flow" width="712" height="678" data-path="imgs/en/diagrams/va-settle-standard-dark.svg" />
</Frame>

### Partial settlement

The merchant settles less than the authorized amount (a restaurant bill settled without the tip, for example). DCS releases the **full** authorization hold, posts only the actual amount, and the excess hold returns to the available balance automatically.

<Frame>
  <img className="block dark:hidden" src="https://mintcdn.com/dcs-0bf7a937/oUoeUKtwWWK2o-Li/imgs/en/diagrams/va-settle-partial-light.svg?fit=max&auto=format&n=oUoeUKtwWWK2o-Li&q=85&s=068817d99d2917f50548706b40030126" alt="Partial settlement flow" width="712" height="678" data-path="imgs/en/diagrams/va-settle-partial-light.svg" />

  <img className="hidden dark:block" src="https://mintcdn.com/dcs-0bf7a937/oUoeUKtwWWK2o-Li/imgs/en/diagrams/va-settle-partial-dark.svg?fit=max&auto=format&n=oUoeUKtwWWK2o-Li&q=85&s=ab84a86d9b9f82d7131b88d78db02115" alt="Partial settlement flow" width="712" height="678" data-path="imgs/en/diagrams/va-settle-partial-dark.svg" />
</Frame>

### Overage settlement

Certain merchant categories, such as dining and hotels where tips or surcharges apply, may settle slightly above the authorized amount. Once the checks pass, DCS releases the original hold and posts the actual amount.

<Frame>
  <img className="block dark:hidden" src="https://mintcdn.com/dcs-0bf7a937/oUoeUKtwWWK2o-Li/imgs/en/diagrams/va-settle-excess-light.svg?fit=max&auto=format&n=oUoeUKtwWWK2o-Li&q=85&s=0a8aa70439a9296d4ade2bb093335f2f" alt="Overage settlement flow" width="712" height="678" data-path="imgs/en/diagrams/va-settle-excess-light.svg" />

  <img className="hidden dark:block" src="https://mintcdn.com/dcs-0bf7a937/oUoeUKtwWWK2o-Li/imgs/en/diagrams/va-settle-excess-dark.svg?fit=max&auto=format&n=oUoeUKtwWWK2o-Li&q=85&s=32f15735970ce57ef480628546ecd30f" alt="Overage settlement flow" width="712" height="678" data-path="imgs/en/diagrams/va-settle-excess-dark.svg" />
</Frame>

> Overage settlement only takes effect within the limits allowed by card network rules and the relevant Merchant Category Codes (MCC); requests above the permitted ceiling are rejected.

### Multiple settlement

One authorization settled in several batches, as with staged e-commerce shipments. DCS **keeps** the authorization hold through the early batches and only releases it and posts once every batch has settled.

<Frame>
  <img className="block dark:hidden" src="https://mintcdn.com/dcs-0bf7a937/oUoeUKtwWWK2o-Li/imgs/en/diagrams/va-settle-multi-light.svg?fit=max&auto=format&n=oUoeUKtwWWK2o-Li&q=85&s=b6c74cf999c6c045b8444b4f916060cc" alt="Multiple settlement flow" width="712" height="926" data-path="imgs/en/diagrams/va-settle-multi-light.svg" />

  <img className="hidden dark:block" src="https://mintcdn.com/dcs-0bf7a937/oUoeUKtwWWK2o-Li/imgs/en/diagrams/va-settle-multi-dark.svg?fit=max&auto=format&n=oUoeUKtwWWK2o-Li&q=85&s=78cd0bd806f8b791adc4c12fb2f12803" alt="Multiple settlement flow" width="712" height="926" data-path="imgs/en/diagrams/va-settle-multi-dark.svg" />
</Frame>

### Force settlement

Settlement with no prior authorization, as in offline or disconnected scenarios such as in-flight shopping. DCS has no hold to release and posts directly against the available balance.

<Frame>
  <img className="block dark:hidden" src="https://mintcdn.com/dcs-0bf7a937/oUoeUKtwWWK2o-Li/imgs/en/diagrams/va-settle-force-light.svg?fit=max&auto=format&n=oUoeUKtwWWK2o-Li&q=85&s=3bf989761eb0a42a9ab6e42c3f106a7d" alt="Force settlement flow" width="712" height="538" data-path="imgs/en/diagrams/va-settle-force-light.svg" />

  <img className="hidden dark:block" src="https://mintcdn.com/dcs-0bf7a937/oUoeUKtwWWK2o-Li/imgs/en/diagrams/va-settle-force-dark.svg?fit=max&auto=format&n=oUoeUKtwWWK2o-Li&q=85&s=0fba4f01d211512902fb8c3b4b8fee15" alt="Force settlement flow" width="712" height="538" data-path="imgs/en/diagrams/va-settle-force-dark.svg" />
</Frame>

> Force settlement only applies to certain merchant categories; offline scenarios normally allow a tolerance of up to 15% to absorb adjustments such as shipping and tax.

### Refund

A refund is a negative transaction that credits the amount back to the cardholder's account and may not reference an original transaction. DCS validates the refund request and posts it directly, increasing the available balance.

<Frame>
  <img className="block dark:hidden" src="https://mintcdn.com/dcs-0bf7a937/oUoeUKtwWWK2o-Li/imgs/en/diagrams/va-settle-refund-light.svg?fit=max&auto=format&n=oUoeUKtwWWK2o-Li&q=85&s=e98e91acea4ccf0b3ff1040618f143ac" alt="Refund posting flow" width="712" height="466" data-path="imgs/en/diagrams/va-settle-refund-light.svg" />

  <img className="hidden dark:block" src="https://mintcdn.com/dcs-0bf7a937/oUoeUKtwWWK2o-Li/imgs/en/diagrams/va-settle-refund-dark.svg?fit=max&auto=format&n=oUoeUKtwWWK2o-Li&q=85&s=85d1fdd94d6bbc53eb527c9411f742e9" alt="Refund posting flow" width="712" height="466" data-path="imgs/en/diagrams/va-settle-refund-dark.svg" />
</Frame>

> A refund can be initiated at any time after the original transaction has completed. In the statement detail, `debitCreditIndcator=C` marks a refund credit.

## The reconciliation webhook after settlement

Once settlement completes, DCS pushes the `CARD_TRANSACTION_SETTLEMENT` webhook event carrying the settled amount (`settledAmount`), the settlement currency (`settledCurrencyCode`), the original transaction amount and currency (`transactionAmount` / `transactionCurrencyCode`), the direction (`direction`), the external transaction ID (`externalTranId`), the last 4 digits of the card number (`cardNumber`), the transaction type (`transactionType`, the single-letter code R/C/Q/P), the local transaction date and time (`localTransactionDate` / `localTransactionTime`), the merchant information (`cardAcceptorNameLocation`, `mcc`, `merchantCountryCode`) and the remaining fields. For every webhook field, the signature verification and a sample JSON payload, see [Webhook & WebSocket](../../integration-resources/webhook-websocket).

### Authorization webhook versus settlement webhook

| Dimension             | Authorization webhook `CARD_TRANSACTION`                       | Settlement webhook `CARD_TRANSACTION_SETTLEMENT`                          | What the partner does                                       |
| --------------------- | -------------------------------------------------------------- | ------------------------------------------------------------------------- | ----------------------------------------------------------- |
| Stage                 | When the authorization happens (freeze)                        | When settlement completes (posting)                                       | —                                                           |
| Key fields            | `response` (A approved / D declined), `authType`               | `settledAmount`, `settledCurrencyCode`, `transactionType` (single letter) | —                                                           |
| Meaning of the amount | Pre-authorized amount, which may differ from the final posting | Final posted amount                                                       | Reconcile against this                                      |
| Effect on balances    | No deduction from the available balance, only a hold           | Actual deduction or credit                                                | Already done by DCS, **no manual balance operation needed** |

### What you need to do

* **Query statements**: use `statements` and `statements/detail` (see the next section) to confirm the settled amount and its line items.
* **Reconcile against the webhook**: use the `CARD_TRANSACTION_SETTLEMENT` event to compare DCS settlement records with your own books asynchronously. **Do not use it to post entries manually.**
* **Resolve state by ID** (optional): when you hold a set of transaction IDs and are unsure whether they have posted, call `POST /card/v1/transaction/id/resolve` (see below).

> In the DeCard-Managed model, posting and the balance deduction are already completed inside DCS, so the partner never needs to act on this webhook to change balances on the DCS side.

## How to query settlement results

Once settlement completes, the endpoints below return statements and their line items. Both **identify the card with `cardId`**.

| Endpoint               | Method | Path                              | Purpose                                                                                                 |
| ---------------------- | ------ | --------------------------------- | ------------------------------------------------------------------------------------------------------- |
| Statement list         | GET    | `/card/v2/statements`             | List statements (filtered by `externalUserId` plus `cardId`)                                            |
| Statement detail       | GET    | `/card/v2/statements/detail`      | Line items for a given `statementId` plus `cardId` (carries the `assetMovements` asset movement detail) |
| Resolve transaction ID | POST   | `/card/v1/transaction/id/resolve` | Resolve the posting state of a transaction ID                                                           |

> See also `/card/v1/fiat/transactions` (GET, the fiat transaction records). Its `postingTransType` field classifies the transaction after settlement; it is semantically related to `transactionType` in the statement detail but is a different field name, so do not confuse the two. For details, see [Managing Transactions](./overview).

### Statement list

Returns a user's card statements, including posted (`POSTED`) and not yet posted (`NOT_POSTED`) ones, with pagination and filtering.

**Prerequisite**: the user is registered, holds a card and has transacted.

**Request** (v2, GET `/card/v2/statements`):

| Parameter        | Required | Description          |
| ---------------- | -------- | -------------------- |
| `externalUserId` | Required | Partner-side user ID |
| `cardId`         | Required | Card ID              |
| `page`           | Optional | Page number          |
| `rows`           | Optional | Items per page       |
| `order`          | Optional | Sort direction       |
| `sort`           | Optional | Sort field           |
| `startTime`      | Optional | Start time           |
| `endTime`        | Optional | End time             |

```
GET /card/v2/statements?externalUserId=usr_demo_001&cardId=card_demo_001&page=1&rows=20
```

**Response** (amounts in both SGD and USD; the example uses redacted placeholder data):

```json theme={null}
{
  "code": "SYS_SUCCESS",
  "message": "success",
  "messageDetail": null,
  "data": [
    {
      "type": "POSTED",
      "statementDateStart": "2025-01-01",
      "statementDateEnd": "2025-01-31",
      "paymentAmountInSgd": 0.0,
      "paymentAmountInUsd": 0.0,
      "nonPostedAmountInSgd": 0.0,
      "nonPostedAmountInUsd": 0.0,
      "statementId": "stmt_demo_001",
      "cardNumberLast4": "1234",
      "cardOrganizationLogo": "https://example.com/logo.png",
      "cardOrganization": "VISA",
      "cardScheme": "VISA",
      "debitAmountExcludePayment": 0.0
    }
  ]
}
```

**Fields**:

| Field                                           | Description                                                                           |
| ----------------------------------------------- | ------------------------------------------------------------------------------------- |
| `type`                                          | Statement type: `POSTED` (statement issued) / `NOT_POSTED` (statement not yet issued) |
| `statementDateStart` / `statementDateEnd`       | Statement period                                                                      |
| `paymentAmountInSgd` / `paymentAmountInUsd`     | Repayment amount (SGD and USD)                                                        |
| `nonPostedAmountInSgd` / `nonPostedAmountInUsd` | Not-yet-posted amount (SGD and USD)                                                   |
| `statementId`                                   | Statement ID                                                                          |
| `cardNumberLast4`                               | Last 4 digits of the card number                                                      |
| `cardOrganizationLogo`                          | Card network logo image URL                                                           |
| `cardOrganization` / `cardScheme`               | Card network / card scheme type (such as `VISA` or `MASTERCARD`)                      |
| `debitAmountExcludePayment`                     | Actual spending on the statement, with all repayments and fees deducted               |

### Statement detail

Returns the line items of a given `statementId`, including merchant, amount, currency, posting state and asset movement records.

**Request** (v2, GET `/card/v2/statements/detail`):

| Parameter                          | Required | Description            |
| ---------------------------------- | -------- | ---------------------- |
| `externalUserId`                   | Required | Partner-side user ID   |
| `cardId`                           | Required | Card ID                |
| `statementId`                      | Required | Statement ID           |
| `page` / `rows` / `order` / `sort` | Optional | Pagination and sorting |

```
GET /card/v2/statements/detail?externalUserId=usr_demo_001&cardId=card_demo_001&statementId=stmt_demo_001&page=1&rows=20
```

**Response** (redacted placeholder data with a masked card number and a placeholder merchant name):

```json theme={null}
{
  "code": "SYS_SUCCESS",
  "message": "success",
  "messageDetail": null,
  "data": [
    {
      "merchantName": "DEMO MERCHANT",
      "mcc": "5411",
      "merchantCountryCode": "702",
      "transactionType": "SPEND",
      "cardOrganizationLogo": "https://example.com/logo.png",
      "postIndicator": 1,
      "transactionDateTime": "2025-01-15T10:00:00+08:00",
      "postingAmountInSgd": 0.0,
      "postingAmountInUsd": 0.0,
      "debitCreditIndcator": "D",
      "transactionDescription": "DEMO MERCHANT PURCHASE",
      "cardNumber": "************1234",
      "postingDate": "2025-01-16",
      "transactionAmount": 0.0,
      "transactionCurrency": "USD",
      "externalTranId": 0,
      "cardOrganization": "VISA",
      "postedTransactionId": "ptx_demo_001",
      "cardScheme": "VISA",
      "systemTraceAuditNumber": "000000",
      "transactionDateTimeStr": "2025-01-15 10:00:00",
      "assetMovements": [
        {
          "id": "am_demo_001",
          "asset": "USDT",
          "amount": 0.0,
          "movementTime": "2025-01-15T10:00:01+08:00",
          "movementType": "DEBIT"
        }
      ],
      "assetMovementStatus": 1
    }
  ]
}
```

**Fields**:

| Field                                            | Description                                                                                                    |
| ------------------------------------------------ | -------------------------------------------------------------------------------------------------------------- |
| `merchantName`                                   | Merchant name                                                                                                  |
| `mcc`                                            | Merchant Category Code (MCC)                                                                                   |
| `merchantCountryCode`                            | Merchant country code                                                                                          |
| `transactionType`                                | Transaction type (values include `SPEND`, `REFUND` and `PARTIAL_REFUND`)                                       |
| `cardOrganizationLogo`                           | Card network logo image URL                                                                                    |
| `postIndicator`                                  | Posting state: `1` posted, `0` not yet posted                                                                  |
| `transactionDateTime` / `transactionDateTimeStr` | Transaction time / raw time string (`yyyy-MM-dd HH:mm:ss`)                                                     |
| `postingAmountInSgd` / `postingAmountInUsd`      | Posted amount (SGD and USD)                                                                                    |
| `debitCreditIndcator`                            | Debit or credit direction: `C` credit (money in, such as a refund) / `D` debit (money out, such as a purchase) |
| `transactionDescription`                         | Transaction description                                                                                        |
| `cardNumber`                                     | Card number (masked)                                                                                           |
| `postingDate`                                    | Posting date                                                                                                   |
| `transactionAmount` / `transactionCurrency`      | Transaction amount / transaction currency                                                                      |
| `externalTranId`                                 | External transaction ID                                                                                        |
| `cardOrganization` / `cardScheme`                | Card network / card scheme type                                                                                |
| `postedTransactionId`                            | Posted transaction ID                                                                                          |
| `systemTraceAuditNumber`                         | System trace audit number                                                                                      |
| `assetMovements`                                 | List of the user's asset movements (see the next section)                                                      |
| `assetMovementStatus`                            | Asset processing state: `1` funds processed, `0` funds not yet processed                                       |

> For the field definitions, see [Managing Transactions › Reporting Field Descriptions](./reporting-field-descriptions).

<Warning>
  **Three different transaction type encodings coexist, so keep them apart**: this section describes the **word encoding used by the query APIs** (`SPEND`/`REFUND`/`PARTIAL_REFUND`). **The same field name in webhooks uses a single-letter encoding instead**: `R` card purchase / `C` ATM withdrawal / `Q` enquiry / `P` transfer or refund (see the `CARD_TRANSACTION_SETTLEMENT` field table in [Webhook & WebSocket](../../integration-resources/webhook-websocket)). On top of that, the fiat transaction endpoint `/card/v1/fiat/transactions` uses the field name **`postingTransType`** rather than `transactionType`, with yet another set of values.
  `assetMovements`, the field that ties card settlement to on-chain asset movements, is covered in the next section.
</Warning>

## Asset movement detail: assetMovements

`assetMovements` is the field that makes the DeCard-Managed model distinctive, because it **connects card settlement to the on-chain asset movements on the user's own account and ledger**. While querying a card purchase, you can see directly which of the user's crypto assets (USDT, USDC and so on) were deducted or returned, which keeps the flow of funds transparent end to end.

| Field          | Description                                                                                                            |
| -------------- | ---------------------------------------------------------------------------------------------------------------------- |
| `id`           | Unique identifier of the asset movement (the last two digits of the userId plus an auto-increment ID within the shard) |
| `asset`        | Asset type (such as `USDT` or `USDC`)                                                                                  |
| `amount`       | Amount moved (**negative for a deduction, positive for a refund**)                                                     |
| `movementTime` | Time of the movement                                                                                                   |
| `movementType` | Movement type (such as `DEBIT` for a deduction or `CREDIT` for a credit)                                               |

The outer `assetMovementStatus` tells you whether the funds behind this settlement have finished processing (`1` complete, `0` incomplete).

> This field arrived with the response format update in August 2025 and is returned by the statement detail endpoint. It reflects the transparency of DCS's own ledger (Crypto-Ledger) mode, where card spending draws down stablecoins directly.

## Resolving posting state by ID: transaction/id/resolve

When you only hold a set of transaction IDs and need to know quickly whether each is **outstanding** or **posted**, use the resolution endpoint POST `/card/v1/transaction/id/resolve`. It is the by-ID entry point into the outstanding-to-posted semantics described above.

**Request** (POST `/card/v1/transaction/id/resolve`):

```json theme={null}
{
  "ids": ["tx_demo_001", "tx_demo_002"]
}
```

**Response** (redacted placeholder data):

```json theme={null}
{
  "code": "SYS_SUCCESS",
  "message": "success",
  "messageDetail": null,
  "data": [
    {
      "id": "tx_demo_001",
      "outstandingTransactionId": "ost_demo_001",
      "postedTransactionId": null,
      "posted": false
    },
    {
      "id": "tx_demo_002",
      "outstandingTransactionId": null,
      "postedTransactionId": "ptx_demo_002",
      "posted": true
    }
  ]
}
```

| Field                      | Description                                                                                                                   |
| -------------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
| `id`                       | The original ID you passed in                                                                                                 |
| `outstandingTransactionId` | Outstanding transaction ID; **`null` when the transaction posted directly with dual messaging and has no outstanding record** |
| `postedTransactionId`      | Posted transaction ID; **`null` while the transaction is still outstanding**                                                  |
| `posted`                   | Whether the transaction has posted (`true` / `false`)                                                                         |

> How to read it: `posted=false` with an `outstandingTransactionId` means the transaction is still before posting; `posted=true` with a `postedTransactionId` means settlement and posting are complete.

## Response envelope and error handling

Every endpoint on this page uses the site-wide response envelope `{code, message, messageDetail, data}` (**there is no `success` boolean**). The success code literal is `SYS_SUCCESS`. `messageDetail` is usually `null`; when it is not, the structured object contains the following sub-fields:

| Field       | Type   | Description     |
| ----------- | ------ | --------------- |
| `message`   | string | Message body    |
| `title`     | string | Title           |
| `type`      | string | Type            |
| `icon`      | string | Icon identifier |
| `action`    | string | Action          |
| `linkTitle` | string | Link title      |
| `linkUrl`   | string | Link URL        |

On failure, `code` and `message` explain the cause, such as a card or user that does not exist. The example below is redacted and its error code is a placeholder; in simple failure cases `messageDetail` is usually `null`:

```json theme={null}
{
  "code": "CARD_NOT_FOUND",
  "message": "Card not found",
  "messageDetail": null,
  "data": null
}
```

For the complete error code dictionary, see [Integration Resources › Error codes](../../integration-resources/overview).

## Next steps

* For the hold decision that precedes settlement (the authorization stage), read [Authorizing Transactions](./authorizing-transactions).
* For the mental model of the transaction flow (the two stages, the Outstanding bridge, the invariants), read [Transaction Lifecycle · Overview](../../basic-concepts/transaction-lifecycle).
* For the `free` / `freeze` / `total` balance model and the custody strategies, read [Account and Asset Model (Ledgering)](../../basic-concepts/ledgering-system).
* To integrate webhook notifications and verify their signatures, read [Webhook & WebSocket](../../integration-resources/webhook-websocket).
