Going Live
What to verify before you switch to live keys and start moving real money.
Going live is a configuration change, not a code change. The endpoints, payloads, and webhooks are identical — only your key differs. That is convenient, and it is also the risk: nothing stops a live key being used against code that was only ever exercised in test mode.
Work through this list before you switch.
Credentials
- Your backend uses the live secret key (
sk_live_). - The live key is supplied by environment variable, not committed to source control.
- No secret key is reachable from browser or mobile code. Your frontend calls your backend; your backend calls Kyshi.
- Your test key still works in your staging environment, so you can keep testing after launch.
Remember the base URL does not change between modes. The key is the only thing separating a test charge from a real one. See Test Mode And Sandbox.
Webhooks
- Your live webhook URL is configured in your business settings, separately from the test URL.
- The endpoint is publicly reachable over HTTPS.
- Signatures are verified on every request, using a constant-time comparison.
- Your handler reads the raw request body, not a re-serialised parsed object.
- You respond
2xxwithin 10 seconds, and do the real work afterwards. - Unrecognised events return
2xxrather than an error. - Deliveries are deduplicated on
meta.kyshiEventId.
See Webhook and Webhook Events.
Money Handling
- Value is released only after server-side verification, never on a client-side signal.
- Value is released exactly once per order, even if a webhook arrives twice.
-
PARTIALandOVERPAIDvirtual account collections are handled. -
IN_REVIEWdoes not fall through to a success path. -
transfer.reversedcan unwind a payout your system already marked final. - Unknown statuses default to "wait and verify", never to success.
Currency And Pricing
- The currencies you need are enabled for live mode.
-
amountCurrencyis set deliberately on every creation call. - Amounts are sent in major units. Verify one real amount end to end.
-
feeBearermatches your commercial intent. - Where
feeBearerisCUSTOMER, you displaypayableAmountand notrequestedAmount.
See Countries And Currencies and Fees And Who Pays Them.
Reconciliation
- You store your own
referenceon every transaction. - You store
meta.fxRateandmeta.feeBreakdownat the time of the sale. - Your finance process reconciles at settlement batch level, not per transaction.
- You have a scheduled job that lists recent transactions and repairs anything a missed webhook left behind.
See Settlements.
Operations
- Failed payments surface a usable message to the customer, not a raw provider string.
-
5xxresponses are retried only where the operation is safe to repeat or you supplied your own reference. - You log the Kyshi
referenceandmeta.transactionIdon every payment, so support can trace a specific payment. - Someone owns the alert when webhook processing starts failing.
The First Live Transaction
Do not let your first live transaction be a customer's.
Put through one real payment of the smallest viable amount, yourself, and follow it all the way through: checkout, webhook, verification, value released, and the transaction appearing correctly in your records. Then check it again once it has settled.
A live smoke test takes ten minutes and catches the class of problem that test mode structurally cannot — real bank rails, real card issuers, real customers behaving unexpectedly.
After Launch
Watch these in the first week:
| Signal | What it usually means |
|---|---|
Rising PARTIAL collections | You are displaying the wrong amount to customers. |
| Webhook retries climbing | Your endpoint is slow or intermittently failing. |
404 on objects you just created | A mode mismatch — test key reading live data, or the reverse. |
| Settlement not matching your ledger | Fees or FX not captured at the time of sale. |
Next
- Test Mode And Sandbox — the test pass to complete first
- Errors — what each status code means
Updated about 20 hours ago
