> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.crisscross.money/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.crisscross.money/_mcp/server.

# Going Live

> The checklist for taking a CrissCross integration live — what to have tested, what changes in production, and the live pass for each market.

Going live changes less than you might expect. The URL stays the same, and the requests stay the same. What changes is the credentials you load, and a few things that only exist in production.

### Before you ask for production access

Make sure you've tested the parts that apply to you — see [Which parts you need](/testing-overview#which-parts-you-need).

For every product:

* **The happy path**: [Your First Payment](/testing-first-payment), [Your First Payout](/testing-first-payout), [Your First Trade](/testing-first-trade) or [Your First Withdrawal](/testing-first-withdrawal).
* **Failures**: your integration shows a sensible message for each failure your markets can produce.
* **Webhooks**: your endpoint verifies signatures, handles duplicate deliveries, and updates your records from the events for your products — `transaction.*`, `payout.*`, or the Exchange `order.*`, `withdrawal.*`, `deposit.*` and `beneficiary.*` events. See [Webhooks](/core-concepts-webhooks).

If you use Collect or Payouts:

* **The approval flow for each market**, using the Approval flow column on its [country page](/payment-method-mobile-money#supported-countries) and the matching [trigger numbers](/testing-trigger-numbers).
* **Duplicate references**: resending a payout with a used `merchantReference` returns `409 Conflict`, and your code treats that as "already sent", not as a failure.

If you use Exchange:

* **Quote expiry**: your code accepts a quote before `expiresAt`, and requests a new one on `QUOTE_EXPIRED` rather than retrying the old one.
* **Retries are safe**: creating a beneficiary or a withdrawal sends an `Idempotency-Key` — the only Exchange endpoints that take one — so a retry returns the original beneficiary or withdrawal instead of creating a duplicate. Accepting a quote and cancelling a withdrawal need no key: a retry returns the original order or the cancelled withdrawal.
* **Reserved funds**: your records treat a pending withdrawal as reserved, not spent, until it completes. A trade moves your balances as soon as you accept the quote.

Then ask your account manager to enable production access.

### What to change

**1. Load your production credentials.** Swap in your production `client_id`, `client_secret` and, for Collect and Payouts, `merchantId`. Keep them in a separate secret store from the sandbox set, and never fall back to production credentials when a sandbox call fails. Because the URL is the same, the credentials are the only thing that decides whether money moves.

**2. Subscribe a production webhook endpoint.** For Collect and Payouts, webhook subscriptions belong to a `merchantId`, so the endpoint you set up for the sandbox won't receive production events. [Add an endpoint](/core-concepts-webhooks#creating-a-webhook-subscription) for your production merchant, subscribe it to the same events, and verify signatures with its own secret. Check `paymentAttributes.merchant_type` is `"real"` before you treat an event as a real payment. For Exchange, subscribe the production endpoint to the Exchange events too — see [Exchange Webhooks](/exchange-webhooks#securing-and-delivery).

**3. Check your network rules.** Your servers need outbound HTTPS to `api.crisscross.money`. If you allowlist incoming webhook traffic, ask your account manager for the current [source IP ranges](/core-concepts-webhooks#ip-allowlisting).

**4. Fund your balance.** Production payouts, trades and withdrawals draw on your real CrissCross balance.

* **Payouts:** see [Funding Your Payout Balance](/payout-getting-started#funding-your-payout-balance).
* **Exchange:** send real funds to the deposit details returned by [Get deposit account details](/api-reference/exchange/exchange/deposits/get-deposit-account-details). If they include a `reference`, put it on the payment so the deposit is credited to your account automatically. See [Funding](/exchange-funding#deposits).

**5. Register your production beneficiaries early.** If you withdraw from Exchange, sandbox beneficiaries don't carry over. In production a fiat beneficiary is only approved once its compliance documents are reviewed, so create yours well before your first withdrawal is due.

**6. Don't reuse sandbox data.** [Bank codes](/api-reference/payouts/payouts/lookups/list-payout-banks), [rates](/testing-rate-locks) and [rate limits](/rate-limiting) can all differ in production. Fetch bank codes at runtime rather than hardcoding them, because some sandbox codes are placeholders that production rejects.

### Run a live pass for each market

The sandbox can't show you what the market does: the operator's prompts and timeouts, payer limits, settlement timing, or how strictly names are matched. Before you launch a market, your solutions engineer runs a small-value live payment with you on production credentials.

Check that:

* the payer gets the prompt, OTP or redirect you expect for that operator
* the payment reaches `COMPLETED` and your production webhook receives it
* a refund or payout, if you use them, reaches the recipient
* the amounts in your records match what the payer paid

For Exchange, the live pass is a small deposit, trade and withdrawal. Check that:

* the deposit is credited and your balance matches what you sent
* a small trade fills at the quoted rate
* a withdrawal to your own beneficiary arrives, and your records match the [balance statement](/api-reference/exchange/exchange/balances/get-balance-statement)

### After launch

* Watch delivery failures in the webhooks dashboard. An endpoint that keeps failing is [disabled automatically](/core-concepts-webhooks#endpoint-auto-disabling).
* If you miss events, [replay them](/core-concepts-webhooks#resending-and-replaying-webhooks) rather than guessing the state.
* Check [status.crisscross.money](https://status.crisscross.money) if payments start failing across the board.