Use the SDK-level complete-receipt flow where available. It coordinates the merchant side of the current digital route:
- resolve the customer and owner devices
- inspect the explicit
deliveryRouteType - serialize the definitive receipt payload locally
- encrypt that payload independently for every matched device
- submit the complete device set to
/receipt/encrypted
The accepted submission becomes durable device work. Final CHEQI and UBL documents are generated later on owner devices, not by the backend.
ReceiptResult result = sdk.getReceiptService()
.issueReceipt(identificationDetails, receiptPayload);
if (result.isAccepted()) {
System.out.println(result.getDeliveryRouteType());
System.out.println(result.getCheqiReceiptId());
} else if (result.isEmailReceiptRequired()) {
// Generate and submit the email receipt explicitly.
} else if (result.isDownloadEnvelopeRequired()) {
// Build a final ReceiptEnvelope and call completeDownloadFallback(...).
}Both current SDKs accept a definitive ReceiptPayload. For digital delivery, the SDK encrypts that input locally; it does not send it to a plaintext template-generation endpoint. A missing route is raised as CUSTOMER_NOT_FOUND by the high-level method rather than returned as a ReceiptResult state.
If you implement the low-level flow yourself, submit the match and one independently encrypted copy per matched device:
{
"matchId": "match_opaque",
"storeId": "4ce2f858-d57d-4fde-a7ce-2e93f165494b",
"deviceDeliveries": [
{
"deviceRecipientId": "rcpt_temporary_1",
"encryptedContent": "base64-aes-gcm-ciphertext",
"encryptedAesKey": "base64-wrapped-content-key"
},
{
"deviceRecipientId": "rcpt_temporary_2",
"encryptedContent": "base64-aes-gcm-ciphertext",
"encryptedAesKey": "base64-wrapped-content-key"
}
]
}storeId is optional. When present, it must identify a store directly owned by the company in the authenticated token. The authenticated company remains the legal issuer.
A successful request returns 202 Accepted:
{
"cheqiReceiptId": "CHQ-20260802-143502-A1B2C3",
"matchId": "match_opaque",
"status": "PENDING",
"createdAt": "2026-08-02T14:35:02Z"
}Acceptance means Cheqi durably queued the encrypted work. It does not mean a phone has generated or acknowledged the receipt yet.
- Treat
matchIdas single-use, short-lived flow state. - Submit exactly the temporary device recipient IDs returned by that match.
- Encrypt the same definitive payload independently with a fresh symmetric key for every device.
- Preserve the returned
cheqiReceiptId; it identifies the durable receipt job after the match has been consumed. - A retry with the same match and identical request is idempotent. A conflicting replay is rejected.
- Do not put plaintext receipt contents, final CHEQI JSON, or UBL XML in the encrypted-submission request outside the device ciphertext.
Determine the legal issuer before recipient resolution and use the same company-bound access token through resolution and encrypted submission.
For company groups, obtain a delegated token for the company that legally made the sale. A parent-company token cannot select a child as issuer. The deprecated childCompanyId field does not grant parent-to-child issuance.
See Companies, Child Companies, and Stores for retail, group, and franchise mappings.
Follow deliveryRouteType; do not infer the route from recipient count.
DIGITAL: encrypt the definitive payload for every matched owner device and submit/receipt/encrypted.DOWNLOAD_FALLBACK: build and encrypt the download envelope locally, then use/receipt/download. The response URL carries the content key only in its fragment.routeFound: false: stop with customer-not-found in the healthy online flow.
Download fallback does not return a Cheqi-held recipient key and does not go through /receipt/encrypted. See Download Links.
Cheqi creates durable encrypted generation work for each assigned device and an outbox entry for its opaque push hint. A phone may process the job from that hint or during foreground catch-up sync. Only device generation, acknowledgement, and encrypted downstream delivery advance the durable job; provider acceptance of a push does not.
See Mobile Delivery for APNs, FCM, notification permission, retry, and force-quit behavior.