Core concepts
Invoice lifecycle
An invoice moves through review and approval before it reaches the customer. Your system raises it; people in Flux approve it; webhooks tell you each step.
The lifecycle#
Statuses#
| status | Meaning |
|---|---|
| awaiting_approval | Raised, and waiting for the accountant's review. |
| awaiting_final_approval | The accountant approved it; a final approver must too. |
| returned | Sent back to the raiser to fix. It goes through review again when resubmitted. |
| approved | Fully approved and emailed to the customer. Payable. |
| paid | Paid. A receipt exists. |
| voided | Cancelled before payment. Can't be paid. |
Final approval is set per organization: never, always, or above an NGN amount. A return at final approval goes back to the raiser, then through the accountant's review again.
Steps and webhooks#
| Step | Status after | Webhooks |
|---|---|---|
| Raised, through the API or in the app | awaiting_approval | invoice.created |
| Edited in the app | unchanged | invoice.updated |
| Returned by a reviewer | returned | invoice.returned |
| Resubmitted by the raiser | awaiting_approval | invoice.submitted |
| Approved by the accountant, above the final-approval threshold | awaiting_final_approval | invoice.awaiting_final_approval |
| Fully approved | approved | invoice.approved and invoice.issued |
| Paid online, or payment confirmed in the app | paid | invoice.paid and receipt.issued (online payments also send payment.succeeded) |
| Voided | voided | invoice.voided |
Webhooks can arrive out of order or more than once. When order matters, re-read the invoice. See Receiving webhooks.
When the customer hears about it#
- The invoice is emailed to the customer's billing contacts only when it becomes approved.
- Raising an invoice through the API notifies the organization's reviewers, not the customer.
- Who gets it: the primary billing contact (or the customer's
emailif there isn't one), plus every contact withccOnInvoices.
Overdue#
overdue isn't a status. It's true when the invoice is approved, unpaid, not voided and past its dueDate. Filter with GET /invoices?overdue=true.
paymentStatus#
A free-text note set by payment processing, such as successful, amount_mismatch: paid NGN 858,500.00, invoice requires NGN 860,000.00 or refunded: NGN 1,000.00. Show it to people; don't branch on it. Use status and the payment events instead.
What the API can't do#
The API can't update, approve, return or void an invoice. People with the right roles do that in the Flux app; approval is a deliberate human control. You learn about each step by webhook.