Skip to content

Recipient resolution is the first step in the Cheqi receipt and credit note flows. You submit IdentificationDetails, and Cheqi returns:

  • whether a delivery route was found
  • the matchId used for later submission
  • an explicit deliveryRouteType
  • for digital delivery, one temporary recipient and public key per owner device
  • server-known customer context such as buyerCountryCode and buyerType

Supported identifiers

The current API and SDKs support these fields on IdentificationDetails:

FieldTypical use
pairingCodeCustomer-generated code from the Cheqi app
cardDetailsIn-store card payments using PAR or other card identifiers
paymentAccountDetailsIBAN or other payment-account-based matching
recipientEmailWebshop flows and fallback delivery
cheqiReceiptIdFollow-up flows tied to an existing receipt, especially credit notes

Priority order

The backend resolves identifiers in this order:

  1. cheqiReceiptId
  2. pairingCode
  3. paymentAccountDetails
  4. cardDetails
  5. recipientEmail

cheqiReceiptId is an explicit follow-up-flow override. For new checkout flows, pairing code takes precedence over payment-account, card, and email matching. When multiple supplied identifiers resolve to different customers, Cheqi rejects the request instead of silently choosing one identity.

Card-payment receipt metadata

merchantId and paymentTerminalId are not fields on the current IdentificationDetails model. Put those display values in the definitive, encrypted ReceiptPayload.paymentDetails object. They are not customer identifiers and do not change matching priority.

Pairing code example

IdentificationDetails identificationDetails = new IdentificationDetails()
    .paymentType(PaymentType.CARD_PAYMENT)
    .pairingCode("84739201");

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

Card and email matching

IdentificationDetails customer = new IdentificationDetails()
    .paymentType(PaymentType.CARD_PAYMENT)
    .cardDetails(new CardDetails()
        .paymentAccountReference("PAR123456789")
        .cardProvider(CardDetails.CardProviderEnum.VISA))
    .recipientEmail("customer@example.com");

Payment-account matching

IdentificationDetails customer = new IdentificationDetails()
    .paymentType(PaymentType.DIRECT_DEBIT)
    .paymentAccountDetails(new PaymentAccountDetails()
        .identifier("NL91ABNA0417164300")
        .accountIdentifierType(AccountIdentifierType.IBAN))
    .recipientEmail("customer@example.com");

Match response

Typical fields in the current response:

{
  "routeFound": true,
  "deliveryRouteType": "DIGITAL",
  "matchId": "match_123456789",
  "recipients": [
    {
      "id": "rcpt_abc123",
      "publicKey": "base64-encoded-key",
      "keyAlgorithm": "RSA_2048",
      "acceptedFormats": ["CHEQI"]
    }
  ],
  "expiresAt": "2026-01-26T20:00:00Z",
  "buyerCountryCode": "DE",
  "buyerType": "BUSINESS"
}

The initial digital recipients are owner devices. They are not the downstream company or client-application recipients, which one leased device resolves after local generation.

Recipient IDs are temporary, opaque, and scoped to this match. Do not expose them as customer identifiers or reuse them in another transaction.

Delivery routes are explicit

Use deliveryRouteType to choose the next step:

  • DIGITAL returns owner-device recipients. Encrypt the same definitive generation payload independently for every returned device and submit it to /receipt/encrypted.
  • DOWNLOAD_FALLBACK returns no device recipients. Build the client-encrypted download envelope locally and upload it through /receipt/download.
  • routeFound: false means no enabled route was found.

Do not infer the route from the number of recipients. In particular, download fallback no longer uses a Cheqi-held fallback key and does not submit through /receipt/encrypted.

A request without a customer locator can deliberately select the anonymous download fallback when that route is enabled. See Download Links.

How the flow uses this response

  • For DIGITAL, matchId is sent back with /receipt/encrypted and consumed by that submission.
  • recipients provide the temporary device IDs and public keys used to encrypt the merchant generation input.
  • Send the same definitive payload to every device. Do not pre-generate or filter final CHEQI or UBL documents on the merchant side.
  • buyerCountryCode and buyerType are server-known context. The backend snapshots the routing context and returns it to the authenticated device with its encrypted job.
  • Downstream recipient formats are resolved later by exactly one leased owner device.

Best practices

  • Include recipientEmail when it is an available recipient-resolution identifier.
  • Enable the download fallback when you want to offer a receipt to every customer, including unmatched or anonymous ones, via a QR code or link.
  • Treat the returned device set as exact: submit one independently encrypted delivery for every recipient and no extras.
  • Use a fresh symmetric content key for each device.
  • Branch on deliveryRouteType; do not treat fallback routes as normal device matches.
  • Use cheqiReceiptId for follow-up flows such as issuing credit notes against an existing receipt.