Skip to content

Invoice Generation

Overview

Invoices in SynthesQ represent formal requests for payment from customers. They can be generated automatically from sales orders or created manually for standalone billing. This guide covers invoice creation, structure, validation, and the various methods of generating invoices.

Table of Contents

Invoice Structure

Core Invoice Fields

Invoice Identity:

  • invoice_number - Unique identifier (e.g., "INV-20251217-001")
  • id - Internal database ID
  • type - Invoice type (standard, proforma, credit_note, debit_note)
  • reference_number - External reference (optional)
  • purchase_order_number - Customer's PO number (optional)

Relationships:

  • customer_id - Reference to customer record (required)
  • order_id - Reference to source order (if applicable)

Financial Details:

  • subtotal_amount - Sum of all line items before taxes/fees
  • tax_amount - Total tax charged
  • discount_amount - Total discounts applied
  • shipping_amount - Shipping charges (if applicable)
  • total_amount - Final invoice total (auto-calculated)
  • amount_paid - Amount paid so far
  • amount_due - Remaining balance (auto-calculated)
  • currency - Currency code (default: USD)

Dates:

  • issue_date - Date invoice was issued
  • due_date - Payment due date
  • sent_date - When invoice was sent to customer
  • paid_date - When invoice was paid in full
  • overdue_date - When invoice became overdue

Payment Terms:

  • payment_terms - Payment terms and conditions
  • late_fee_rate - Late fee percentage (if applicable)
  • late_fee_amount - Calculated late fee amount

Status Tracking:

  • status - Current invoice status
  • approved_by - User who approved invoice
  • approved_at - When invoice was approved
  • sent_by - User who sent invoice
  • cancelled_at - When invoice was cancelled (if applicable)
  • cancellation_reason - Reason for cancellation

Addresses:

  • billing_address - Customer billing address
  • shipping_address - Delivery address (if different)

Additional Fields:

  • line_items - Invoice line items (deprecated - use relationship)
  • tax_breakdown - Detailed tax calculations
  • discount_details - Discount details and codes
  • notes - Internal notes
  • custom_fields - Extensible JSON field
  • tags - Array of tags

Invoice Status Lifecycle

Invoices progress through these statuses:

Draft:

  • Initial state when created
  • Can be freely edited
  • Not visible to customer
  • Not included in accounts receivable

Pending Approval:

  • Awaiting manager/admin approval
  • Cannot be sent until approved
  • May be required for high-value invoices

Approved:

  • Approved for sending
  • Ready to be sent to customer
  • Included in accounts receivable

Sent:

  • Delivered to customer
  • Payment is expected
  • Included in aging reports

Partially Paid:

  • Some payment received
  • Balance still outstanding
  • May require follow-up

Paid:

  • Paid in full
  • No balance remaining
  • Closed for payment purposes

Overdue:

  • Past due date without payment
  • Late fees may apply
  • Requires collection action

Cancelled:

  • Invoice voided
  • Not payable
  • Reason documented

Generating from Orders

Automatic Invoice Generation

Endpoint: POST /api/v1/sales/orders/{order}/generate-invoice

Authentication: Required (Bearer token)

Purpose: Create invoice automatically from existing order

Prerequisites:

  • Order must exist and be confirmed or later status
  • Order must have customer assigned
  • Order must not already have an invoice (unless creating supplemental)

Request Body (optional parameters):

json
{
  "issue_date": "2025-12-17",
  "due_date": "2026-01-16",
  "payment_terms": {
    "terms": "Net 30",
    "due_days": 30,
    "method": "bank_transfer"
  },
  "include_shipping": true,
  "notes": "Payment due within 30 days. Thank you for your business!",
  "auto_send": false
}

Response (201 Created):

json
{
  "message": "Invoice generated successfully from order",
  "data": {
    "id": 456,
    "invoice_number": "INV-20251217-001",
    "type": "standard",
    "status": "draft",
    "customer": {
      "id": 42,
      "customer_number": "CUST-00042",
      "company_name": "Acme Corporation",
      "email": "billing@acme.com"
    },
    "order": {
      "id": 123,
      "order_number": "ORD-A3X7K9M2"
    },
    "issue_date": "2025-12-17",
    "due_date": "2026-01-16",
    "subtotal_amount": 349.97,
    "tax_amount": 12.50,
    "shipping_amount": 0.00,
    "discount_amount": 15.00,
    "total_amount": 347.47,
    "amount_paid": 0.00,
    "amount_due": 347.47,
    "currency": "USD",
    "items": [
      {
        "id": 789,
        "product_id": 101,
        "sku": "WIDGET-001",
        "name": "Premium Widget",
        "description": "High-quality widget",
        "quantity": 2,
        "unit_price": 99.99,
        "tax_amount": 5.00,
        "discount_amount": 0.00,
        "line_total": 204.98
      },
      {
        "id": 790,
        "product_id": 102,
        "sku": "GADGET-002",
        "name": "Smart Gadget",
        "description": "Advanced smart gadget",
        "quantity": 1,
        "unit_price": 149.99,
        "tax_amount": 7.50,
        "discount_amount": 15.00,
        "line_total": 142.49
      }
    ],
    "billing_address": {
      "street": "123 Main St",
      "city": "San Francisco",
      "state": "CA",
      "postal_code": "94105",
      "country": "US"
    },
    "payment_terms": {
      "terms": "Net 30",
      "due_days": 30,
      "method": "bank_transfer"
    },
    "created_at": "2025-12-17T11:30:00Z",
    "updated_at": "2025-12-17T11:30:00Z"
  }
}

