Skip to content

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") and terms — 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 payout step (who: admin) turns green.

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 pending one.
  • 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) with payouts_configured: true, and the earlier approved one becomes superseded.
  • 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.