Skip to content

Invoice Fundamentals

An Invoice is the core entity in the PEPPOL invoicing system. It can be a debit invoice or a credit note. It represents a standardized electronic invoice document that contains all the necessary information for a commercial transaction between a seller and a buyer.

Each invoice includes:

  • Party Information: Seller and buyer details (name, tax identification number, country)
  • Tax Representatives: Optional tax representative details for the seller
  • Document References: Invoice number, issue date, invoice type, and optional references (buyer reference, project reference, contract reference, billing reference)
  • Financial Totals: All monetary amounts including net amount, taxes, allowances, charges, and the final payable amount
  • Line Items: The individual products or services being invoiced (tracked by lines_count)
  • Contract details: Contract information related to the invoice
  • Currency: The transaction currency (ISO 4217 code)
  • Status Tracking: Lock status and response codes for invoice lifecycle management

How Invoices Work

Each invoice has a unique ULID id (Universally Unique Lexicographically Sortable Identifier) for secure, sortable identification.

We use this id to identify and track the invoice throughout its lifecycle, from creation to transmission and response handling.

Invoice Lifecycle

  1. Creation: An invoice is created with all required parties and financial information
  2. Locking: Invoices are locked by default (is_locked = true) to prevent modifications after transmission
  3. Transmission: The invoice is sent to the PEPPOL network, creating transmission records
  4. Response Handling: Responses are received and linked to the invoice via response_code
  5. Webhooks: Webhooks notify the system of status changes

Relationship: Invoice - Transmission

An Invoice has many Transmissions. Each transmission represents an attempt to send the invoice to the PEPPOL network.

Transmission Structure

Transmissions track the delivery lifecycle:

  • status_code: HTTP-style status code indicating transmission result
  • response_code: PEPPOL response code (2 characters)
  • error_message: Detailed error information if transmission failed

Why Multiple Transmissions?

An invoice may have multiple transmissions due to:

  • Initial transmission attempts that failed
  • Retries after network or validation errors
  • Updates or corrections requiring re-transmission

Relationship: Transmission - Invoice Response

Invoice responses represent feedback from the receiving party or PEPPOL Access Point. Transmissions can have multiple Invoice Responses.

Invoice Response Structure

  • response_code: 2-character code indicating the response type (acceptance, rejection, etc.)
  • reason_code: Optional 3-character code providing more specific reason information
  • reason: Human-readable text explanation of the response
  • created_at: Timestamp of when the response was received

Response Flow

  1. A transmission is sent for an invoice (a new Transmission record is created)
  2. The PEPPOL network or recipient processes the invoice and generates a response asynchronously
  3. Responses are received and linked to the corresponding Transmission
  4. The invoice's response_code field is updated with the latest response status
  5. Multiple responses may be received over time (status updates, clarifications, final acceptance/rejection)
  6. Webhooks notify the system of status changes

If a rejection occurs, the seller may need to correct and resend the invoice, which results in new transmissions and responses lifecycle.

Data Model Summary

Invoice Relationship Diagram

  • One Invoice can have many Transmissions (delivery attempts)
  • One Transmission can have many Responses (tracking which transmission generated which response)

This architecture ensures complete auditability and traceability of the entire invoice lifecycle from creation through delivery to final resolution.

Released under the MIT License.