Finalizes the sale. This is a fiscal event — the platform signs the end, generates the fiscal document, and (where required) transmits to the tax authority.
The response includes the fully-formed operation with fiscal.end_event populated.
The receipt is now available at GET /operations/:id/receipt.
After completion, fiscal contains both the start and end signatures,
as required by KassenSichV. Both must be printed on the receipt.
"fiscal": {
"regime": "tse",
"document_number": "2026-004822",
"document_type": "Kassenbeleg",
"transmission_status": "not_required",
"tse_serial": "TSE0123456789ABCDEF",
"client_id": "Kasse1",
"signature_algorithm": "ecdsa-plain-SHA384",
"time_format": "utcTime",
"start_event": {
"signed_at": "2026-02-25T19:02:11Z",
"transaction_counter": 4821,
"signature": "base64encodedStartSignature=="
},
"end_event": {
"signed_at": "2026-02-25T20:14:55Z",
"transaction_counter": 4822,
"signature": "base64encodedEndSignature==",
"process_type": "Kassenbeleg-V1",
"process_data": "Beleg^42.50_0.00_0.00_0.00_0.00^42.50:Bar"
},
"verification": {
"qr_data": "V0;Kasse1;ecdsa-plain-SHA384;2026-02-25T19:02:11;2026-02-25T20:14:55;42.50;4822;base64encodedEndSignature=="
}
}
The qr_data value follows the DSFinV-K QR format and is printed verbatim
on the receipt.
Platform API key sent as Authorization: Bearer ofk_platform_....
Platform integrators also pass OpenFiskal-Organization: org_xxx
to act on behalf of a merchant.
Merchant organization ID. Required for platform integrators acting on behalf of a specific merchant. Omit when using an organization-scoped API key directly.
Unique key to make the request idempotent. If a request with this key
was already processed, the original response is returned without
re-executing the operation. Strongly recommended on all start and
complete actions — these are fiscal events and must not be duplicated.
Data required to finalize and fiscalize the sale.
One or more payments settling this sale. All payment lines on a
sale should have direction: inbound.
For cash sales, include a separate outbound cash line for change:
[
{ "method": "cash", "direction": "inbound", "amount": 5000, "cash": { "amount_tendered": 5000 } },
{ "method": "cash", "direction": "outbound", "amount": 750 }
]1Order-level discounts to be allocated across line items.
OpenFiskal allocates each discount to line items according to
the allocation_method and records allocations on each LineItem.
Optional jurisdiction-specific overrides. See jurisdiction guides.
Sale completed and fiscalized
Shared fields present on every operation regardless of type.
"op_01HXYZ"
"operation"sale The POS lifecycle state of the operation. Transitions are
one-directional and enforced server-side — invalid transitions
return 409 Conflict.
open — operation in progress, mutations allowedcompleted — POS finalized the operation (payment collected)cancelled — POS cancelled before completion| From | Event | To |
|---|---|---|
open | POST .../complete | completed |
open | POST .../cancel | cancelled |
open, completed, cancelled Monotonically increasing, register-scoped sequence number
Jurisdiction-specific fiscal output attached to every operation.
Discriminated by regime — each variant carries typed fields for its
fiscal security device and signing protocol.
The fiscalization state of the operation, tracked independently from the operation state.
pending — fiscalization not yet attempted or in progresssucceeded — fiscal device recorded the event, fiscal data availablefailed — fiscalization failed (device unreachable, transmission error)The POS should check fiscal.state before printing — only print
fiscal data on the receipt when it is succeeded.
pending, succeeded, failed Links to related operations. The audit chain between operations lives here
at the envelope level — not inside the type-specific data block — because
any operation type can reference any other.
Timestamp of the fiscal start event