Statements¶
A statement lists every movement of an app's (or a sub-merchant's) money, one row each, by Ulaanbaatar date — for the
month-end close, bookkeeping and Excel. About 6 minutes to read. You need a member with miniapp.finance in the
console, or an API key with the settlements:read scope on your server.
Where to get one¶
| Who | Path | Authentication |
|---|---|---|
| Console | GET /api/v1/miniapp/dev/statements?app_id=… |
a signed-in session, miniapp.finance (or an administrator); app_id is required — a statement is one app's |
| Your backend | GET /api/v1/miniapp/statements |
Basic (API keys only — not a person's token), scope settlements:read; the app and the environment are the key's |
curl -sS "https://geregeapp.mn/api/v1/miniapp/statements?from=2026-10-01&to=2026-10-31&format=csv" \
-u "$GEREGE_CLIENT_ID:$GEREGE_CLIENT_SECRET" -o statement-2026-10.csv
| Parameter | Meaning |
|---|---|
from, to |
YYYY-MM-DD, Ulaanbaatar days, both included. Default: the 30 days up to today; ≤ 366 days; from after to or a bad date → 400 invalid_range |
sub_merchant_id |
omitted: every stream (the app's own and each sub-merchant's); empty (sub_merchant_id=): only the app's own stream; a UUID: that sub-merchant's |
format |
json (default) or csv; anything else → 400 invalid_format |
environment |
console only: live (default) or test. On the server it is the key's environment — a test key reads the sandbox's statement |
One statement holds at most 100 000 rows; more is 422 statement_too_large (max_rows) — split the range. Rate
limits: 60/min on the server, 30/min in the console. Other errors: the «Dashboard, statements and simulation» section
of Error codes.
Row types¶
A statement follows each stream's clearing balance (money waiting for a settlement): balance_after is that
stream's balance after the row, net its change.
type |
When | gross |
fee |
net |
|---|---|---|---|---|
captured |
a payment reached the app (confirmed_at) |
+amount | 0 | +amount |
refunded |
a refund succeeded | −amount | 0 | −amount |
fee |
a paid settlement's fee (+ when fees were given back) | 0 | −fee | −fee |
settlement_paid |
money left for the payout account | 0 | 0 | −paid |
fee_carried |
a settlement carried its fee to the next one (nothing to take it from) | 0 | −amount | 0 |
clearing_carried |
refunds beyond what a settlement took in, carried to the next | −amount | 0 | 0 |
- For an app without settlements (every app today), for payments captured before the switch and in test mode,
the money goes straight to the payout account, so every
capturedrow is followed at once by asettlement_paid(−amount), and every refund out of the payout account by asettlement_paid(+amount) — the stream's balance stays 0. - Only paid settlements appear; pending, failed and voided ones do not.
- Rows are in time order, then
captured→refunded→ settlement.
JSON¶
{
"object": "statement",
"app_id": "2c4b8e1a-7d3f-4a5b-9c6d-1e2f3a4b5c6d",
"sub_merchant": null,
"environment": "live",
"from": "2026-10-01",
"to": "2026-10-31",
"timezone": "Asia/Ulaanbaatar",
"currency": "MNT",
"streams": [{"sub_merchant": null, "opening_balance": 0, "closing_balance": 0}],
"totals": {"captured": 45000, "refunded": 0, "fees": 0, "settlement_paid": 45000, "net": 0},
"data": [
{"date": "2026-10-22", "at": "2026-10-22T08:59:55Z", "type": "captured", "payment_intent": "pi_4fQ2mX8kLp0aZr7TbN3cVw9E",
"refund": null, "settlement": null, "sub_merchant": null, "reference": "order_8812",
"gross": 45000, "fee": 0, "net": 45000, "balance_after": 45000, "currency": "MNT"},
{"date": "2026-10-22", "at": "2026-10-22T08:59:55Z", "type": "settlement_paid", "payment_intent": "pi_4fQ2mX8kLp0aZr7TbN3cVw9E",
"refund": null, "settlement": null, "sub_merchant": null, "reference": "order_8812",
"gross": 0, "fee": 0, "net": -45000, "balance_after": 0, "currency": "MNT"}
]
}
streams[]— each stream's opening (opening_balance, at 00:00 of thefromday) and closing balance. For every stream,opening_balance + Σ net = closing_balance.totals—captured(Σ gross +),refunded(Σ refunds, as a positive number),fees,settlement_paid,net.atis UTC,datethe Ulaanbaatar date.
CSV¶
The columns are fixed (an Excel formula built on them does not break when a field is added):
date,type,payment_intent,refund,settlement,sub_merchant,reference,gross,fee,net,balance_after,currency
- UTF-8 with a BOM — Excel opens Mongolian text correctly; comma-separated; whole ₮.
- The file is named
statement-<slug>-<environment>-<from>-<to>.csv. - A
referencestarting with=,+,-or@gets a leading'(so Excel does not run it as a formula).
The console also exports the payments list as CSV (GET /api/v1/miniapp/dev/payments?format=csv, miniapp.finance)
— one row per intent (the «From the dashboard» section of Payment intent).
Reconciling¶
- Each month, pull a statement with
from/toset to the month's first and last day. - Match the sum of the
settlement_paidrows against what reached the payout account; with settlements on, match eachsettlementid with theintents[]/refund_items[]ofGET /settlements/{id}(Settlements). - Match
referenceagainst your own orders; for anything missing,GET /payment-intents?reference=…(Reconciliation).