What Gets Copied from Order:

  • Customer information
  • Billing and shipping addresses
  • All order line items (products, quantities, prices)
  • Tax calculations
  • Discount amounts
  • Shipping charges (if include_shipping: true)
  • Currency
  • Custom fields (if configured)

Auto-Generated Fields:

  • invoice_number - Sequential or date-based
  • issue_date - Current date (or provided)
  • due_date - Calculated based on payment terms
  • total_amount - Calculated from line items
  • amount_due - Initially equals total_amount

Generate with Custom Due Date

json
POST /api/v1/sales/orders/{order}/generate-invoice
{
  "due_date": "2025-12-31",
  "payment_terms": {
    "terms": "Due on receipt",
    "due_days": 0
  },
  "notes": "Urgent payment required by year end"
}

Generate and Send Immediately

json
POST /api/v1/sales/orders/{order}/generate-invoice
{
  "auto_send": true,
  "email_to": "billing@acme.com",
  "email_cc": ["manager@acme.com"],
  "email_message": "Please find attached invoice for your recent order. Payment terms: Net 30."
}

Response includes:

json
{
  "status": "sent",
  "sent_date": "2025-12-17T11:30:00Z",
  "email_sent_to": ["billing@acme.com"],
  "email_sent_cc": ["manager@acme.com"]
}

Error Responses

Order Already Has Invoice:

json
{
  "error": "Invoice already exists",
  "message": "Order ORD-A3X7K9M2 already has an invoice associated with it",
  "existing_invoice": {
    "id": 456,
    "invoice_number": "INV-20251217-001",
    "status": "sent"
  }
}

Order Not Ready:

json
{
  "error": "Order not ready for invoicing",
  "message": "Order must be in confirmed or later status. Current status: draft",
  "current_status": "draft"
}

Manual Invoice Creation

Creating Standalone Invoices

Endpoint: POST /api/v1/sales/invoices

Authentication: Required (Bearer token)

Purpose: Create invoice manually without an order (for services, subscriptions, or custom billing)

Request Body:

json
{
  "customer_id": 42,
  "type": "standard",
  "issue_date": "2025-12-17",
  "due_date": "2026-01-16",
  "reference_number": "PO-CUST-12345",
  "currency": "USD",
  "billing_address": {
    "street": "123 Main St",
    "city": "San Francisco",
    "state": "CA",
    "postal_code": "94105",
    "country": "US"
  },
  "payment_terms": {
    "terms": "Net 30",
    "due_days": 30,
    "method": "bank_transfer"
  },
  "items": [
    {
      "name": "Consulting Services",
      "description": "Q4 2025 Business Consulting - 40 hours",
      "quantity": 40,
      "unit_price": 150.00,
      "tax_rate": 8.5,
      "tax_amount": 510.00
    },
    {
      "name": "Monthly Subscription",
      "description": "Premium Plan - December 2025",
      "quantity": 1,
      "unit_price": 299.00,
      "tax_rate": 8.5,
      "tax_amount": 25.42
    }
  ],
  "notes": "Payment due within 30 days. Wire transfer details provided separately."
}

Response (201 Created):

