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

# Test your integration

> Validate payment routes, payment links, and local fiat orders with simulated test API keys.

Use **`rmf_test_`** keys against `https://api.remitflex.io/v1`. Create keys in the [dashboard](https://dashboard.remitflex.io) with `api:read` and `api:write` (full access).

|            | Test                                                            | Live                          |
| ---------- | --------------------------------------------------------------- | ----------------------------- |
| Key prefix | `rmf_test_`                                                     | `rmf_live_`                   |
| Base URL   | `https://api.remitflex.io/v1`                                   | Same                          |
| Providers  | In-process simulators (no real Relay/PayCrest/StRails/on-chain) | Live Relay, PayCrest, StRails |

Environment is encoded in the key prefix (or dashboard `X-Remitflex-Environment` header for JWT sessions). There is no separate sandbox hostname.

```bash theme={null}
export REMITFLEX_API_KEY="rmf_test_YOUR_KEY"
export API_BASE="https://api.remitflex.io/v1"
```

<Info>
  All curl examples below use **`rmf_test_`** keys. They exercise Remitflex APIs end-to-end with **simulated** provider settlement — not testnet deposits or real fiat rails.
</Info>

## Simulated settlement

Test mode never calls external Relay, PayCrest, or StRails APIs. Instead:

1. **Create** — Your API call returns a simulated deposit address and provider id (for example `sim_relay_…`).
2. **Auto-settle** — After about **8 seconds** (`SANDBOX_AUTO_SETTLE_MS`), the in-process simulator marks the request successful and fills synthetic tx hashes.
3. **Sync** — Background jobs and read paths sync simulated status into your payment routes, collections, swaps, and offramps — same as live mode.
4. **Force** — Skip the wait with `POST /v1/sandbox/simulate` (test environment only).

Check simulator settings:

```bash theme={null}
curl -s "$API_BASE/sandbox/status" \
  -H "Authorization: Bearer $REMITFLEX_API_KEY" | jq .
```

Force a provider request to complete immediately:

```bash theme={null}
curl -s -X POST "$API_BASE/sandbox/simulate" \
  -H "Authorization: Bearer $REMITFLEX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "provider": "relay",
    "id": "sim_relay_REPLACE_WITH_REQUEST_ID"
  }' | jq .
```

Supported `provider` values: `relay`, `paycrest`, `strails`. Optional `status` overrides the default terminal status (for example `"failed"`).

Requires a test key with an `api:write` secret key.

## Payment link (invoice)

```bash theme={null}
curl -s -X POST "$API_BASE/collections" \
  -H "Authorization: Bearer $REMITFLEX_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
    "linkMode": "invoice",
    "pricingType": "fixed",
    "amount": 10,
    "destinationChainKey": "solana",
    "destinationCurrency": "USDC",
    "destinationAddress": "YOUR_WALLET",
    "label": "Test invoice"
  }' | jq .
```

Open the returned `payUrl`. The pay page shows a **simulated** deposit address. Settlement completes automatically (\~8s) or when you call `/sandbox/simulate` with the Relay request id from the collection.

## Checkout link

```bash theme={null}
curl -s -X POST "$API_BASE/collections" \
  -H "Authorization: Bearer $REMITFLEX_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
    "linkMode": "checkout",
    "pricingType": "open",
    "destinationChainKey": "solana",
    "destinationCurrency": "USDC",
    "destinationAddress": "YOUR_WALLET",
    "label": "Donate"
  }' | jq .
```

Share the same `payUrl` for every visitor. Each quote creates a session — list them with `GET /collections/{collectionId}` (checkout parent UUID).

## Payment route

```bash theme={null}
curl -s "$API_BASE/payment-routes/chains" \
  -H "Authorization: Bearer $REMITFLEX_API_KEY" | jq .

curl -s -X POST "$API_BASE/payment-routes" \
  -H "Authorization: Bearer $REMITFLEX_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Test route",
    "originChainKey": "ethereum",
    "destinationChainKey": "solana",
    "destinationCurrency": "USDC",
    "destinationAddress": "YOUR_WALLET"
  }' | jq .
```

Route deposits sync from the simulated Relay client — no on-chain transfer required.

## Offramp quote

Verify your key has `api:read`:

```bash theme={null}
curl -s "$API_BASE/fiat/currencies" \
  -H "Authorization: Bearer $REMITFLEX_API_KEY" | jq .

curl -s "$API_BASE/fiat/rates/USDC/10/NGN" \
  -H "Authorization: Bearer $REMITFLEX_API_KEY" | jq .
```

Fiat rate and institution endpoints use simulators in test mode. See [Local fiat](/products/fiat-rails) for the full payout flow.

## Webhooks

Create a key with `api:write`, then register an HTTPS receiver:

```bash theme={null}
curl -s -X POST "$API_BASE/webhooks" \
  -H "Authorization: Bearer $REMITFLEX_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com/webhooks/remitflex",
    "events": ["swap.updated", "collection.updated"]
  }' | jq .
```

Copy `secret` once, then `POST /webhooks/{webhookEndpointId}/test` to queue a `webhook.test` ping for **that endpoint** (`{webhookEndpointId}` is the RemitFlex webhook endpoint UUID from `POST /webhooks`; the test bypasses the event allowlist). Simulated settlements still emit real outbound webhooks to your endpoint. See [Webhooks](/guides/webhooks).

If you register with a narrow `events` allowlist, money events still require those types to be listed — only the dedicated test ping is exempt.

## Retries

Send `Idempotency-Key` on every mutating request. Reuse the same key to safely retry after a timeout; use a new key for each distinct operation.

<Warning>
  Do not commit API keys to git or expose them in client-side code. Revoke compromised keys in the dashboard.
</Warning>
