> ## Documentation Index
> Fetch the complete documentation index at: https://rain-sandbox-trial.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# transaction.completed

<Update label="v1.5.0" description="minor update">
  ### currency added to fundMovements entries

  | Field                            | Type     | Description                              |
  | -------------------------------- | -------- | ---------------------------------------- |
  | `spend.fundMovements[].currency` | `string` | The currency of the fund movement amount |
</Update>

<Update label="v1.4.0" description="minor update">
  ### fundMovements field added

  Added the `fundMovements` array to the `transaction.completed` (spend) webhook payload. Each entry describes one on-chain fund movement that backs the card transaction. For example, the authorization pull that reserved funds on-chain. Movements are ordered oldest first. You receive this field only if your tenant is opted in to webhook version `1.4.0` or later; earlier versions never include it. When no on-chain movements back the transaction, `fundMovements` is an empty array.

  #### New Field

  | Field                 | Type    | Description                                                                                                          |
  | --------------------- | ------- | -------------------------------------------------------------------------------------------------------------------- |
  | `spend.fundMovements` | `array` | On-chain fund movements backing the transaction, ordered oldest first. Empty when no movements back the transaction. |

  #### `fundMovements[]` Object

  | Field         | Type     | Description                                                              |
  | ------------- | -------- | ------------------------------------------------------------------------ |
  | `hash`        | `string` | The on-chain transaction hash for this movement.                         |
  | `chainId`     | `string` | The chain identifier where the movement settled (for example, `0x2105`). |
  | `kind`        | `string` | The type of fund movement. See possible values below.                    |
  | `direction`   | `string` | The direction of the movement. Currently always `debit`.                 |
  | `amountCents` | `number` | The amount moved, in cents.                                              |
  | `occurredAt`  | `string` | ISO 8601 timestamp of when the movement occurred on-chain.               |

  #### Possible Values for `kind`

  | Value              | Description                                                     |
  | ------------------ | --------------------------------------------------------------- |
  | `auth`             | Initial authorization pull.                                     |
  | `incremental_auth` | Additional pull for an incremental authorization.               |
  | `force_post`       | Pull backing a force-posted settlement.                         |
  | `over_capture`     | Pull covering a settlement that exceeded the authorized amount. |
  | `sweep`            | Pull that sweeps remaining funds for the transaction.           |

  #### Example Payload

  ```json theme={null}
  {
      "resource": "transaction",
      "action": "completed",
      "version": "1.4.0",
      "body": {
          "id": "txn_abc123",
          "type": "spend",
          "spend": {
              "amount": 5500,
              "currency": "USD",
              "localAmount": 4950,
              "localCurrency": "EUR",
              "authorizedAmount": 5000,
              "merchantName": "RESTAURANT XYZ",
              "merchantCity": "Miami",
              "merchantCountry": "US",
              "merchantCategory": "Restaurants",
              "merchantCategoryCode": "5812",
              "cardId": "card_123",
              "cardType": "physical",
              "companyId": "company_456",
              "userId": "user_789",
              "userFirstName": "John",
              "userLastName": "Doe",
              "userEmail": "john.doe@example.com",
              "status": "completed",
              "authorizedAt": "2026-01-27T19:30:00.000Z",
              "postedAt": "2026-01-29T08:15:00.000Z",
              "exchangeRate": 1.11,
              "completionReason": "settlement",
              "isForcePosted": true,
              "closedAuthorizationTransactionId": "txn_auth456",
              "threeDSecure": true,
              "fundMovements": [
                  {
                      "hash": "0x9f2c1a7b3e5d4c8f6a0b2d1e3f4c5a6b7d8e9f0a1b2c3d4e5f6a7b8c9d0e1f2a",
                      "chainId": "0x2105",
                      "kind": "auth",
                      "direction": "debit",
                      "amountCents": 5000,
                      "occurredAt": "2026-01-27T19:29:58.000Z"
                  },
                  {
                      "hash": "0x1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b",
                      "chainId": "0x2105",
                      "kind": "over_capture",
                      "direction": "debit",
                      "amountCents": 500,
                      "occurredAt": "2026-01-29T08:14:55.000Z"
                  }
              ]
          }
      }
  }
  ```
</Update>