json
{
  "message": "Invoice created successfully",
  "data": {
    "id": 457,
    "invoice_number": "INV-20251217-002",
    "type": "standard",
    "status": "draft",
    "customer": {
      "id": 42,
      "customer_number": "CUST-00042",
      "company_name": "Acme Corporation",
      "email": "billing@acme.com"
    },
    "order_id": null,
    "reference_number": "PO-CUST-12345",
    "issue_date": "2025-12-17",
    "due_date": "2026-01-16",
    "subtotal_amount": 6299.00,
    "tax_amount": 535.42,
    "shipping_amount": 0.00,
    "discount_amount": 0.00,
    "total_amount": 6834.42,
    "amount_paid": 0.00,
    "amount_due": 6834.42,
    "currency": "USD",
    "items": [
      {
        "id": 791,
        "product_id": null,
        "name": "Consulting Services",
        "description": "Q4 2025 Business Consulting - 40 hours",
        "quantity": 40,
        "unit_price": 150.00,
        "tax_rate": 8.5,
        "tax_amount": 510.00,
        "discount_amount": 0.00,
        "line_total": 6510.00
      },
      {
        "id": 792,
        "product_id": null,
        "name": "Monthly Subscription",
        "description": "Premium Plan - December 2025",
        "quantity": 1,
        "unit_price": 299.00,
        "tax_rate": 8.5,
        "tax_amount": 25.42,
        "discount_amount": 0.00,
        "line_total": 324.42
      }
    ],
    "created_at": "2025-12-17T12:00:00Z",
    "updated_at": "2025-12-17T12:00:00Z"
  }
}

Invoice Line Items

Line Item Structure

Each invoice line item contains:

json
{
  "name": "Product/Service Name",
  "description": "Detailed description",
  "sku": "PROD-SKU-001",
  "product_id": 101,
  "quantity": 5,
  "unit_price": 99.99,
  "tax_rate": 8.5,
  "tax_amount": 42.50,
  "discount_amount": 10.00,
  "line_total": 532.45
}

Required Fields:

  • name - Product/service name
  • quantity - Quantity (must be positive)
  • unit_price - Price per unit

Optional Fields:

  • description - Additional details
  • sku - Stock keeping unit
  • product_id - Reference to product catalog
  • tax_rate - Tax percentage
  • tax_amount - Calculated tax
  • discount_amount - Line item discount

Calculated Fields:

  • line_total = (unit_price × quantity) + tax_amount - discount_amount

Adding Line Items to Existing Invoice

Endpoint: PUT /api/v1/sales/invoices/{invoice}

Request Body:

json
{
  "items": [
    {
      "name": "Additional Service",
      "description": "Extra hours consulting",
      "quantity": 5,
      "unit_price": 150.00,
      "tax_amount": 63.75
    }
  ]
}

Note: This replaces all items. To add items, include existing items in the array.

Tax and Discount Handling

Automatic Tax Calculation

When creating invoices, taxes can be calculated automatically:

Line Item Tax:

json
{
  "items": [
    {
      "name": "Product",
      "quantity": 1,
      "unit_price": 100.00,
      "tax_rate": 8.5
    }
  ]
}

System calculates:

  • tax_amount = 100.00 × 0.085 = 8.50
  • line_total = 100.00 + 8.50 = 108.50

Order-Level Discounts

Percentage Discount:

json
{
  "subtotal_amount": 1000.00,
  "discount_details": {
    "type": "percentage",
    "value": 10,
    "code": "SAVE10"
  },
  "discount_amount": 100.00
}

Fixed Amount Discount:

json
{
  "subtotal_amount": 1000.00,
  "discount_details": {
    "type": "fixed",
    "value": 50.00,
    "reason": "Valued customer discount"
  },
  "discount_amount": 50.00
}

Tax Breakdown

For complex tax scenarios (multiple jurisdictions):

json
{
  "tax_breakdown": [
    {
      "jurisdiction": "State",
      "rate": 6.5,
      "amount": 65.00
    },
    {
      "jurisdiction": "County",
      "rate": 1.5,
      "amount": 15.00
    },
    {
      "jurisdiction": "City",
      "rate": 0.5,
      "amount": 5.00
    }
  ],
  "tax_amount": 85.00
}

Invoice Numbering

Automatic Numbering

The system automatically generates invoice numbers using configurable formats:

Sequential Format:

  • Pattern: INV-{sequence}
  • Example: INV-00001, INV-00002, INV-00003

Date-Based Format:

  • Pattern: INV-{YYYYMMDD}-{sequence}
  • Example: INV-20251217-001, INV-20251217-002

Custom Prefix:

  • Pattern: {prefix}-{YYYYMMDD}-{sequence}
  • Example: INVOICE-20251217-001, BILL-20251217-001

Manual Override

You can override automatic numbering:

json
{
  "invoice_number": "CUSTOM-INV-12345",
  "customer_id": 42,
  "items": [...]
}

Warning: Manual numbering bypasses uniqueness checks. Ensure numbers don't conflict.

Invoice Validation

Automatic Validations

The system validates invoices during creation:

Required Fields:

  • customer_id - Must reference valid customer
  • items - At least one line item required
  • Each item must have: name, quantity, unit_price

Business Rules:

  • quantity must be positive
  • unit_price must be non-negative
  • due_date must be after issue_date
  • total_amount must match calculated sum
  • amount_due = total_amount - amount_paid

