এই ভলিউমে · ভলিউম 05
অ্যাকাউন্টিং
হিসাব তালিকা জার্নাল ও লেজার বিলিং ও ইনভয়েসিং পেমেন্ট ও রসিদ পেমেন্ট রিকনসিলিয়েশন মাল্টি-কারেন্সি ডেফার্ড রেভিনিউ কমিশন অ্যাকাউন্টিং কর (VAT/GST) পিরিয়ড ক্লোজ
বাংলা সারসংক্ষেপ

ইনভয়েস হলো গ্রাহককে পাঠানো ফরমাল বিলিং নথি। ফরম্যাট: জুরিসডিকশন-নির্দিষ্ট (বাংলাদেশের NBR, ভারতের GST)। ইনভয়েস নম্বরিং: কঠোর অনুক্রমিক প্রতি বছর। স্টেট: DRAFTISSUEDPARTIALLY_PAIDPAID

Chapter 5.3 — Billing & Invoicing Lifecycle

chapter: 05-accounting/03-billing-invoicing
version: 1.0.0
status: stable
last_reviewed: 2026-05-26
owners: [accounting, product]

1. Purpose

This chapter covers customer invoicing end-to-end: how invoices are created from operational events, the document lifecycle, credit notes, dunning, and the relationship between an invoice and the underlying journal entries.

2. Why this matters in modern travel accounting

In a travel business, an invoice is not the source of the revenue record — the booking is. The invoice is the legal document presented to the customer. Confusing the two leads to common defects:

  • Two invoices for the same booking (duplicate revenue in reports).
  • An invoice issued, the customer pays, but the booking was never ticketed — the agency receivable is wrong.
  • A credit note that does not link back to the original invoice — VAT filing breaks.

travoBooks treats invoices as derivable from operational events, with explicit linkage and a controlled lifecycle.

3. Industry relevance

For B2B agencies, the invoice is the primary commercial artefact: corporate customers will not pay without one matching their PO. For B2C, the invoice doubles as a tax receipt. For sub-agent settlements, the invoice is the monthly consolidation. Each use case has different requirements; travoBooks supports all three.

4. Compliance considerations

  • Tax invoice rules vary by jurisdiction (VAT/GST regulations specify mandatory fields, numbering schemes, and time-of-issuance rules).
  • Sequential numbering is mandatory in many countries (Bangladesh, India, UAE, EU, etc.). Gaps must be explainable.
  • PDF immutability: once issued, the PDF of an invoice must be retrievable in its original form for the statutory retention period (5–10 years depending on jurisdiction).
  • IFRS 15: the invoice does not by itself recognise revenue; revenue follows the performance obligation.

5. Business logic

5.1 Invoice lifecycle

stateDiagram-v2 [*] --> Draft Draft --> Issued: Issue (assigns invoice_no, locks fields) Draft --> Cancelled: Cancel Issued --> PartiallyPaid: Partial receipt applied PartiallyPaid --> Paid: Full receipt applied Issued --> Paid: Full receipt applied Issued --> Overdue: Past due_date and not Paid Overdue --> PartiallyPaid: Partial receipt applied Overdue --> Paid: Full receipt applied Paid --> Closed: Period close Issued --> CreditNoted: Credit note issued (full) PartiallyPaid --> CreditNoted: Credit note issued Overdue --> CreditNoted: Credit note issued CreditNoted --> [*] Cancelled --> [*]

States: - Draft — editable; not visible to customer; no JE. - Issued — locked; invoice_no assigned; customer-facing; AR created via JE link to booking. - PartiallyPaid / Paid — receipts applied; tracked in invoice_allocations. - Overdue — derived state; computed from due_date and balance. - CreditNoted — fully neutralised by one or more credit notes. - Cancelled — only from Draft. - Closed — historical; locked further.

5.2 Invoice structure

Invoice
├── id, partner_id, customer_id
├── invoice_no                    (sequential, gap-free per partner+series)
├── series                        (e.g., "INV", "PI" proforma, "RCT" receipt)
├── issue_date, due_date
├── currency, fx_rate_to_functional
├── status
├── source_type                   (booking | manual | subscription | merge)
├── source_ids[]                  (one invoice can span multiple bookings)
├── billing_address, shipping_address
├── tax_summary
├── totals: subtotal, tax_total, discount_total, grand_total, paid, balance
├── notes, terms
├── pdf_url                       (signed, partner-scoped)
├── created_by, issued_by, approved_by
└── Lines[]
    ├── line_no
    ├── description
    ├── item_type             (ticket | ancillary | service_fee | hotel | other)
    ├── source_ref            (booking_id, ticket_id, etc.)
    ├── quantity
    ├── unit_price            (transaction currency)
    ├── discount_amount
    ├── tax_code
    ├── tax_amount
    ├── line_total
    ├── account_code          (revenue account this line maps to)
    ├── service_date          (for revenue recognition)
    └── passenger_name        (for travel-related lines)

5.3 Numbering

Invoice numbers follow a partner-configured pattern, with mandatory gap-free sequencing per (partner_id, series, fiscal_year). Defaults:

