The invoice module produces and tracks invoices — both auto-generated from orders and manually created for B2B billing, services, and project work. Each invoice has a PDF, a payment link, a status timeline, and an audit trail. Invoices are how the platform handles "I owe you money, here's how to pay" outside the cart-and-checkout flow.
Save and read
/storefront/invoices/saveJWT/storefront/invoicesJWT/storefront/invoices/:idJWT/storefront/invoices/dashboard/metricsJWTsave creates or updates an invoice (upsert by ID). The body specifies line items, customer, dates, terms:
{
"customerId": "cust-acme",
"merchantCustomerId": "mc-acme",
"issueDate": "2026-04-25",
"dueDate": "2026-05-25",
"currency": "USD",
"terms": "NET-30",
"lineItems": [
{ "description": "April consulting", "quantity": 40, "rate": 175, "amount": 7000 },
{ "description": "Cloud hosting", "quantity": 1, "rate": 295, "amount": 295 }
],
"subtotal": 7295,
"tax": 583.60,
"total": 7878.60,
"notes": "Thank you for your business."
}
The platform assigns an invoice number on save (sequential per org, per the configured pattern). The dashboard metrics endpoint returns outstanding receivables, average days-to-pay, top late accounts.
Send and reminders
/storefront/invoices/:id/sendJWT/storefront/invoices/:id/reminderJWTsend emails the invoice to the customer with the PDF attached and a payment link. reminder sends a follow-up. Both go through the Broadcast module so delivery tracking, opens, and clicks are recorded.
Payment
/storefront/invoices/pay/:idNo auth/storefront/invoices/pay/:idNo auth/storefront/invoices/:id/amount-dueJWTPublic payment endpoints. The pay/:id GET returns the public-safe invoice (line items, total, payment options) — what a customer sees when clicking the payment link in their email. The POST takes a Stripe/PayPal payment intent confirmation and marks the invoice paid.
// Customer-facing payment page
const inv = await fetch(`/api/storefront/invoices/pay/${invoiceId}`, {
headers: { orgid: ORG_ID },
}).then(r => r.json());
// After Stripe payment
await fetch(`/api/storefront/invoices/pay/${invoiceId}`, {
method: 'POST',
headers: { 'Content-Type': 'application/json', orgid: ORG_ID },
body: JSON.stringify({
paymentIntentId: 'pi_xyz',
amount: inv.total,
}),
});
Status transitions
/storefront/invoices/:id/mark-paidJWT/storefront/invoices/:id/mark-overdueJWT/storefront/invoices/:id/cancelJWT/storefront/invoices/:id/reopenJWT/storefront/invoices/:id/refundJWT/storefront/invoices/:id/duplicateJWTThe status machine: draft → sent → viewed → (partially-paid) → paid (with overdue and cancelled as side states). mark-paid is for offline payments (cheque, ACH outside the platform). mark-overdue is usually triggered by a scheduled job rather than called by hand. refund reverses a payment via the original payment method. duplicate is a quick way to create a recurring invoice — copy, edit dates, save.
PDF and rendering
The PDF is generated server-side from a configurable template (logo, layout, terms text). Org-management exposes the template editor; invoices read the latest template at PDF render time, so updating the template re-styles future invoices without touching past ones.
The PDF URL is on the invoice record under data.pdfUrl. It's a signed URL valid for the org's default expiry (configurable, default 30 days). Re-fetching the invoice generates a fresh URL.
Recurring invoices
For predictable monthly billing, two paths:
- Subscription via storefront — see Subscriptions and rentals. Stripe handles the recurrence, invoices are auto-generated.
- Manual recurring — duplicate the invoice on a schedule via the Automation module. Use this for hand-curated B2B invoicing where line items change each month.
Merchant-customer integration
When a B2B merchant account is on NET-30 terms (see Merchant customer), placed orders don't get charged immediately. Instead the merchant's monthly billing job calls POST /crm/merchant-customers/invoices/generate/:id, which rolls unbilled orders into a single invoice via this module. The merchant then pays the invoice through the public payment endpoint.
For US tax compliance with services or hybrid invoices, plug a tax provider into the shipping and tax module. Invoice tax calculation uses the same engine.