<Update label="v1.3.0" description="minor update">
  ### threeDSecure field added

  Added the `threeDSecure` field to the `transaction.completed` (spend) webhook payload. This field indicates whether 3D Secure authentication was used for the transaction.

  #### New Field

  | Field                | Type                 | Description                                                             |
  | -------------------- | -------------------- | ----------------------------------------------------------------------- |
  | `spend.threeDSecure` | `boolean` (optional) | Indicates whether 3D Secure authentication was used for the transaction |

  #### Example Payload

  ```json theme={null}
  {
      "resource": "transaction",
      "action": "completed",
      "version": "1.3.0",
      "body": {
          "id": "txn_abc123",
          "type": "spend",
          "spend": {
              "amount": 5500,
              "currency": "USD",
              "localAmount": 4950,
              "localCurrency": "EUR",
              "authorizedAmount": 5000,
              "merchantName": "RESTAURANT XYZ",
              "merchantCity": "Miami",
              "merchantCountry": "US",
              "merchantCategory": "Restaurants",
              "merchantCategoryCode": "5812",
              "cardId": "card_123",
              "cardType": "physical",
              "companyId": "company_456",
              "userId": "user_789",
              "userFirstName": "John",
              "userLastName": "Doe",
              "userEmail": "john.doe@example.com",
              "status": "completed",
              "authorizedAt": "2026-01-27T19:30:00.000Z",
              "postedAt": "2026-01-29T08:15:00.000Z",
              "exchangeRate": 1.11,
              "completionReason": "settlement",
              "isForcePosted": true,
              "closedAuthorizationTransactionId": "txn_auth456",
              "threeDSecure": true
          }
      }
  }
  ```
</Update>

<Update label="v1.2.0" description="minor update">
  ### Force-posted transaction fields added

  Added `isForcePosted` and `closedAuthorizationTransactionId` fields to the `transaction.completed` (spend) webhook payload. These fields identify force-posted transactions: settlements that arrive without a prior authorization hold, or settlements that arrive after the original transaction has already been closed and settled.

  #### New Fields

  | Field                                    | Type                 | Description                                                                                                                                                           |
  | ---------------------------------------- | -------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
  | `spend.isForcePosted`                    | `boolean` (optional) | Indicates whether this transaction was force posted. Present when the value is explicitly `true` or `false`.                                                          |
  | `spend.closedAuthorizationTransactionId` | `string` (optional)  | The ID of the authorization transaction that was closed when this force-posted settlement arrived. Present only when the force post closed an existing authorization. |

  #### When These Fields Appear

  * **`isForcePosted`**: Included when the transaction has a defined force-post status. A value of `true` indicates the settlement arrived without a matching open authorization, or a new settlement arrived for a transaction that was already closed and settled. Omitted for transactions without force-post metadata.
  * **`closedAuthorizationTransactionId`**: Included only when a force-posted settlement closed an existing (possibly stale) authorization. If the force post had no prior authorization at all, this field is absent.

  #### Example Payload (Force-Posted Transaction)

  ```json theme={null}
  {
      "resource": "transaction",
      "action": "completed",
      "version": "1.2.0",
      "body": {
          "id": "txn_abc123",
          "type": "spend",
          "spend": {
              "amount": 5500,
              "currency": "USD",
              "localAmount": 4950,
              "localCurrency": "EUR",
              "authorizedAmount": 5000,
              "merchantName": "RESTAURANT XYZ",
              "merchantCity": "Miami",
              "merchantCountry": "US",
              "merchantCategory": "Restaurants",
              "merchantCategoryCode": "5812",
              "cardId": "card_123",
              "cardType": "physical",
              "companyId": "company_456",
              "userId": "user_789",
              "userFirstName": "John",
              "userLastName": "Doe",
              "userEmail": "john.doe@example.com",
              "status": "completed",
              "authorizedAt": "2026-01-27T19:30:00.000Z",
              "postedAt": "2026-01-29T08:15:00.000Z",
              "exchangeRate": 1.11,
              "completionReason": "settlement",
              "isForcePosted": true,
              "closedAuthorizationTransactionId": "txn_auth456"
          }
      }
  }
  ```
</Update>

<Update label="v1.1.0" description="minor update">
  ### completionReason field added

  Added the `completionReason` field to the `transaction.completed` (spend) webhook payload. This field provides context about why the transaction was completed.

  #### New Field

  | Field                    | Type                | Description                              |
  | ------------------------ | ------------------- | ---------------------------------------- |
  | `spend.completionReason` | `string` (optional) | The reason the transaction was completed |

  #### Possible Values for `completionReason`

  | Value                         | Description                                              |
  | ----------------------------- | -------------------------------------------------------- |
  | `settlement`                  | Normal settlement from the payment network               |
  | `stale_authorization_closure` | Authorization expired due to age without settlement      |
  | `authorization_reversal`      | Merchant fully reversed the authorization amount to zero |
  | `refund`                      | Transaction was refunded                                 |
  | `chargeback`                  | Transaction was charged back                             |
  | `manual_closure`              | Manually closed by an administrator                      |
  | `reprocessed_settlement`      | Replayed force-posted settlement                         |

  #### Example Payload

  ```json theme={null}
  {
      "resource": "transaction",
      "action": "completed",
      "version": "1.1.0",
      "body": {
          "id": "txn_abc123",
          "type": "spend",
          "spend": {
              "amount": 5500,
              "currency": "USD",
              "localAmount": 4950,
              "localCurrency": "EUR",
              "authorizedAmount": 5000,
              "merchantName": "RESTAURANT XYZ",
              "merchantCity": "Miami",
              "merchantCountry": "US",
              "merchantCategory": "Restaurants",
              "merchantCategoryCode": "5812",
              "cardId": "card_123",
              "cardType": "physical",
              "companyId": "company_456",
              "userId": "user_789",
              "userFirstName": "John",
              "userLastName": "Doe",
              "userEmail": "john.doe@example.com",
              "status": "completed",
              "authorizedAt": "2026-01-27T19:30:00.000Z",
              "postedAt": "2026-01-29T08:15:00.000Z",
              "exchangeRate": 1.11,
              "completionReason": "settlement"
          }
      }
  }
  ```