Series Pattern Example
INV (standard) INV/{YYYY}/{NNNNNN} INV/2026/000123
PI (proforma) PI/{YYYY}/{NNNNNN} PI/2026/000045
CN (credit note) CN/{YYYY}/{NNNNNN} CN/2026/000007
RCT (receipt) RCT/{YYYY}/{NNNNNN} RCT/2026/000089

The sequence allocator is partner-scoped row-level locking on a sequences table to guarantee no gaps under concurrency.

5.4 Tax handling on the invoice

Each line has a tax_code that resolves to a tax rate plus tax-account mapping. The system computes per-line tax, sums to a tax summary (grouped by code), and writes the appropriate output-tax payable lines into the JE.

For pass-through items (airline ticket portion that is not taxable to the agency because the ticket is the airline's supply), the invoice line displays the gross amount as a "carriage" line with taxable = false; the agency's own service fee is the taxable component.

5.5 Discounts and surcharges

  • Line-level discount: percentage or fixed; reduces taxable base.
  • Invoice-level discount: applied proportionally to lines or to specific lines.
  • Surcharge: payment-method fee (e.g., card surcharge); behaves like a line with its own tax code.

5.6 Multi-booking invoice (consolidation)

A common B2B pattern: one invoice consolidates a month's worth of bookings for a corporate client. The system supports merging draft invoices for the same customer prior to issuance.

5.7 Proforma invoices

A PI series invoice represents an expected charge; it does not affect AR. Used commonly for "send me a quote I can put on a PO". When the actual booking is finalised, the proforma is converted into a standard invoice (which then writes the AR).

5.8 Credit notes

A credit note reduces a previously-issued invoice. Use cases: refund, service failure compensation, error correction.

  • Linked to a parent invoice (or several).
  • Writes a reversing JE (full or partial of the parent).
  • Reduces AR.
  • If the customer has already paid the parent, credit note creates a customer credit balance (separate liability) usable on a future invoice, or refunded.

5.9 Dunning

A scheduled job evaluates Issued invoices against due_date. Reminders fire per the partner's dunning policy. Policies are sequences of (offset days, channel, template):

Offset Channel Default template
−3 days Email "Friendly upcoming-due reminder"
0 days Email "Due today"
+7 days Email "First past-due"
+14 days Email + SMS "Second past-due"
+21 days Email + Phone task "Account manager call required"
+30 days Email + Statement "Final notice + statement attached"

Policies are customisable per customer (large clients often want different cadences). Automatic suspension of booking privileges at a configurable threshold is supported.

6. Inputs → processing → outputs

6.1 Auto-invoice on booking issuance

When a booking is ticketed and the customer is a credit customer (B2B), a draft invoice is auto-created. Whether it is auto-issued depends on customer.invoice_policy:

Policy Effect
per_booking_auto_issue Draft is issued immediately.
per_booking_manual_issue Stays in draft until a user issues.
consolidated_weekly Accumulates into a weekly draft; issued by scheduler.
consolidated_monthly Same, monthly.
on_demand No draft until user creates one.

6.2 Manual invoice (input)

invoice:
  customer_id: "C-1023"
  series: "INV"
  issue_date: "2026-05-26"
  due_date: "2026-06-09"
  currency: "USD"
  lines:
    - description: "Hotel — Burj Al Arab, 26–28 May 2026"
      item_type: "hotel"
      source_ref: "BKG-P001-9001"
      quantity: 2
      unit_price: 1850.00
      tax_code: "VAT-5"
      account_code: "4023"
      service_date: "2026-05-26"
      passenger_name: "Mr. K. Roberts"
  notes: "Per PO #44521"

6.3 Processing on issuance

  1. Validate customer, addresses, tax setup.
  2. Lock fields.
  3. Allocate invoice_no via sequence service.
  4. Compute tax per line.
  5. Write JE: 🅓 AR / 🅒 Revenue accounts per line + 🅒 Tax Payable.
  6. Generate PDF and store in object storage; assign signed URL.
  7. Emit invoice.issued event → email to customer (if auto_send_email).
  8. Audit log.

6.4 Outputs

  • The customer receives the invoice via email (with PDF attached) and a magic link to a customer portal page where they can view, download, and (where enabled) pay.
  • AR balance updated.
  • Searchable in invoice list.

7. Module dependencies

  • Reads: customers, bookings/tickets, chart of accounts, tax profiles, FX rates, dunning policies, document templates.
  • Writes: invoices, invoice_lines, invoice_allocations, journal_entries, audit_logs, object storage, notification outbox.
  • Read by: payments, reports (AR ageing, sales by customer), dunning job, statements.

8. Security & permissions

Permission Allows
invoice.read.partner View invoices
invoice.create.own / .partner Create drafts
invoice.edit.draft Edit drafts
invoice.issue.partner Issue (allocate number, post JE)
invoice.void.draft Cancel a draft
invoice.credit_note.partner Issue credit notes
invoice.email.partner Send to customer via email
invoice.export.partner Bulk export
invoice.read_payment_details.partner See full payment allocations

Maker–checker on credit notes above threshold and on any backdated issue.

9. Validation rules

Rule Code
Customer is active INVOICE_CUSTOMER_INACTIVE
Currency enabled for partner INVOICE_CURRENCY_DISABLED
At least one line INVOICE_NO_LINES
Line unit_price > 0 (or explicit zero-rated allowed) INVOICE_LINE_PRICE_INVALID
Tax code valid for the customer's tax jurisdiction INVOICE_TAX_INVALID
due_date ≥ issue_date INVOICE_DATES_INVALID
FX rate available for the issue date INVOICE_FX_MISSING
issue_date is in an open period INVOICE_PERIOD_CLOSED
Credit note total ≤ original invoice's net of prior credit notes CN_OVERCREDIT
Invoice cannot be edited once issued INVOICE_LOCKED

10. Error handling

  • Sequence allocator collision: retry up to 3 times with row-level lock; on persistent failure, return 503 with retry hint. Will not allocate duplicates.
  • PDF generation failure: the JE is not rolled back; the invoice is issued with pdf_status = pending and the PDF generator re-tries via the job queue.
  • Customer email bounce: notification_outbox.status = bounced and a task is created for the assigned account manager.
  • Credit-note overcrediting: rejected; UI must show remaining creditable balance.

11. Real-world example

Scenario. Corporate customer Beta Corp (C-1023). Consolidated monthly invoicing. In May 2026 they had:

  • 2 May, Air, BKG-1010, sell USD 1,200, service fee USD 25, VAT 5% on service fee.
  • 14 May, Hotel, BKG-1042, sell USD 3,700 (markup model — agency owns the sale), VAT 5% on full.
  • 22 May, Air refund of BKG-0998 (issued April), refund fee USD 50 + VAT.

At end of May the consolidator job creates a draft INV/2026/000158. Lines:

# Description Account Tax Amount
1 Air — DAC–LON 02-May (BKG-1010) 4012 (carriage pass-through) n/a 1,200.00
2 Service Fee — BKG-1010 4031 VAT-5 25.00
3 Hotel — XYZ 14–18 May (BKG-1042) 4023 VAT-5 3,700.00
4 Cancellation Fee — BKG-0998 4041 VAT-5 50.00
Subtotal 4,975.00
Tax (VAT 5% on lines 2,3,4) 188.75
Total 5,163.75

JE posted:

Acct 🅓 🅒
1022 AR – Beta Corp 5,163.75
4012 Air Pass-through 1,200.00
4031 Service Fee Revenue 25.00
4023 Hotel Revenue 3,700.00
4041 Cancellation Fee Revenue 50.00
2021 VAT Output Payable 188.75

Note: the cost side (BSP payable for the air ticket; hotel net cost) was already journaled at booking issuance, not at invoicing. The invoice's job is to crystallise the customer's obligation, not to re-recognise the cost.

12. Step-by-step — issuing a draft invoice

sequenceDiagram autonumber participant U as User participant UI participant API participant Inv as Invoice Svc participant Seq as Sequence Svc participant Tax as Tax Svc participant JE as Journal Svc participant PDF as PDF Generator participant Store as Object Storage participant N as Notifications U->>UI: Open draft → "Issue" UI->>API: POST /invoices/:id/issue API->>Inv: issue(draftId) Inv->>Inv: validate(draft) Inv->>Tax: compute(lines) Inv->>Seq: nextNumber(partner, series, fy) Seq-->>Inv: "INV/2026/000158" Inv->>JE: post(invoiceIssuanceJE) JE-->>Inv: ok Inv-->>API: invoice(state=issued) API-->>UI: 200 par PDF Inv->>PDF: enqueue(invoiceId) PDF->>Store: upload PDF->>Inv: signed_url and Email Inv->>N: enqueue email N->>N: send via SES end

13. Database tables touched

  • invoices, invoice_lines, invoice_allocations
  • credit_notes, credit_note_lines, credit_note_allocations
  • sequences
  • journal_entries, journal_entry_lines
  • documents (PDF references)
  • audit_logs, notification_outbox

14. Future scalability

Need Approach
Customer self-service portal Magic-link page already; expand to full account view with statements and pay-now.
E-invoicing networks (Peppol, ZATCA, India IRP) Per-country adapters that consume the issued invoice and submit to the network; store the network UUID on the invoice.
Embedded invoicing for partners' own customer apps Render-as-component widget with HMAC-signed config; payments tunnel back to platform PSP.
Document templating per customer Customer-level overrides for header/footer/language without forking the underlying engine.

15. Common pitfalls

  • ⚠️ Editing the customer address on a draft after pricing was computed — re-run tax computation explicitly; do not rely on auto-recompute.
  • ⚠️ Issuing a credit note for an unpaid invoice without checking that the AR balance still matches. Always allocate the CN to the specific invoice.
  • ⚠️ Using a manual JE to "correct" an invoice. Don't. Use a credit note + new invoice.
  • ⚠️ Mixing currencies on a single invoice. Each invoice is one currency; if a booking spans currencies, split into multiple invoices.
  • 🔒 Sequence-allocation outside the issuance flow (e.g., reserving a number "for later"). Forbidden — would create gaps.

Next: 04-payments-receipts.md — applying customer receipts and supplier disbursements.