Data Integrity:

  • Customer must exist
  • Product IDs must reference valid products (if provided)
  • Currency must be valid ISO code
  • Dates must be valid format (YYYY-MM-DD)

Business Scenarios

Scenario 1: Post-Delivery Invoicing

Workflow:

  1. Order fulfilled and delivered
  2. Generate invoice: POST /api/v1/sales/orders/{order}/generate-invoice
  3. Invoice created in draft status
  4. Review and approve invoice
  5. Send to customer: POST /api/v1/sales/invoices/{invoice}/send
  6. Track payment: Monitor invoice status

Use Case: Standard B2B sales where payment follows delivery

Scenario 2: Proforma Invoice

Create proforma invoice (before shipment):

json
POST /api/v1/sales/invoices
{
  "type": "proforma",
  "customer_id": 42,
  "issue_date": "2025-12-17",
  "due_date": "2025-12-24",
  "items": [...],
  "notes": "Proforma invoice for advance payment. Final invoice to follow upon shipment."
}

Use Case: International orders requiring advance payment or customs documentation

Scenario 3: Subscription Billing

Monthly recurring invoice:

json
POST /api/v1/sales/invoices
{
  "customer_id": 42,
  "type": "standard",
  "reference_number": "SUB-2025-12",
  "issue_date": "2025-12-01",
  "due_date": "2025-12-10",
  "items": [
    {
      "name": "Premium Subscription",
      "description": "Monthly subscription - December 2025",
      "quantity": 1,
      "unit_price": 299.00,
      "tax_amount": 25.42
    }
  ],
  "payment_terms": {
    "terms": "Due within 10 days",
    "due_days": 10,
    "method": "auto_charge"
  }
}

Use Case: SaaS or subscription-based billing

Scenario 4: Consolidated Billing

Monthly consolidated invoice for multiple orders:

json
POST /api/v1/sales/invoices
{
  "customer_id": 42,
  "reference_number": "CONSOLIDATED-DEC-2025",
  "issue_date": "2025-12-31",
  "due_date": "2026-01-30",
  "items": [
    {
      "name": "Order ORD-001 - Widgets",
      "description": "December 5, 2025",
      "quantity": 10,
      "unit_price": 99.99,
      "tax_amount": 85.00
    },
    {
      "name": "Order ORD-002 - Gadgets",
      "description": "December 12, 2025",
      "quantity": 5,
      "unit_price": 149.99,
      "tax_amount": 63.75
    },
    {
      "name": "Order ORD-003 - Services",
      "description": "December 20, 2025",
      "quantity": 8,
      "unit_price": 150.00,
      "tax_amount": 102.00
    }
  ],
  "notes": "Consolidated invoice for all December 2025 orders. Payment terms: Net 30."
}

Use Case: Enterprise customers with monthly billing cycles

Scenario 5: Credit Note

Issue credit note for returns/refunds:

json
POST /api/v1/sales/invoices
{
  "type": "credit_note",
  "customer_id": 42,
  "reference_number": "RMA-12345",
  "issue_date": "2025-12-20",
  "items": [
    {
      "name": "Premium Widget (Returned)",
      "description": "Product returned - defective",
      "quantity": -2,
      "unit_price": 99.99,
      "tax_amount": -17.00
    }
  ],
  "notes": "Credit note for returned items under RMA-12345"
}

Use Case: Product returns, refunds, or billing adjustments

Integration Points

With Orders Module

  • Invoices generated automatically from completed orders
  • Order status tracked with invoice creation
  • Invoice references source order for audit trail

With Payments Module

  • Invoice balance updated when payments received
  • Payment status reflects invoice amounts
  • Multiple payments can be applied to single invoice

With Finance Module

  • Invoices create accounts receivable entries
  • Revenue recognized based on invoice status
  • Aging reports generated from invoice due dates
  • Tax reporting based on invoice tax breakdowns

Best Practices

  1. Generate Invoices Promptly: Create invoices immediately after order fulfillment to minimize payment delays

  2. Use Clear Line Item Descriptions: Provide detailed descriptions so customers understand charges

  3. Set Appropriate Due Dates: Consider payment terms, customer creditworthiness, and industry standards

  4. Include Purchase Order Numbers: Reference customer PO numbers to facilitate their accounts payable process

  5. Review Before Sending: Always review draft invoices for accuracy before sending to customers

  6. Leverage Invoice Types: Use proforma, credit notes, and debit notes appropriately for different scenarios

  7. Maintain Consistent Numbering: Use automatic numbering to ensure sequential, unique invoice numbers

  8. Document Tax Calculations: Include detailed tax breakdowns for transparency and compliance

Documentation for SynthesQ CRM/ERP Platform