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

# Go-live checklist

> The rules Zapyd enforces, and everything to check before production.

Work through this page in sandbox. The Zapyd team reviews the same points before issuing production credentials.

## Rules Zapyd enforces

Breaking these rules gets the order rejected, refunded or held. There's no soft error.

| Rule | Applies to | What happens if broken |
| - | - | - |
| The user pays from a bank account in their own KYC name | Payin | Refunded (`THIRD_PARTY_PAYMENT`) |
| The user pays the exact quoted amount, in one transfer | Payin | Refunded (`INCORRECT_AMOUNT`) |
| Fiat goes to the quotation's `deposit_instructions` only | Payin | Not matched |
| Crypto goes to the quotation's `wallet_address`, with the quoted asset and network | Payout | Possible permanent loss |
| A transaction hash funds one payout only | Payout | Rejected |
| The bank account holder is the customer | Payout | Bank `NAME_MISMATCH` |
| Initiate before `expiry_time`. Each quotation is used once | All | Rejected. Create a new quotation |

## Checklist

### Customers and KYC

* [ ] Customers are created with your `client_reference_id`, and you store the Zapyd `id`
* [ ] Orders are blocked until the customer is `VERIFIED`
* [ ] `FAILED` KYC shows the user what to fix, and only the failed part is resubmitted
* [ ] A customer blocked after three attempts is handled

### Payins

* [ ] The rate, fees and `receiving_amount` shown come from the quotation
* [ ] `deposit_instructions` come from each quotation and are never cached
* [ ] The transfer reference is collected and sent as `transaction_reference_id`
* [ ] Crypto is credited only on `SUCCESS`, never on `ON_HOLD`, `FAILED` or `REFUNDED`

### Payouts

* [ ] Asset, network and `wallet_address` are read from the quotation for every transfer
* [ ] Per-order payouts are initiated with the matching `transaction_hash`
* [ ] `IN_REVIEW` with an `rfi_link` sends the customer to answer it
* [ ] The UTR from `SUCCESS` is shown to the user

### Webhooks

* [ ] The signature and the timestamp window are checked on every event
* [ ] The endpoint returns `2xx` fast and processes the event asynchronously
* [ ] Events are deduplicated on `id` and `event`
* [ ] Orders without a final status after a set time are polled, and you get an alert

### Errors and operations

* [ ] Signing passes the [test vector](/guides/development-and-testing/authentication#test-vector) in a unit test
* [ ] Code branches on `err_code`, and only `429` and `5xx` are retried, with backoff
* [ ] Users never see raw `err_code` values
* [ ] Requests, Zapyd IDs and responses for money-moving calls are logged

### Security

* [ ] The API secret lives in a secrets manager and never reaches a browser or mobile app
* [ ] Widget Initialize runs server-side, and only `widget_link` reaches the client
* [ ] Sandbox and production credentials are kept separate

## Switch to production

<Steps>
  <Step title="Get production credentials">
    Share your sandbox results with the Zapyd team. After review, you get production keys.
  </Step>

  <Step title="Change the configuration">
    Change the host from `sandbox.zapyd.com` to `api.zapyd.com`. Swap the keys and the widget `app_id`. Move from Sepolia to mainnet networks. Register your production webhook URL.
  </Step>

  <Step title="Remove sandbox-only code">
    Remove the mock status calls and your test customers.
  </Step>

  <Step title="Run a small live order">
    Complete one small real order in each direction you support, then roll out.
  </Step>
</Steps>
