Skip to content

Sending Receipts

Pass your identification details and completed receipt payload to the SDK. It resolves the delivery route, encrypts the receipt locally, and submits it. Store the returned receipt ID and delivery result.

Complete receipt flow

ReceiptResult result = sdk.getReceiptService()
    .issueReceipt(identificationDetails, receiptPayload);

if (result.isAccepted()) {
    System.out.println(result.getDeliveryRouteType());
    System.out.println(result.getCheqiReceiptId());
} else if (result.isDownloadEnvelopeRequired()) {
    // Build a final ReceiptEnvelope and call completeDownloadFallback(...).
}

To act for a connected company, pass its OAuth access token per call with RequestOptions; see OAuth 2.0.

All current SDKs accept a definitive ReceiptPayload. For digital delivery, the SDK encrypts that input locally. A missing route is raised as CUSTOMER_NOT_FOUND by the high-level method rather than returned as a ReceiptResult state.

Submission result

The SDK handles encrypted submission. For a custom integration, use the partner API reference for request fields and follow the submission rules below.

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 the submission is stored for processing. It does not confirm completed delivery to the customer.

Submission rules

  • Treat matchId as short-lived flow state that creates at most one digital submission. Keep it to recover an uncertain outcome.
  • 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.
  • If the outcome is uncertain, check GET /recipient/matches/{matchId}. A submitted match returns its original acceptance result; an in-progress match can be retried after the indicated delay. Reuse the original match and definitive receipt payload. Encryption may produce different ciphertext on retry, and the original requester still receives the accepted result.
  • An expired, unsubmitted match cannot be used for digital delivery. Resolve the recipient again before a new submission.
  • 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.

Delivery routes

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: end the Cheqi flow and use your existing receipt process in the healthy online flow.

See Download Links for merchant upload and Web Wallet for the customer app and browser paths.

After submission

Keep the returned cheqiReceiptId and delivery result for your records. The customer receives the encrypted receipt through the Cheqi app. If the customer does not see it immediately, they can reopen the app to refresh their wallet.