In J2Commerce 6.6.4, the invoice identity is directly coupled to the order.
An invoice number is assigned when an order is created, and InvoiceHelper::hasInvoiceNumber() effectively considers every existing order to have an invoice number.
However, an order and an invoice are separate business documents and accounting events. An order documents what a customer has ordered, while an invoice is a separate billing document issued for that transaction.
Creating an order should therefore not automatically create an invoice or assign an invoice number.
The current coupling makes it impossible to represent a clean lifecycle between ordering, invoicing, payment, cancellation and invoice correction.
International and EU relevanceThe separation of orders and invoices is not specific to the European Union. It is a standard distinction in commercial and accounting workflows internationally, including in the United States and many other jurisdictions.
The exact legal requirements for invoices, cancellations and corrections vary by jurisdiction. However, coupling the invoice identity directly to the creation of an order prevents J2Commerce from supporting these different workflows cleanly.
Within the European Union, the issue has additional regulatory significance. VAT invoicing rules define invoices as regulated accounting documents with requirements including an issue date and unique sequential identification, as well as requirements for documents correcting an issued invoice.
Therefore, this is both:
- a general international commerce/accounting architecture issue, and
- a specific invoicing compliance concern for shops operating under EU VAT rules.
Current behavior
The current workflow is effectively
Create Order → Invoice identity is created automatically
This creates several problems:
- An order may be cancelled before an invoice needs to be issued.
- An invoice number is already assigned even though no separate invoicing action has taken place.
- J2Commerce cannot properly distinguish between an order that has not yet been invoiced and an invoiced order.
- Once an invoice has been issued, there is no complete invoice correction lifecycle for full or partial cancellations.
The invoice identity is also derived directly from the order ID, which further couples both documents.
Expected behaviorOrder creation and invoice creation should be separate processes:
Order → Create Invoice → Invoice
Creating an order should only create an order.
Invoice creation should be a separate action and may be triggered:
- manually by the shop administrator, or
- automatically when appropriate, for example after a successfully completed payment.
Only when the invoice is actually created should an invoice number be assigned.
An order that has not yet been invoiced can simply be cancelled without creating an unnecessary invoice correction process.
Invoice corrections and cancellationsOnce an invoice has been issued, it should remain unchanged and traceable.
J2Commerce therefore also needs a proper correction workflow for issued invoices:
- Full cancellation: Create a cancellation/correction invoice for the complete original invoice.
- Partial cancellation/correction: Create a correction document for individual items, quantities or amounts.
- The correction document must clearly reference the original invoice.
- The original invoice must remain unchanged and traceable.
A payment refund alone is not sufficient, because the payment transaction and the correction of an issued invoice are separate business processes.
Technical issueCurrently, J2Commerce effectively determines the existence of an invoice from the existence of the order itself.
For example, InvoiceHelper::hasInvoiceNumber() considers an existing j2commerce_order_id sufficient to determine that an invoice number exists.
The invoice number is also derived from the order ID rather than being created as part of a separate invoice process.
This means J2Commerce cannot properly represent the different states:
Order not invoiced → Invoice issued → Invoice partially corrected → Invoice fully cancelled/corrected
Proposed solutionOrders and invoices should be separated at the core level.
J2Commerce should provide:
1. Order lifecycle
Order creation, processing and cancellation without automatically creating an invoice.
2. Invoice lifecycle
Explicit invoice creation with its own invoice number and issue date.
3. Configurable invoice trigger
Manual creation by default, with optional automatic creation based on events such as successful payment.
4. Invoice correction lifecycle
Full and partial correction/cancellation documents referencing the original invoice while preserving the original document.
This would establish a clear separation between orders, payments, invoices and invoice corrections and provide a reliable foundation for legally compliant invoicing workflows.