Payout accounts¶
Which account the money people pay goes into: the app's payout account (the organisation's admin points it at the organisation's own account; any other is set by the operator), an organisation's Gerege Wallet account, and, on a multi-owner platform, each sub-merchant's payout account (approved in Gerege App by the account's holder). About 8 minutes to read. Step-by-step integration: Pay with Gerege App.
The app's payout account¶
- The organisation's admin points the app's takings at the organisation's own Gerege Wallet account from the console (below, «To the organisation's account»). Any other account (another organisation's, a person's) is set by the operator — after the contract and the business check (KYB). There is no API for your server integration (client credentials) to set it, deliberately: pointing an app's takings at another account is the one edit that would turn a leaked credential into stolen money.
- The operator checks the account with the ledger (active, MNT) and records its holder (a person or an organisation).
- Without a payout account, creating a live intent answers
409 payouts_not_configured— refused at creation so that nobody is ever shown a payment sheet that cannot succeed. Test mode needs no payout account. - When the account changes, payments captured earlier stay where they went; their refunds come out of that account.
- For an app without settlements (every app today) each capture moves the money straight into this account, and refunds come out of it too (Refunds); with settlements on, through settlements (Settlements).
An organisation's Gerege Wallet account¶
The natural account for a merchant's takings is the organisation's own Gerege Wallet account. The organisation must have Gerege Wallet installed, and an admin opens it (an impersonated session can only read):
| Method | Path | Answer |
|---|---|---|
| GET | /api/v1/bank/org/{tenant}/accounts |
200 {"accounts": [Account]} |
| POST | /api/v1/bank/org/{tenant}/accounts {"name"?} (≤ 60) |
201 a new account, 200 the existing one — one account per organisation |
The account holder's name is the organisation's legal name (and registration number) as registered on the platform. Moving money from it to a real bank: Withdrawals to a bank.
To the organisation's account (console, admin)¶
The console's Balance → App payout → «To the organisation's account» (PUT /api/v1/miniapp/dev/apps/{id}/payout
{"account_id": "<the organisation's account id>"}, not server-to-server) makes the organisation's own account the
payout of an app — a mini app or a merchant:
- The organisation's admin only (not an impersonated session), after signing in again (within 10 minutes) — and not in a sandbox organisation.
- The account must be an active MNT account of your organisation (from
GET /api/v1/bank/org/{tenant}/accounts). Any other account →422 account_not_owned— that one is the operator's to set. - An account the operator set can be replaced by your own this way; the audit records the previous account (last four) and the time of the sign-in, and the operator is notified. Removing the payout is the operator's.
- The answer is the app (
payouts_configured: true,payout_account: "******1234") andterms— refunds of payments made into this account (within 90 days) are taken back from it; the console shows them beside the button. - Payments captured earlier, and their refunds, stay with the old account; with settlements on, a pending or failed settlement keeps the account it stored, and the next one pays the new account.
- The go-live checklist's
payoutstep (who: admin) turns green.
A sub-merchant's payout link¶
On a multi-owner platform (a vending network whose machines have different owners, for example) each sub-merchant is paid into its own payout account. Your server's word alone never points somebody's takings at an account — only the account holder's approval in Gerege App does.
curl -sS https://geregeapp.mn/api/v1/miniapp/sub-merchants/9a7c5e3b-1d2f-4e6a-8b0c-7d9e1f3a5b7c/payout-link \
-u "$GEREGE_LIVE_CLIENT_ID:$GEREGE_LIVE_CLIENT_SECRET" \
-H "Content-Type: application/json" \
-d '{"account": "MN75 0098 0009 8123 4560"}'
account — an IBAN (MN + 18 digits) or a 10-digit account number; spaces and dashes are fine. Live
keys only, scope payout_links:write (test → 403 live_only; the list GET …/payout-links needs sub_merchants:read). Rate limit — 30 a minute (each request sends somebody a push).
Answer 201:
{
"id": "…",
"object": "payout_link",
"sub_merchant": "9a7c5e3b-1d2f-4e6a-8b0c-7d9e1f3a5b7c",
"status": "pending",
"account_masked": "******2345",
"requested_at": "2026-10-27T09:00:00Z",
"expires_at": "2026-11-03T09:00:00Z",
"decided_at": null,
"terms": {
"mn": "Энэ данс руу орсон төлбөрүүдийн буцаалтыг (төлбөрөөс хойш 90 хоногийн дотор) энэ данснаас хасна.",
"en": "Refunds of payments made into this account (within 90 days of each payment) are taken back from this account."
}
}
- Who is asked follows the ledger's holder: a person's account → that person; an organisation's account → every active admin at that moment (one approval is enough). They get a notification in Gerege App — its text is only the app's approved name (nothing you wrote).
- A request is valid for 7 days. A new request cancels the earlier
pendingone. terms— what approving means: refunds of payments made into this account (within 90 days) are taken back from it. The request, the notification and the approval screen all say so.- At the moment of approval the platform checks again: the account is active MNT, and the approver is its owner (or
an admin of the owning organisation today). Once approved it becomes the sub-merchant's
payout_account(******2345) withpayouts_configured: true, and the earlierapprovedone becomessuperseded. GET /sub-merchants/{sid}/payout-links— the requests, newest first (≤ 50). Requests and answers are history (never deleted).
status |
Meaning |
|---|---|
pending |
waiting for the holder's answer |
approved |
approved — the current payout |
declined |
the holder declined |
canceled |
replaced by a newer request |
superseded |
another link was approved later |
expired |
no answer within 7 days |
The holder sees the request in Gerege App (iOS) under Settings → Wallet → «Payout links» (or from the request's notification), reads the terms and approves with Face ID or declines. For an organisation's account, any one of its current admins approving is enough.
Errors¶
| HTTP | code |
When |
|---|---|---|
| 400 | validation_error |
account malformed, not found, inactive or not MNT |
| 403 | live_only |
the request was sent with a test credential |
| 409 | sub_merchant_disabled |
the sub-merchant is disabled |
| 409 | payouts_not_configured |
a live intent: the app has no payout, or the sub-merchant's payout is not approved |
| 422 | account_not_owned |
console, «To the organisation's account»: the account is not your organisation's — contact the operator |
| 422 | account_unavailable |
console, «To the organisation's account»: no such account, not active, or not MNT |
| 403 | admin_required · impersonated · fresh_sign_in_required |
console: not the admin · an impersonated session · sign in again |
| 422 | account_unsupported |
the account's holder is neither a Gerege App person nor an organisation |
| 422 | no_admin |
an organisation's account with no admin to ask |
| 502 | core_unavailable |
core banking did not answer — retry |
| 503 | directory_unavailable |
the organisation's admins could not be determined just now ("could not tell", not "none") — retry |
| 503 | payments_unavailable |
core banking is not enabled |
The complete list: Error codes.