Fiscal Lifecycle
Orders can communicate fiscal intent through two fields:
| Field | Values |
|---|---|
fiscal_event | order_sync, invoice_candidate, cancel_candidate, refund_candidate |
invoice_action | none, create_invoice, cancel_or_annul, rectify_or_refund, exchange_to_full (v1.1) |
Common Flows
| Scenario | fiscal_event | invoice_action |
|---|---|---|
| Sync without invoicing | order_sync | none |
| Paid order ready to invoice | invoice_candidate | create_invoice |
| Cancelled order | cancel_candidate | cancel_or_annul |
| Partial or total refund | refund_candidate | rectify_or_refund |
| Guest checkout later provides a tax ID | invoice_candidate | exchange_to_full (v1.1) |
For post-invoice changes, send contract_version: "1.3" with correction_events[]. Refunds and returns should include stable event ids, line-level evidence and signed deltas. A fingerprint-only change is unknown: it opens guided review but is never auto-corrected. Legacy refunds[] remains compatible.
F2-to-F3 Exchange
A guest buyer first receives a simplified invoice (F2, "ticket"). If they later provide their tax details and request a full invoice, resend the order with invoice_action: "exchange_to_full" and the customer's full tax identification in client:
json
{
"contract_version": "1.1",
"id_external": "order-1001",
"reference": "1001",
"fiscal_event": "invoice_candidate",
"invoice_action": "exchange_to_full",
"original_order_reference": "1001",
"client": {
"id_external": "customer-1001",
"company": "Example SL",
"vat_number": "B00000000",
"customer_type": "b2b",
"tax_id_type": "cif",
"country": "ES"
}
}original_order_referenceis only needed when the exchange is sent as a new order referencing the original one. Omit it when the exchange is sent as an update of the same order.- The core issues a full invoice (F3) that supersedes the F2. The F2 is not cancelled or rectified.
- The exchange requires the F2 to be accepted, not previously exchanged, and within the allowed time window. If a guard is not met, the order is left in
needs_reviewinstead of returning an error. - Resending the same exchange is idempotent: it will not generate a second F3.