Receipt validation logic
The Receipt API validates every receipt against the retail JSON schema. It can also check whether the receipt is internally consistent, including totals, line-item calculations, and the information needed to deliver the receipt to a customer.
Validation feedback
Section titled “Validation feedback”JSON-schema validation is always enabled. A malformed request is rejected with
HTTP 400 and error code 40000.
Semantic validation feedback is opt-in:
- Newly created sandbox partners are opted in automatically. Ask Kivra to opt out if your data is not ready for these checks.
- Production partners are opted out until validation feedback is enabled for their account.
When semantic validation feedback is enabled, an error finding rejects the
receipt with HTTP 400 and error code 40020. Accepted receipts return HTTP
201 or 202 and can include non-fatal warning and info findings.
Findings
Section titled “Findings”Each finding contains:
| Field | Description |
|---|---|
code |
Stable identifier for the validation check, such as items.paid_mismatch. |
severity |
error, warning, or info. |
path |
Path to the relevant value in the receipt, such as payments[0].tender.card_token. |
message |
Human-readable explanation of the finding. |
expected |
Expected value, when the finding is a mismatch. |
actual |
Value found, when the finding is a mismatch. |
Severity describes whether the receipt violates a contract. It does not
describe how important the finding is to your integration. Some warning and
info findings can be functionally required for a particular flow.
For example, Kivra can deliver a receipt to a customer only when the receipt
contains an identifier such as an SSN, email address, phone number, or
card_token. A store that does not capture customer identity at checkout
typically relies on card_token. Use the par scheme when available for more
reliable matching. The related transaction.* findings may be info or
warning, but they are effectively required for delivery in this flow.
Examples of validation messages:
| Severity | Code | Example message |
|---|---|---|
| error | totals.paid_mismatch |
Paid total 90.00 does not match the sum of payments 100.00 (difference -10.0000). |
| warning | items.amount_math_imprecise |
extended_amount 36.1500 differs from actual_sales_unit_price x quantity (21.9000 x 1.6500 = 36.1350, difference 0.0150). |
| info | transaction.field_missing |
card_token is missing on a creditdebit payment; Kivra uses it to match the receipt to a customer. |
| info | transaction.card_token_scheme_not_par |
The card_token scheme is kivra; par is recommended for reliable matching. |
Finding codes
Section titled “Finding codes”The following codes describe the current validation checks. Their default
severities can change over time, so branch on the returned severity instead
of assuming a severity for a particular code.
Totals
Section titled “Totals”| Code | Severity | Meaning |
|---|---|---|
totals.gross_missing |
error | No gross entry exists in totals. |
totals.gross_mismatch |
error | The gross total does not match the sum of item gross amounts. |
totals.paid_missing |
error | No paid entry exists in totals. |
totals.paid_mismatch |
error | The paid total does not match the sum of payments. |
| Code | Severity | Meaning |
|---|---|---|
vat.total_missing |
error | No vat entry exists in totals. |
vat.total_mismatch |
error | The vat total does not match the VAT derived from the receipt. |
vat.subtotal_inconsistent |
error | The vat total does not match the sum of its sub_totals. |
Payments and amounts
Section titled “Payments and amounts”| Code | Severity | Meaning |
|---|---|---|
payments.refund_flag_mismatch |
error | A refund flag is inconsistent with the signed amounts. |
amounts.negative |
error | A negative amount appears where only non-negative values are allowed. |
| Code | Severity | Meaning |
|---|---|---|
items.amount_math_mismatch |
error | extended_amount does not match actual_sales_unit_price x quantity. |
items.amount_math_imprecise |
warning | extended_amount differs from the price-by-quantity result by a small, rounding-level amount. |
items.paid_mismatch |
error | The paid total does not match the amount derived from the line items. |
items.vat_mismatch |
error | The vat total does not match the VAT derived from the line items. |
items.deposit_vat_unresolved |
warning | A deposit’s VAT cannot be derived because it has no tax_percentage and no resolvable item_link. |
items.multiple_replace |
warning | A line has more than one replace retail price modifier. replace substitutes the line amount, so at most one is meaningful. |
items.incomplete |
warning | A required field is missing on an item. |
Transactions
Section titled “Transactions”These checks apply to creditdebit payments.
| Code | Severity | Meaning |
|---|---|---|
transaction.field_missing |
info | A contract-optional creditdebit field is missing, such as card_token or card_acceptor_id. Kivra uses card_token to match the receipt to a customer. |
transaction.recommended_field_missing |
warning | A recommended creditdebit field is missing. |
transaction.card_token_scheme_not_par |
info | The card_token scheme is not par. The par scheme is recommended for reliable matching. |
transaction.payment_slip_missing |
warning | A creditdebit payment has no payment_slip. |
Structure
Section titled “Structure”| Code | Severity | Meaning |
|---|---|---|
merchant.incomplete |
warning | The merchant or business unit is missing recommended fields. |
identifier.incomplete |
warning | The receipt identifier is missing recommended fields. |
control_unit.incomplete |
warning | Control unit information is missing recommended fields. |
Handling findings
Section titled “Handling findings”Treat error findings as rejected data and correct the receipt before
resending it. Review warning and info findings as well: they can identify
missing customer identifiers, incomplete payment data, or presentation issues.
The Merchant Toolbox uses the same receipt rules. Use it to validate a payload and preview how the receipt will render before sending it from your POS integration.