# Go-live checklist

> What to check in your integration before the merchant's first real sale goes through it.

Go through this list with the test key before you switch to the live key.

## Keys

- [ ] The key is kept on your server only, never in a mobile app, a browser or a code repository.
- [ ] The live key has only the permissions your system uses, and only the branches it works in.
- [ ] Your system reads the key from configuration, so replacing it needs no new release.
- [ ] You know who at the merchant revokes and reissues the key, and you handle `401 revoked_api_key` and `401 expired_api_key` by alerting someone, not by retrying.
- [ ] If the key has an expiry date, someone owns renewing it before that day.

## Requests

- [ ] Every `POST`, `PATCH` and `DELETE` sends an `Idempotency-Key`, one per logical operation, and a retry sends the same key.
- [ ] You retry only timeouts, dropped connections, `409 idempotency_in_progress` and `5xx`, with the same key. See [Retries and idempotency](https://docs.kosoor.com.sa/idempotency.md).
- [ ] Your code branches on `code`, never on `message`.
- [ ] You log the `Request-Id` of every call, so you can quote it to support.
- [ ] Branch, item and payment method ids come from `GET /v1/branches`, `GET /v1/items` and `GET /v1/payment-methods`, not from constants.
- [ ] Each sales invoice, payment and credit note carries your own `referenceId`, and your system handles `409 reference_id_taken` by reading `existingId`.
- [ ] A phone in a query string is encoded: `%2B966...`, not `+966...`.

## Money

- [ ] You read `total`, `lines[].unitDiscount`, `amountPaid` and `amountDue` from the reply, not from your request.
- [ ] To pay an invoice in full, you send `payment` without `amount`.
- [ ] Sales to a person are paid at issue; only company customers buy on account.

## ZATCA

- [ ] Your system shows or stores `zatca.status` for every invoice and credit note, and treats `pending` as issued, not failed.
- [ ] A `rejected` document reaches a person at the merchant who can correct it.
- [ ] You handle `422 zatca_rejected` and `422 customer_address_incomplete` on standard invoices; you tested both with the sandbox fixtures.
- [ ] You fetch a standard invoice's PDF only once it is `cleared`.

## Switching to live

- [ ] The merchant issued a live key with the same permissions and branches as the test key.
- [ ] Your system checks the `Kosoor-Mode` header: present as `test` in the sandbox, absent on live data.
- [ ] You made one real call and the merchant found it in **Settings → Developers → Request log**, under **Live**.
- [ ] Customers you created in the sandbox are created again, or found, on live data: the sandbox's customers are its own.

## Support

Kosoor support answers on WhatsApp only: [+966 12 606 1770](https://wa.me/966126061770). There is no phone line and no email. Send the `Request-Id` of the call and what you expected.

Source: https://docs.kosoor.com.sa/go-live
