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

# Sandbox simulations

> Sandbox test cards, cardholder #dbg directives, magic-amount transfer outcomes, and how to test user cancellation

In sandbox (`raas_sandbox_*` keys) you can force three kinds of test cases: **test cards** (PAN / debit vs credit), **cardholder directives** (card add / destination card), and **magic amounts** (operation lifecycle). Magic amounts are also how you [test user cancellation](#testing-user-cancellation).

## Test cards

Use a Luhn-valid Visa or Mastercard, any future expiry, and a 3-digit CVV (`123`). Most flows accept Visa and Mastercard only.

On sandbox partners, card validation runs in the Raas CVS stub (no live Card Validation call). The stub classifies **debit vs credit from the last four digits** — brand is ignored:

| last4 | Class | Shown as |
| -: | - | - |
| `1111` | Debit (regulated) | Debit card |
| `4444` | Credit | Credit card |
| any other | Debit (unregulated) | Debit card |

Canonical PANs:

| PAN | Brand | last4 | Class |
| - | - | -: | - |
| `4111111111111111` | Visa | 1111 | Debit |
| `4242424242424242` | Visa | 4242 | Debit |
| `5555555555554444` | Mastercard | 4444 | Credit |

<Note>
  If the corridor only offers debit (for example some Banrural fund-request routes), a `*4444` card is saved but does not appear in the payment-method picker. Use a debit PAN (`4111…1111` or `4242…4242`) for those corridors.
</Note>

Put `#dbg` on the **cardholder name** to simulate accept / reject — see [Cardholder directives](#cardholder-directives). Example happy path: name `Ale Martin #dbg`, PAN `4111111111111111`.

## Magic amounts

The **cents of the amount the user types** select a simulated transfer outcome. Any other cents run the happy path.

Use the anchored amount: send amount on send-anchored quotes, receive amount on receive-anchored quotes. Examples: `100.04`, `25.77`, `50.78`.

| Cents | What it simulates |
| -: | - |
| `.04` | Sender rejected |
| `.13` | Execution rejected |
| `.31` | Transient error |
| `.20` | Settle after \~20 s |
| `.21`–`.30` | Settle after N minutes (`.21` = 1 min … `.30` = 10 min) |
| `.66` | Settle as failed |
| `.77` | PIN and receipt while `processing` (\~3 s); settle \~20 s later |
| `.78` | Completes first (\~2 s); PIN and receipt \~6 s after accept |
| `.99` | Funding expires (cash) / execution cancelled (card, ACH) |
| other | Happy path (settle \~2 s) |

<Note>
  Use a two-decimal currency (USD, MXN, …). Currencies with 0 or 1 decimal cannot express magic cents and always run the happy path.

  Delayed settlement (`.20`, `.21`–`.30`) is an in-memory timer on the sandbox instance. A backend restart cancels a pending delay and the operation stays `processing` until you recreate it or a live corridor event arrives.
</Note>

## Testing user cancellation

<Warning>
  **"I can't test cancel — the button never shows up."** In sandbox, a normal amount settles in about 2 seconds. The operation is `completed` before the receipt renders, so the **Cancel transfer** button never appears. To test cancellation you must use a **delayed-settlement magic amount**.
</Warning>

### Why the button is time-limited

End users can cancel a transfer only for a short window. This follows the U.S. Remittance Transfer Rule (Regulation E, Subpart B). Under [12 CFR 1005.34](https://www.consumerfinance.gov/rules-policy/regulations/1005/34/), a sender may cancel within **30 minutes after making payment**, as long as the funds have **not** been picked up by the recipient or deposited into the recipient's account.

The widget applies the same rule. **Cancel transfer** shows on the receipt and on the operation detail view while **both** of these are true:

* Less than **30 minutes** have passed since the user pressed **Make Payment**. The clock starts when the operation is created, not when the quote was accepted.
* The operation has **not** settled at the destination. The status is not `completed`, `failed`, or `cancelled` yet.

The first of the two to end closes the window. The backend decides if the button shows and checks again when the user taps it. A late tap is rejected even if the screen still shows the button.

### Build the scenario

1. Create a transfer in sandbox and type an amount whose cents delay settlement. For example, `100.25` holds the operation in `processing` for about **5 minutes**.
2. Finish the flow up to **Make Payment** and wait for the receipt.
3. The receipt shows **Cancel transfer** with a countdown. Tap it and confirm.
4. Check the result:
   * The operation moves to `cancelled` and your webhook endpoint receives [`operation.cancelled`](/raas-widgets/webhooks/events#operationcancelled), with `cancellationReason`.
   * If funds already moved to the corridor, the widget shows **Cancellation in progress** and support follows up. Refunds apply only if the funds were not delivered to the recipient.
   * When the delay timer ends, it does **not** bring a cancelled operation back to `completed`.

| Cents | Time before settlement | Use for |
| -: | - | - |
| `.20` | \~20 s | Quick check that the button shows (tight to tap) |
| `.21`–`.30` | 1–10 min (`.25` = 5 min, `.30` = 10 min) | **Recommended** for cancel tests |
| other | \~2 s | Button never shows. Use this to check the "no cancel after settlement" case |

<Tip>
  You cannot reach the **30-minute** limit in sandbox. The longest delay is 10 minutes (`.30`), so the operation always settles first and settlement is what hides the button. To check the time limit, watch the countdown on the receipt.
</Tip>

<Note>
  For a moment right after **Make Payment**, the operation may be in an in-flight step, such as funding or execution. The button can be hidden or a tap can be rejected as `IN_FLIGHT`. Wait a few seconds and try again. The 30-minute window keeps running.
</Note>

## Cardholder directives

When the user adds a **funding card** or a **destination card**, append `#dbg` to the cardholder name (funding field, or the recipient name on push-to-card). The sandbox stub **replicates the same `#dbg` grammar** as live Card Validation (`NETWORK_STUB`).

Format: `<name> #dbg k=v k=v …`. Bare `#dbg` is the happy path.

| Cardholder name | What you see |
| - | - |
| `Ale Martin #dbg` | Card accepted |
| `Ale Martin #dbg outcome=deny` | Card rejected |
| `Ale Martin #dbg outcome=review` | Card under review — cannot be used yet |
| `Ale Martin #dbg outcome=restrict` | Card accepted with restrictions |
| `Ale Martin #dbg push=off` | Destination card rejected (no international push) |
| `Ale Martin #dbg pull=off` | Funding pull disabled |

Aliases: `out=` for `outcome=`; `deny` / `reject`; `review` / `nr`; `restrict`; `approve`. `push=off` also turns off domestic push and fast funds.

<Note>
  `ani`, `avs`, `cvv`, and `pen` are accepted so recipes match Card Validation, but they do not change the sandbox decision. Use `outcome=` to force reject / review / restrict.
</Note>


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