Invoice Lifecycle
Overview
The invoice flow ties together collection, customer management, payment links, and Tanzania Revenue Authority (TRA) fiscal receipts. A merchant creates an invoice, MALIPOPAY generates a shareable payment link, the customer pays via any channel, the merchant receives confirmation, and MALIPOPAY issues the TRA fiscal receipt automatically.
Sequence diagram
Key endpoints
| Step | Endpoint | Notes |
|---|---|---|
| 1 | POST /invoice | Create a draft invoice with line items, customer, tax. |
| 6 | POST /invoice/send | Dispatch the payment link to the customer. Channels: sms, whatsapp, email. |
| 8 | GET /invoice/{shortCode} | Hosted checkout page (rendered for the customer, not for the merchant). |
| 10 | POST /payment/collection | Called by the hosted checkout when the customer picks a channel and pays. |
| 14 | POST <merchant webhook> | Final invoice status push with fiscalReceipt attached. |
TRA integration
For merchants registered with TRA, MALIPOPAY automatically requests a fiscal receipt from the TRA service the moment the payment completes. The fiscal receipt arrives as part of the merchant webhook payload and also as a separate endpoint:
GET /invoice/{invoiceId}/tra/receipt
If the TRA service is unreachable (e.g. TRA downtime), the invoice is marked PAID but fiscalReceipt is null. MALIPOPAY automatically retries the TRA request every 15 minutes for up to 24 hours. The merchant can manually retrigger with:
POST /tra/retry/{invoiceId}
States
DRAFT → SENT → PAID → [FISCAL_PENDING →] FISCAL_ISSUED
↓
VOIDED
A DRAFT invoice can be edited; once SENT it's immutable. VOIDED is terminal: a voided invoice can never be paid.
Cancellation
To cancel an invoice before payment:
POST /invoice/mark-voided
{ "invoiceId": "...", "reason": "customer request" }
After payment, refunds must go through the disbursement flow. See Payment Disbursement.