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

# Testing in Sandbox

> Drive every transaction lifecycle scenario end-to-end without a real card network.

The sandbox environment exposes simulation endpoints that produce authorizations, clearings, reversals, refunds, and declines on demand. Use them to test every state your integration needs to handle without waiting for a real card network event.

Simulation is available in all sandbox projects. These endpoints return an error if called in a production environment.

Simulated transactions are priced like live traffic. The `amount` you pass is the merchant amount, and your program's [cardholder fees](/transactions/fees) are charged on top of it. The amount on the resulting transaction is therefore the merchant amount plus `fees`, in the same way a real transaction reports it. See [Amounts](/transactions/amounts) for the full breakdown.

Fees apply on the same terms as in production. An ATM withdrawal is charged the domestic or the cross-border tier depending on `merchant.country`, a purchase in another currency is charged the FX markup, and an account with its own override is charged that instead. To exercise a fee, pass `channel: ATM` or an `originalCurrency` other than your billing currency; for the cross-border ATM tier, also pass a `merchant.country` other than your card program's.

A simulation is deliberately predictable about what it charges: omitting `channel` runs as `ECOMMERCE` and omitting `merchant.country` places the merchant in your card program's own country. A request that names neither therefore carries no fees, and the same request always charges the same amount.

For the underlying status transitions and what to expect on each event, see [Lifecycle](/transactions/lifecycle).

***

## Scenario 1: Authorization and clearing

1. [Create a card](/api-reference/cards/create-card) with `type: VIRTUAL`
2. [Simulate authorization](/api-reference/simulation/simulate-authorization) with a `cardId` and `amount`
3. Confirm [`CARD_TRANSACTION_CREATED`](/api-reference/card-transaction-created) webhook received with `status: PENDING`
4. [Simulate clearing](/api-reference/simulation/simulate-clearing) with the `transactionId`
5. Confirm [`CARD_TRANSACTION_UPDATED`](/api-reference/card-transaction-updated) webhook received with `status: CLEARED`

***

## Scenario 2: Declined transaction

1. [Create a card](/api-reference/cards/create-card)
2. [Simulate decline](/api-reference/simulation/simulate-decline) with a `cardId`, `amount`, and optional `declineReason` (defaults to `INSUFFICIENT_BALANCE`)
3. Confirm [`CARD_TRANSACTION_CREATED`](/api-reference/card-transaction-created) webhook received with `status: DECLINED`

See [Decline reasons](/transactions/decline-reasons) for the full set of codes you can pass as `declineReason`.

***

## Scenario 3: Decline against a frozen card

1. [Freeze a card](/api-reference/cards/freeze-card)
2. Confirm [`CARD_STATUS_UPDATED`](/api-reference/card-status-updated) webhook received with `status: FROZEN`
3. [Simulate authorization](/api-reference/simulation/simulate-authorization) (confirm it is declined)
4. [Unfreeze a card](/api-reference/cards/unfreeze-card)
5. Confirm [`CARD_STATUS_UPDATED`](/api-reference/card-status-updated) webhook received with `status: ACTIVE`

***

## Scenario 4: Refund on a cleared transaction

1. [Create a card](/api-reference/cards/create-card)
2. [Simulate authorization](/api-reference/simulation/simulate-authorization)
3. [Simulate clearing](/api-reference/simulation/simulate-clearing) with the `transactionId`
4. [Simulate refund](/api-reference/simulation/simulate-refund) with the `transactionId`
5. Confirm [`CARD_TRANSACTION_UPDATED`](/api-reference/card-transaction-updated) webhook received

***

## Scenario 5: External authorization

<Note>
  Applies to **External** [authorization mode](/program-configuration/authorization-mode) projects only. In Managed projects, Reap decides the authorization and there is no endpoint to call.
</Note>

In an External project, simulation fires a real signed `CARD_AUTHORIZATION_REQUEST` to your registered authorization endpoint and authorizes based on the decision you return. See [The authorization request](/transactions/external-authorization/authorization-request) for the contract.

1. Register your authorization endpoint (a webhook with `mode: REQUEST`) and [create a card](/api-reference/cards/create-card)
2. [Simulate authorization](/api-reference/simulation/simulate-authorization) with a `cardId` and `amount`
3. Your endpoint receives a `CARD_AUTHORIZATION_REQUEST`; return `{ "decision": "APPROVE" }` or a decline
4. Confirm the [`CARD_TRANSACTION_CREATED`](/api-reference/card-transaction-created) webhook reflects your decision: `status: PENDING` on approve, `status: DECLINED` on decline

***

## Scenario 6: Authorization with 3DS challenge (WEBHOOK)

Use this when the card uses `3dsChallengeMethod: WEBHOOK` and you need to exercise the challenge → respond → transaction path end-to-end.

1. [Create a card](/api-reference/cards/create-card) with `3dsChallengeMethod: WEBHOOK` (or [update](/api-reference/cards/update-3ds-challenge-method) an existing card)
2. [Simulate authorization with 3DS](/api-reference/simulation/simulate-3ds-authorization) with a `cardId` and `amount`
3. Confirm [`CARD_3DS_CHALLENGE_CREATED`](/api-reference/3ds-challenge-created) — there is **no** `CARD_TRANSACTION_CREATED` yet
4. [Respond to 3DS challenge](/api-reference/cards/respond-to-3ds-challenge) with `approve: true` or `false`
5. On **approve**, confirm [`CARD_TRANSACTION_CREATED`](/api-reference/card-transaction-created) with `status: PENDING`. On **reject**, the challenge becomes `REJECTED` and **no** transaction is created (same as production — a rejected 3DS never produces a network authorization).

***

## Scenario 7: Detected fraud alert

1. [Create a card](/api-reference/cards/create-card)
2. [Simulate authorization](/api-reference/simulation/simulate-authorization) with `triggerFraudAlert: true`
3. Confirm [`CARD_TRANSACTION_CREATED`](/api-reference/card-transaction-created) webhook received with `status: PENDING`
4. Confirm [`CARD_FRAUD_ALERT_CREATED`](/api-reference/card-fraud-alert-created) webhook received with `origin: DETECTED` and `status: PENDING`
5. [Respond to alert](/api-reference/fraud-alerts/respond-to-alert) with confirm or decline

Detection alone does not block the card. See [Fraud Alerts](/cards/fraud-alerts) for respond and manual-report flows. You can also [report fraud](/api-reference/fraud-alerts/report-fraud) against transactions from any simulation path. Some older simulated transactions might not support fraud reporting, please use a newer transaction in that case.

***

## Simulating card statuses

To force a card into a status that is otherwise hard to trigger (`BLOCKED`, `EXPIRED`), see [Simulating card statuses](/cards/overview#simulating-card-statuses-in-sandbox).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.