Educational billing & VAT invoices
Flow issues VAT-compliant education invoices automatically when a payment succeeds. Invoices are built from session lineItems (or a single line derived from the session amount and description).
Manage invoices, templates, and settings from Dashboard → Billing.
How it works
- Your server creates a session with
amount(VAT-inclusive) and optionallineItems. - The customer pays on hosted checkout.
- On
payment.success, Flow issues a bill (if auto-issue is enabled). - The bill can be emailed and/or posted to your ERP REST endpoint.
- Your webhook includes
billId,billNumber, and VAT totals.
Line items on sessions
Each line's amount is VAT-inclusive (gross). The session amount must equal the sum of all line amounts.
| Field | Required | Description |
|---|---|---|
skuItem | No | SKU or fee code |
description | No | Line description on the invoice |
amount | Yes | Line total including VAT |
amountWithoutVat | No | Net amount; derived at 15% VAT when omitted |
vat | No | VAT percentage (e.g. 15). Default 15 |
vatAmount | No | VAT amount; derived when omitted |
Do not send pre-tax totals as
amount. Example: 1,000 SAR tuition → "amount": 1000, not 1,150.json
POST /api/v1/sessions
{
"amount": 1000.00,
"currency": "SAR",
"customerEmail": "student@univ.edu",
"lineItems": [
{
"skuItem": "TUITION-FALL",
"description": "رسوم دراسية — الفصل الأول",
"amount": 1000.00
}
]
}Billing API
| Endpoint | Description |
|---|---|
GET /api/v1/billing/settings | Billing settings (auto-issue, email, ERP) |
GET /api/v1/billing/templates | Invoice HTML templates |
GET /api/v1/billing/bills | List invoices |
GET /api/v1/billing/bills/{id}/pdf | Download invoice PDF |
GET /api/v1/billing/bills/export | Excel export (one row per line item) |
POST /api/v1/billing/bills/issue/{transactionId} | Manually issue invoice |
POST /api/v1/billing/bills/{id}/send | Send via email and/or ERP |
GET /api/v1/reconciliation/summary | Finance reconciliation summary |
Webhook bill fields
On payment.success, the webhook may include invoice details:
json
{
"event": "payment.success",
"transactionId": "9b2235a0-…",
"status": "SUCCESS",
"amount": 1000.00,
"currency": "SAR",
"billId": "a1b2c3d4-…",
"billNumber": "INV-2026-00042",
"totalCost": 1000.00,
"totalVat": 130.43,
"totalWithoutVat": 869.57
}Refunds
Full refunds void the linked invoice and send payment.refunded. Partial refunds send payment.partially_refunded. See Refunds & captures.