> ## 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.

# Card Authorizations

> Simulate card authorization flows, including cross-currency transactions and decline scenarios.

<Warning>
  **Beta Feature**

  The Transaction Simulations feature is currently in beta. API endpoints and behavior may change as we continue to refine the product. Simulation endpoints are available in development environments only — production returns `404 Not Found`.
</Warning>

Trigger a card authorization exactly as if a merchant had initiated it. Use this in sandbox to test authorization flows, webhook handling, and decline scenarios end-to-end.

When the merchant currency differs from the billing currency (USD), the system applies FX conversion using current market rates plus applicable fees.

To test how your integration handles declines, specify a decline reason in your request.

## Endpoint

```
POST /v1/simulate/transactions/authorize
```

<Info>
  The card must be **active** and belong to your tenant. Cards in `locked`, `canceled`, or `unactivated` status cannot be used for simulation.
</Info>

## Headers

| Header         | Type               | Required | Description                                                      |
| -------------- | ------------------ | -------- | ---------------------------------------------------------------- |
| `Api-Key`      | string             | Yes      | Your tenant API key. The tenant scope is resolved from this key. |
| `Content-Type` | `application/json` | Yes      | —                                                                |

## Body

| Field                  | Type          | Required | Description                                                                        |
| ---------------------- | ------------- | -------- | ---------------------------------------------------------------------------------- |
| `cardId`               | string (UUID) | Yes      | The Rain card ID to authorize against. Must belong to the calling tenant.          |
| `amount`               | integer       | Yes      | The transaction amount in cents (merchant currency). Must be a positive integer.   |
| `currency`             | string        | Yes      | The merchant currency code (for example, `"USD"`, `"EUR"`, `"GBP"`).               |
| `merchantName`         | string        | Yes      | The merchant name.                                                                 |
| `merchantCategoryCode` | string        | Yes      | The merchant category code (MCC). For example, `"5814"` for fast food restaurants. |
| `declineReason`        | string        | No       | Simulate a declined authorization. See [Decline reasons](#decline-reasons) below.  |

```json title="Example request" theme={null}
{
  "cardId": "a7f2c5b1-9e8d-4c3a-bb22-12c0a4d5b8f9",
  "amount": 5000,
  "currency": "USD",
  "merchantName": "Coffee Shop",
  "merchantCategoryCode": "5814"
}
```

## Response

A successful response returns the transaction ID and status.

```json title="200 OK — Approved" theme={null}
{
  "transactionId": "f3a1c92e-1b3d-4d1e-bb22-12c0a4d5b8f9",
  "status": "authorized"
}
```

```json title="200 OK — Declined" theme={null}
{
  "transactionId": "f3a1c92e-1b3d-4d1e-bb22-12c0a4d5b8f9",
  "status": "declined",
  "declinedReason": "account_credit_limit_exceeded"
}
```

| Field            | Type          | Description                                                      |
| ---------------- | ------------- | ---------------------------------------------------------------- |
| `transactionId`  | string (UUID) | The transaction ID.                                              |
| `status`         | string        | The transaction status: `authorized` or `declined`.              |
| `declinedReason` | string        | Present when `status` is `declined`. The reason for the decline. |

<Info>
  The transaction triggers the same webhooks as a real authorization:

  * `transaction.requested` — Sent when the authorization request arrives.
  * `transaction.created` — Sent when the authorization is approved.

  See the [transaction webhook reference](/docs/transaction) for payload schemas.
</Info>

## Decline reasons

Use the `declineReason` field to simulate declined authorizations:

| Value                           | Description                                                                      |
| ------------------------------- | -------------------------------------------------------------------------------- |
| `account_credit_limit_exceeded` | The cardholder does not have sufficient available balance or credit limit.       |
| `card_locked`                   | The card is locked and cannot be used for transactions.                          |
| `card_canceled`                 | The card has been canceled.                                                      |
| `card_not_activated`            | The card has not been activated.                                                 |
| `blocked_mcc`                   | The transaction is declined because the merchant category is blocked.            |
| `blocked_merchant`              | The transaction is declined because the specific merchant is blocked.            |
| `balance_inquiry_not_permitted` | Balance inquiry is not permitted for this card.                                  |
| `expiry_mismatch`               | The card's expiration date does not match the value provided in the transaction. |
| `cvv_mismatch`                  | The card's CVV does not match the value provided in the transaction.             |
| `invalid_pin`                   | The PIN entered for the transaction is incorrect.                                |
| `restricted_country`            | The transaction is declined because it originated from a restricted country.     |

```json title="Example declined authorization" theme={null}
{
  "cardId": "a7f2c5b1-9e8d-4c3a-bb22-12c0a4d5b8f9",
  "amount": 5000,
  "currency": "USD",
  "merchantName": "Online Casino",
  "merchantCategoryCode": "7995",
  "declineReason": "blocked_mcc"
}
```

## Cross-currency transactions

When the `currency` differs from USD (the billing currency), the system applies FX conversion:

1. The merchant amount is converted to USD using current market rates.
2. A Visa foreign exchange fee (1%) is applied.
3. A Rain foreign exchange fee is applied (default 2%, or your tenant-specific rate if configured).

The `billingAmount` in the transaction record reflects the total USD amount after all conversions and fees.

## Errors

| Status                      | When                                                                                                                    |
| --------------------------- | ----------------------------------------------------------------------------------------------------------------------- |
| `400 Bad Request`           | Invalid body — missing required fields, invalid `cardId` format, or invalid `declineReason` value.                      |
| `404 Not Found`             | Endpoint not available in production, simulations are not enabled for your tenant, or the card does not exist.          |
| `500 Internal Server Error` | Card validation failed (card not active, no processor card ID), invalid currency, or unhandled error during simulation. |

## Behavior notes

* **No real funds move.** Simulations are fully mocked — the processor interaction is simulated internally.
* **The transaction record is real.** The simulation creates a real transaction record, queryable via the transactions API, that fires the same webhooks as a real authorization.
* **Network is always VISA.** Simulated authorizations use the VISA network regardless of the actual card network.

## Example

```bash theme={null}
curl -X POST https://api-dev.rain.xyz/v1/simulate/transactions/authorize \
  -H "Api-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "cardId": "a7f2c5b1-9e8d-4c3a-bb22-12c0a4d5b8f9",
    "amount": 5000,
    "currency": "USD",
    "merchantName": "Coffee Shop",
    "merchantCategoryCode": "5814"
  }'
```