</Update>

<Update label="v1.0.0" description="initial release">
  ### transaction.completed webhook (spend)

  Added the `transaction.completed` webhook for spend transactions. Rain triggers this webhook when a transaction settles and posts to the account. This indicates the final state of the transaction after the settlement process.

  #### Payload Fields

  | Field                        | Type                | Description                                                                                                                                                               |
  | ---------------------------- | ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
  | `id`                         | `string`            | The transaction ID                                                                                                                                                        |
  | `type`                       | `string`            | Always `spend` for this webhook                                                                                                                                           |
  | `spend.amount`               | `number`            | Final settled transaction amount in USD                                                                                                                                   |
  | `spend.currency`             | `string`            | Currency code (e.g., `USD`)                                                                                                                                               |
  | `spend.localAmount`          | `number` (optional) | Transaction amount in local currency                                                                                                                                      |
  | `spend.localCurrency`        | `string` (optional) | Local currency code                                                                                                                                                       |
  | `spend.authorizedAmount`     | `number` (optional) | The original authorized amount                                                                                                                                            |
  | `spend.authorizationMethod`  | `string` (optional) | Method of authorization                                                                                                                                                   |
  | `spend.merchantName`         | `string`            | Merchant name                                                                                                                                                             |
  | `spend.merchantCity`         | `string`            | Merchant city                                                                                                                                                             |
  | `spend.merchantCountry`      | `string`            | Merchant country                                                                                                                                                          |
  | `spend.merchantCategory`     | `string`            | Merchant category description                                                                                                                                             |
  | `spend.merchantCategoryCode` | `string`            | Merchant category code (MCC)                                                                                                                                              |
  | `spend.merchantId`           | `string` (optional) | Merchant ID                                                                                                                                                               |
  | `spend.cardId`               | `string`            | The card ID used for the transaction                                                                                                                                      |
  | `spend.cardType`             | `string`            | The card type (`virtual` or `physical`)                                                                                                                                   |
  | `spend.companyId`            | `string` (optional) | Company ID (for corporate cards)                                                                                                                                          |
  | `spend.userId`               | `string`            | The user ID                                                                                                                                                               |
  | `spend.userFirstName`        | `string`            | User's first name                                                                                                                                                         |
  | `spend.userLastName`         | `string` (optional) | User's last name                                                                                                                                                          |
  | `spend.userEmail`            | `string`            | User's email                                                                                                                                                              |
  | `spend.status`               | `string`            | Always `completed` for this webhook                                                                                                                                       |
  | `spend.authorizedAt`         | `string`            | ISO 8601 timestamp of original authorization                                                                                                                              |
  | `spend.postedAt`             | `string`            | ISO 8601 timestamp when the transaction was posted/settled                                                                                                                |
  | `spend.signature`            | `string` (optional) | Signature for verification                                                                                                                                                |
  | `spend.timestamp`            | `number` (optional) | Unix timestamp                                                                                                                                                            |
  | `spend.exchangeRate`         | `number` (optional) | The exchange rate used to convert the local transaction amount to the settlement amount (USD). Present for international transactions where currency conversion occurred. |

  #### Example Payload

  ```json theme={null}
  {
      "resource": "transaction",
      "action": "completed",
      "version": "1.0.0",
      "body": {
          "id": "txn_abc123",
          "type": "spend",
          "spend": {
              "amount": 5500,
              "currency": "USD",
              "localAmount": 4950,
              "localCurrency": "EUR",
              "authorizedAmount": 5000,
              "merchantName": "RESTAURANT XYZ",
              "merchantCity": "Miami",
              "merchantCountry": "US",
              "merchantCategory": "Restaurants",
              "merchantCategoryCode": "5812",
              "cardId": "card_123",
              "cardType": "physical",
              "companyId": "company_456",
              "userId": "user_789",
              "userFirstName": "John",
              "userLastName": "Doe",
              "userEmail": "john.doe@example.com",
              "status": "completed",
              "authorizedAt": "2026-01-27T19:30:00.000Z",
              "postedAt": "2026-01-29T08:15:00.000Z",
              "exchangeRate": 1.11
          }
      }
  }
  ```
</Update>
