Go-live checklist¶
A printable list to walk through once as a team, ticking it off, before taking live payments. Time: 1–2 hours (after running every flow once in test mode). You need: an integration working in test mode (Sandbox) and access to the console.
Technical¶
Webhooks
- The live environment's webhook endpoint is
https://, public, with no redirect and its own secret (separate from test); the endpoint's «Send test» (…/webhook-endpoints/{eid}/test) saysok: true. Its event filter (event_types) includes every type your handler expects. - The signature is checked over the raw body, against every
v1, within ±300 seconds (Verifying signatures). - Duplicates are dropped by
Gerege-Event-Id; an event arriving twice never hands goods over twice. - 2xx is answered within 10 seconds (slow work is queued).
- Ordering is not guaranteed: an old event arriving late does not move a state backwards — re-read with
GETand decide (Idempotent handler). - Unknown
types are answered 2xx and ignored. - It works even when a webhook never comes: a regular reconcile — the Events API
(
GET /events, 30 days) orGET /payment-intents?status=…/?reference=…— checks every pending order (Reconciliation). An endpoint failing for 5 days becomesauto_disabled— it is agreed who receives the admins' notifications.
Payments
- The amount and description come from your server;
description≤ 80, a short order summary (Security checklist). - One order = one intent = one
Idempotency-Key; network errors,429and5xxare retried with the same key. - After a redirect,
return_url?pi=is not trusted: the server matchesstatus,amountandreferencewithGET /payment-intents/{id}. - Every status is handled:
requires_confirmation,processing(a202answer — wait and read again),requires_capture,succeeded,partially_refunded,refunded,canceled,expired,failed(payable again — do not close the order) (Payment intent). - The right behaviour for error codes:
in_progress(wait, read again),idempotency_conflict,terminal_busy(cancel the open intent, then retry),expired,not_capturable,payouts_not_configured,payments_unavailable(Error codes). - Manual capture:
capturewhen dispensed,cancelwhen not, withincapture_within; partly dispensed means a full capture plus a refund. - Refunds: their own
Idempotency-Key; a202/pendingis finished byrefund.succeeded/refund.failed; the 90-day limit (Refunds).
Credentials
- The live secret is only on servers, in a secret manager / environment variables; switching from test to live changes only the credentials — code and URLs stay the same.
- One named key per server with the fewest scopes; test keys no longer needed are revoked.
- The team knows the rotation procedure: API keys roll with an overlap, the default key (
POST …/credentials— today the only way to a live secret) is replaced at once, with no overlap (Security checklist).
Business and registration¶
- The organisation and the app (
kind: merchantor a mini app) are registered in the console. - Submission requirements are met: the privacy policy (
privacy_url), terms of service (terms_url) and support (support_url) links — whenhttps://, each answers200without a redirect; the app's webhook URL (endpoint №1,POST …/webhook) is set; a live secret issued with the default key. For a mini app, a checked manifest (512×512 PNG icon) (Review requirements). - For a merchant, the return hosts (
return_hosts, ≤ 5, exact hosts) are registered before review (changing them after approval means another review). - The app is approved (before that, the live credential is
401 invalid_client). - The payout account that receives the takings is set — by the admin to the organisation's own account in the
console, or by the operator (otherwise a live intent is
409 payouts_not_configured) (Payout accounts). - Each sub-merchant's payout link is approved by its holder in Gerege App.
- Fees and the settlement schedule are agreed with the operator (Fees).
- The organisation's representative has signed the merchant agreement with eID (console → Agreements; the
miniapp.agreements.signpermission, a representative listed in eID). Submission and live keys do not require it yet, but the operator checks. - The business profile (KYB) is filled in, proved and submitted (console → Business profile, 1.14.0): trade name, logo (512×512 PNG), MCC, website, support/technical/finance e-mail and the support phone (each proved with a code), owners of 25 % or more, the registration certificate (and a licence when the MCC needs one). The legal name and register come from what was registered when the organisation was opened with eID. Only an admin submits, after signing in again; the operator approves.
- The go-live checklist is green on the server:
GET /api/v1/miniapp/dev/account(organisation) andGET /api/v1/miniapp/dev/apps/{id}/go-live(app) — every stepdone. - You know your limits: a new merchant (
new) ≤ 1,000,000₮ per payment and ≤ 10,000,000₮ a day;standard10M / 200M; ask for more in the console. Where the installation enforces going live (MINIAPP_GO_LIVE=on), a live intent without the agreement, an approved profile or within the limits is a409(agreement_required,business_profile_required,business_limit_exceeded…).
User experience¶
- A clear «Pay with Gerege App» button, with a loading state when pressed.
- QR / terminal: when
payment_intent.claimedarrives, show «Confirm on your phone»; show how long is left (expires_at). - A cancel button (
cancel), and clear Mongolian messages with a retry for expiry (expired) and declines (failed). - On success, show a receipt / the order number (
reference); the refund policy is visible before paying. - Every path of a redirect checkout has been walked through on both a computer and a phone.
The first day live¶
- One real payment of a small amount (say 100₮) → webhook → fulfilment → refund.
- No
failedevents in the console's «Deliveries» (live endpoint); the dashboard's payment list matches your orders. - The team knows how to reach Support.