Invoice Workflow
Overview
Invoice workflow manages the lifecycle of invoices from creation through payment collection. This guide covers invoice approval, sending to customers, payment tracking, overdue management, and automated reminder systems.
Table of Contents
- Invoice Approval
- Sending Invoices
- Payment Tracking
- Marking Invoices as Paid
- Canceling Invoices
- Overdue Invoice Management
- Invoice Reminders
- Invoice Aging Report
Invoice Approval
Approving an Invoice
Endpoint: POST /api/v1/sales/invoices/{invoice}/approve
Authentication: Required (Bearer token)
Purpose: Approve invoice for sending (required for high-value invoices or specific workflows)
Prerequisites:
- Invoice must be in
draftorpending_approvalstatus - User must have approval permissions
- Invoice details must be accurate and complete
Request Body:
{
"approval_notes": "Reviewed and approved for sending to customer",
"approved_by": 5
}Response (200 OK):
{
"message": "Invoice approved successfully",
"data": {
"id": 456,
"invoice_number": "INV-20251217-001",
"status": "approved",
"approved_at": "2025-12-17T13:00:00Z",
"approved_by": {
"id": 5,
"name": "Jane Manager",
"email": "jane.manager@company.com"
}
}
}Approval Triggers:
- Invoice total exceeds threshold (e.g., > $10,000)
- Custom pricing or discounts applied
- Credit terms extended
- Customer has outstanding overdue invoices
- Manual approval workflow enabled
Error Response:
{
"error": "Cannot approve invoice",
"message": "Invoice must be in draft or pending_approval status. Current status: sent"
}Sending Invoices
Send Invoice to Customer
Endpoint: POST /api/v1/sales/invoices/{invoice}/send
Authentication: Required (Bearer token)
Purpose: Send invoice to customer via email with PDF attachment
Prerequisites:
- Invoice must be in
draftorapprovedstatus - Customer must have valid email address
- Invoice must be complete and accurate
Request Body:
{
"email_to": ["billing@acme.com"],
"email_cc": ["manager@acme.com"],
"email_bcc": ["accounting@company.com"],
"subject": "Invoice INV-20251217-001 from Your Company",
"message": "Dear Customer,\n\nPlease find attached invoice INV-20251217-001 for your recent order.\n\nPayment is due within 30 days. If you have any questions, please don't hesitate to contact us.\n\nThank you for your business!",
"attach_pdf": true,
"send_copy_to_self": true
}Response (200 OK):
{
"message": "Invoice sent successfully",
"data": {
"id": 456,
"invoice_number": "INV-20251217-001",
"status": "sent",
"sent_date": "2025-12-17T14:00:00Z",
"sent_by": {
"id": 3,
"name": "John Sales",
"email": "john.sales@company.com"
},
"email_details": {
"sent_to": ["billing@acme.com"],
"sent_cc": ["manager@acme.com"],
"sent_bcc": ["accounting@company.com"],
"pdf_attached": true,
"delivery_status": "sent"
}
}
}What Happens When Sending:
- Invoice status changes to
sent sent_datetimestamp recorded- PDF invoice generated automatically
- Email sent with PDF attachment
- Customer portal link included (if enabled)
- Invoice appears in accounts receivable
- Due date tracking begins
Generate PDF Without Sending
Endpoint: GET /api/v1/sales/invoices/{invoice}/pdf
Authentication: Required (Bearer token)
Response: Binary PDF file download
Use Case: Preview invoice before sending, save for records, manual delivery
Customizing Email Template
{
"email_to": ["billing@acme.com"],
"subject": "[Action Required] Invoice {{invoice_number}} - Due {{due_date}}",
"message": "Hello {{customer_name}},\n\nInvoice {{invoice_number}} for {{total_amount}} is now available.\n\nPayment Terms: {{payment_terms}}\nDue Date: {{due_date}}\n\nView online: {{portal_link}}\n\nThank you!",
"template_variables": {
"custom_field_1": "Value 1",
"custom_field_2": "Value 2"
}
}Available Variables:
- Custom variables from request
Payment Tracking
Applying Payment to Invoice
Endpoint: POST /api/v1/sales/invoices/{invoice}/apply-payment
Authentication: Required (Bearer token)
Purpose: Record payment received against invoice
Request Body (Full Payment):
{
"payment_id": 789,
"amount": 347.47,
"payment_date": "2025-12-18",
"payment_method": "bank_transfer",
"reference_number": "WIRE-123456",
"notes": "Payment received via wire transfer"
}Response (200 OK):
{
"message": "Payment applied successfully",
"data": {
"id": 456,
"invoice_number": "INV-20251217-001",
"status": "paid",
"total_amount": 347.47,
"amount_paid": 347.47,
"amount_due": 0.00,
"paid_date": "2025-12-18T10:00:00Z",
"payment": {
"id": 789,
"payment_number": "PAY-12345678",
"amount": 347.47,
"method": "bank_transfer"
}
}
}Partial Payment
Request Body:
{
"amount": 100.00,
"payment_date": "2025-12-18",
"payment_method": "credit_card",
"notes": "Partial payment - balance to follow"
}Response:
{
"data": {
"id": 456,
"invoice_number": "INV-20251217-001",
"status": "partially_paid",
"total_amount": 347.47,
"amount_paid": 100.00,
"amount_due": 247.47,
"payment_percentage": 28.77
}
}Viewing Invoice Payments
Endpoint: GET /api/v1/sales/invoices/{invoice}/payments
Authentication: Required (Bearer token)
Response (200 OK):
{
"data": [
{
"id": 789,
"payment_number": "PAY-12345678",
"status": "completed",
"amount": 100.00,
"method": "credit_card",
"payment_date": "2025-12-18T10:00:00Z",
"transaction_id": "TXN-987654"
},
{
"id": 790,
"payment_number": "PAY-12345679",
"status": "completed",
"amount": 247.47,
"method": "bank_transfer",
"payment_date": "2025-12-22T14:30:00Z",
"transaction_id": "WIRE-789456"
}
],
"meta": {
"total_payments": 2,
"total_paid": 347.47,
"payment_complete": true
}
}Marking Invoices as Paid
Mark as Paid Manually
Endpoint: POST /api/v1/sales/invoices/{invoice}/mark-paid
Authentication: Required (Bearer token)
Purpose: Manually mark invoice as paid (when payment received outside system)
Request Body:
{
"paid_date": "2025-12-18",
"payment_method": "check",
"reference_number": "CHECK-789456",
"notes": "Payment received via check - deposited 12/18/2025"
}Response (200 OK):
{
"message": "Invoice marked as paid successfully",
"data": {
"id": 456,
"invoice_number": "INV-20251217-001",
"status": "paid",
"total_amount": 347.47,
"amount_paid": 347.47,
"amount_due": 0.00,
"paid_date": "2025-12-18T00:00:00Z"
}
}Use Cases:
- Cash payments
- Check payments
- Wire transfers verified via bank statement
- Third-party payment processors
- Payments received before invoice sent
Canceling Invoices
Cancel Invoice
Endpoint: POST /api/v1/sales/invoices/{invoice}/cancel
Authentication: Required (Bearer token)
Purpose: Cancel invoice (void for non-payment, corrections, or errors)
Prerequisites:
- Invoice must NOT be paid
- Invoice can be in any status except
paid - Cancellation reason required for audit trail
Request Body:
{
"cancellation_reason": "Invoice issued in error - duplicate billing",
"notify_customer": true,
"refund_payments": false
}Response (200 OK):
{
"message": "Invoice cancelled successfully",
"data": {
"id": 456,
"invoice_number": "INV-20251217-001",
"status": "cancelled",
"cancelled_at": "2025-12-17T16:00:00Z",
"cancellation_reason": "Invoice issued in error - duplicate billing",
"customer_notified": true
}
}What Happens on Cancellation:
- Invoice status changes to
cancelled cancelled_attimestamp and reason recorded- Removed from accounts receivable
- Customer notified if requested
- Partial payments refunded if specified
- Cannot be reactivated (create new invoice instead)
Cancel with Refund
For invoices with partial payments:
{
"cancellation_reason": "Order cancelled - product unavailable",
"notify_customer": true,
"refund_payments": true,
"refund_method": "original_payment_method"
}Response includes:
{
"data": {
"status": "cancelled",
"refund_initiated": true,
"refund_amount": 100.00,
"refund_status": "processing"
}
}Overdue Invoice Management
Get Overdue Invoices
Endpoint: GET /api/v1/sales/invoices/overdue
Authentication: Required (Bearer token)
Purpose: List all invoices past due date without full payment
Query Parameters:
days_overdue(integer) - Minimum days overdue (default: 1)customer_id(integer) - Filter by customermin_amount(number) - Minimum invoice amountsort_by(string) - Sort field (due_date, days_overdue, amount_due)sort_direction(string) - Sort direction (asc, desc)
Response (200 OK):
{
"data": [
{
"id": 458,
"invoice_number": "INV-20251115-003",
"status": "overdue",
"customer": {
"id": 45,
"customer_number": "CUST-00045",
"company_name": "Late Payer Inc"
},
"total_amount": 1250.00,
"amount_paid": 0.00,
"amount_due": 1250.00,
"issue_date": "2025-11-15",
"due_date": "2025-12-15",
"days_overdue": 2,
"late_fee_amount": 25.00
},
{
"id": 459,
"invoice_number": "INV-20251110-004",
"status": "overdue",
"customer": {
"id": 46,
"customer_number": "CUST-00046",
"company_name": "Slow Pay LLC"
},
"total_amount": 875.50,
"amount_paid": 200.00,
"amount_due": 675.50,
"issue_date": "2025-11-10",
"due_date": "2025-12-10",
"days_overdue": 7,
"late_fee_amount": 33.78
}
],
"meta": {
"total_overdue": 2,
"total_overdue_amount": 1925.50,
"average_days_overdue": 4.5
}
}Automatic Overdue Detection
The system automatically:
- Checks invoice due dates daily
- Updates status to
overduewhen due_date passes - Sets
overdue_datetimestamp - Applies late fees if configured
- Triggers reminder workflows
Invoice Reminders
Send Payment Reminders
Endpoint: POST /api/v1/sales/invoices/send-reminders
Authentication: Required (Bearer token)
Purpose: Send automated payment reminders for overdue or due-soon invoices
Request Body:
{
"reminder_type": "overdue",
"days_overdue_min": 1,
"days_overdue_max": 30,
"exclude_customers": [45],
"email_template": "overdue_payment_reminder",
"dry_run": false
}Reminder Types:
due_soon- Invoices due within N daysdue_today- Invoices due todayoverdue- Invoices past due dateseriously_overdue- Invoices 30+ days overdue
Response (200 OK):
{
"message": "Payment reminders sent successfully",
"data": {
"reminder_type": "overdue",
"invoices_processed": 15,
"reminders_sent": 12,
"reminders_failed": 3,
"results": [
{
"invoice_id": 458,
"invoice_number": "INV-20251115-003",
"customer_email": "billing@latepayer.com",
"status": "sent",
"sent_at": "2025-12-17T17:00:00Z"
},
{
"invoice_id": 459,
"invoice_number": "INV-20251110-004",
"customer_email": "ap@slowpay.com",
"status": "sent",
"sent_at": "2025-12-17T17:00:01Z"
}
]
}
}Reminder Schedule
Typical reminder schedule:
- 7 days before due: Friendly reminder
- Due date: Payment due today notice
- 3 days overdue: First overdue notice
- 7 days overdue: Second overdue notice
- 14 days overdue: Final notice
- 30 days overdue: Collection warning
Custom Reminder Template
{
"reminder_type": "overdue",
"email_subject": "URGENT: Invoice {{invoice_number}} is {{days_overdue}} days overdue",
"email_message": "Dear {{customer_name}},\n\nInvoice {{invoice_number}} for {{total_amount}} is now {{days_overdue}} days overdue.\n\nOriginal Due Date: {{due_date}}\nAmount Due: {{amount_due}}\n\nPlease remit payment immediately to avoid late fees and collection action.\n\nLate Fee: {{late_fee_amount}}\nTotal Now Due: {{total_with_late_fee}}\n\nThank you.",
"days_overdue_min": 7
}Invoice Aging Report
Get Aging Report
Endpoint: GET /api/v1/sales/invoices/aging-report
Authentication: Required (Bearer token)
Purpose: View accounts receivable aging analysis
Query Parameters:
as_of_date(date) - Report date (default: today)customer_id(integer) - Filter by customerinclude_paid(boolean) - Include paid invoices (default: false)
Response (200 OK):
{
"data": {
"report_date": "2025-12-17",
"aging_buckets": {
"current": {
"label": "Current (Not Due)",
"count": 45,
"total_amount": 125678.90
},
"1_30_days": {
"label": "1-30 Days Overdue",
"count": 12,
"total_amount": 34567.89
},
"31_60_days": {
"label": "31-60 Days Overdue",
"count": 5,
"total_amount": 12345.67
},
"61_90_days": {
"label": "61-90 Days Overdue",
"count": 2,
"total_amount": 5678.90
},
"over_90_days": {
"label": "Over 90 Days",
"count": 1,
"total_amount": 3456.78
}
},
"summary": {
"total_invoices": 65,
"total_outstanding": 181728.14,
"overdue_percentage": 30.8,
"average_days_to_pay": 25.3
},
"by_customer": [
{
"customer_id": 42,
"customer_name": "Acme Corporation",
"current": 15000.00,
"1_30_days": 5000.00,
"31_60_days": 0.00,
"61_90_days": 0.00,
"over_90_days": 0.00,
"total_outstanding": 20000.00
}
]
}
}Exporting Aging Report
Endpoint: GET /api/v1/sales/invoices/aging-report?format=csv
Response: CSV file download with aging details
Invoice Statistics
Get Invoice Statistics
Endpoint: GET /api/v1/sales/invoices/statistics
Authentication: Required (Bearer token)
Query Parameters:
from_date(date) - Start dateto_date(date) - End datecustomer_id(integer) - Filter by customer
Response (200 OK):
{
"data": {
"period": {
"from": "2025-12-01",
"to": "2025-12-31"
},
"invoice_counts": {
"total": 125,
"draft": 8,
"sent": 35,
"partially_paid": 12,
"paid": 65,
"overdue": 4,
"cancelled": 1
},
"financial_metrics": {
"total_invoiced": 456789.12,
"total_paid": 398765.43,
"total_outstanding": 58023.69,
"average_invoice_value": 3654.31,
"collection_rate": 87.29
},
"payment_metrics": {
"average_days_to_pay": 18.5,
"on_time_payment_rate": 82.5,
"late_payment_rate": 17.5,
"total_late_fees": 1234.56
},
"top_customers_by_revenue": [
{
"customer_id": 42,
"customer_name": "Acme Corporation",
"invoice_count": 15,
"total_invoiced": 125678.90,
"total_paid": 125678.90,
"payment_performance": "excellent"
}
]
}
}Invoice Activities
View Invoice Activity History
Endpoint: GET /api/v1/sales/invoices/{invoice}/activities
Authentication: Required (Bearer token)
Response (200 OK):
{
"data": [
{
"id": 1234,
"type": "invoice_paid",
"description": "Invoice paid in full",
"user": {
"id": null,
"name": "System"
},
"metadata": {
"payment_id": 789,
"payment_method": "bank_transfer",
"amount": 347.47
},
"created_at": "2025-12-18T10:00:00Z"
},
{
"id": 1233,
"type": "invoice_sent",
"description": "Invoice sent to customer",
"user": {
"id": 3,
"name": "John Sales"
},
"metadata": {
"sent_to": ["billing@acme.com"],
"pdf_attached": true
},
"created_at": "2025-12-17T14:00:00Z"
},
{
"id": 1232,
"type": "invoice_created",
"description": "Invoice created from order ORD-A3X7K9M2",
"user": {
"id": 5,
"name": "Jane Manager"
},
"metadata": {
"order_id": 123,
"total_amount": 347.47
},
"created_at": "2025-12-17T11:30:00Z"
}
]
}Best Practices
Approve Before Sending: Review invoices for accuracy before sending to customers
Send Promptly: Send invoices immediately after service delivery or product shipment
Use Clear Payment Terms: Specify payment methods, due dates, and late fee policies
Track Partial Payments: Record all payments promptly to maintain accurate balances
Follow Up on Overdue: Send reminders at 3, 7, and 14 days overdue
Document Cancellations: Always provide detailed reasons for cancelled invoices
Monitor Aging Report: Review weekly to identify collection issues early
Automate Reminders: Set up automatic reminder schedules to reduce manual work
Related Guides
- Invoice Generation - Creating invoices
- Payment Processing - Processing invoice payments
- Order-to-Cash Workflow - Complete sales process
- Sales Analytics - Financial reporting