Recipes / Daily close (Z-report) dashboard
FinanceReconcile one day of trading: the Z-report and the payment breakdown come from the same pipeline, so they always match to the cent.
The same numbers our back office shows store managers.
One call per day is the whole Z-report: turnover (incl/excl/VAT), non-revenue money (gift cards, tips), the payment breakdown, and the order count. It reuses the exact pipeline behind /api/financial-report, so the numbers reconcile 1:1 to the cent. Dates are Europe/Amsterdam.
# the Z-report for Monday July 14th
curl -s "https://api.storekeeper.me/api/reports/daily-close?date=2026-07-14" \
-H "Authorization: Bearer $TOKEN"
{
"date": "2026-07-14",
"location_id": null,
"currency": "EUR",
"turnover": { "incl_vat": 3412.85, "excl_vat": 3131.06, "vat": 281.79 },
"non_revenue": {
"gift_card_sales": 75.00,
"tips": 12.50,
"payments_on_invoice": null,
"prepayments": null,
"total": 87.50
},
"payments": [
{ "provider_method_type_id": 3, "type_alias": "TerminalDevice", "name": "Card terminal", "value": 2410.30 },
{ "provider_method_type_id": 5, "type_alias": "Cash", "name": "Cash", "value": 914.05 },
{ "provider_method_type_id": 8, "type_alias": "GiftCard", "name": "Gift card", "value": 88.50 }
],
"payments_total": 3412.85,
"balance_check": { "payments_match_incl_vat": true, "difference": 0 },
"order_count": 186
}
location_id if you close per branch. Without it you get the whole account rolled into one Z-report, which will not match a single till.The standalone payments report is the same computation exposed for reconciliation. For one day, set from and to to the same date; the response also carries the paid turnover and a built-in balance check.
curl -s "https://api.storekeeper.me/api/reports/payments?from=2026-07-14&to=2026-07-14" \
-H "Authorization: Bearer $TOKEN"
{
"from": "2026-07-14",
"to": "2026-07-14",
"location_id": null,
"currency": "EUR",
"payments": [
{ "provider_method_type_id": 3, "type_alias": "TerminalDevice", "name": "Card terminal", "value": 2410.30 },
{ "provider_method_type_id": 5, "type_alias": "Cash", "name": "Cash", "value": 914.05 },
{ "provider_method_type_id": 8, "type_alias": "GiftCard", "name": "Gift card", "value": 88.50 }
],
"payments_total": 3412.85,
"paid_turnover_incl_vat": 3412.85,
"balance_check": { "payments_match_incl_vat": true, "difference": 0 }
}
Fetch the account's payment method catalog once and cache it. Key your dashboard labels (and any ledger mapping) on type_alias, never on the numeric id.
curl -s https://api.storekeeper.me/api/payment-methods -H "Authorization: Bearer $TOKEN"
{
"count": 3,
"data": [
{ "provider_method_type_id": 3, "type_alias": "TerminalDevice", "name": "Card terminal" },
{ "provider_method_type_id": 5, "type_alias": "Cash", "name": "Cash" },
{ "provider_method_type_id": 8, "type_alias": "GiftCard", "name": "Gift card" }
]
}
provider_method_type_id is registered per account: id 5 is not Cash everywhere. Cash lives on an internal provider registered for the account, so the id differs between accounts while type_alias stays "Cash". Always match on the alias.Because daily-close and payments come from one pipeline, the sums must agree to the cent. Assert the invariants below before rendering; a mismatch means your date or location filter differs between calls, not rounding.
# invariants for the Z-report screen
sum(payments[].value) == payments_total
balance_check.payments_match_incl_vat == true
daily-close.payments_total == payments.payments_total # same date, same location_id
non_revenue money (gift card sales, tips) is deliberately outside turnover. A gift card sale shows up in the payments the day it is sold and in turnover the day it is redeemed. Show it as its own line on the Z-report, do not add it to turnover.Recepten / Dagafsluiting (Z-rapport) dashboard
FinanceSluit een handelsdag aan: het Z-rapport en de betalingsuitsplitsing komen uit dezelfde pijplijn en sluiten dus altijd tot op de cent.
Dezelfde cijfers die onze backoffice aan winkelmanagers toont.
Eén aanroep per dag is het hele Z-rapport: omzet (incl/excl/btw), niet-omzet geld (cadeaubonnen, fooien), de betalingsuitsplitsing en het aantal orders. Het hergebruikt exact de pijplijn achter /api/financial-report, dus de cijfers sluiten 1:1 op de cent aan. Datums zijn Europe/Amsterdam.
# het Z-rapport voor maandag 14 juli
curl -s "https://api.storekeeper.me/api/reports/daily-close?date=2026-07-14" \
-H "Authorization: Bearer $TOKEN"
location_id mee als je per vestiging afsluit. Zonder krijg je het hele account in één Z-rapport, en dat sluit nooit aan op één kassa.Het losse betalingsrapport is dezelfde berekening, apart beschikbaar voor reconciliatie. Zet voor één dag from en to op dezelfde datum; het antwoord bevat ook de betaalde omzet en een ingebouwde balanscontrole.
curl -s "https://api.storekeeper.me/api/reports/payments?from=2026-07-14&to=2026-07-14" \
-H "Authorization: Bearer $TOKEN"
Haal de betaalmethode-catalogus van het account één keer op en cache hem. Sleutel je dashboardlabels (en elke grootboekmapping) op type_alias, nooit op het numerieke id.
curl -s https://api.storekeeper.me/api/payment-methods -H "Authorization: Bearer $TOKEN"
provider_method_type_id wordt per account geregistreerd: id 5 is niet overal Cash. Contant loopt via een interne provider die per account wordt geregistreerd, dus het id verschilt per account terwijl type_alias "Cash" blijft. Match altijd op de alias.Omdat daily-close en payments uit één pijplijn komen, moeten de sommen op de cent gelijk zijn. Controleer de onderstaande invarianten voor je rendert; een verschil betekent dat je datum- of locatiefilter tussen aanroepen verschilt, geen afronding.
# invarianten voor het Z-rapportscherm
sum(payments[].value) == payments_total
balance_check.payments_match_incl_vat == true
daily-close.payments_total == payments.payments_total # zelfde datum, zelfde location_id
non_revenue-geld (cadeaubonverkoop, fooien) staat bewust buiten turnover. Een cadeaubon zit in de betalingen op de verkoopdag en in de omzet op de inwisseldag. Toon het als eigen regel op het Z-rapport, tel het niet bij de omzet op.