Skip to content

Return webhooks cover two distinct encrypted flows:

  • A customer sends an encrypted return request to the original issuer (RETURN_REQUESTED).
  • An issuer creates a credit note through the device-generation flow, and an elected owner device encrypts the generated document bundle for downstream recipients (CREDIT_NOTE_CREATED).

The backend routes both ciphertext types without decrypting them.

Subscribe

{
  "name": "Returns integration",
  "notificationUrl": "https://your-domain.example/webhooks/cheqi",
  "events": [
    "RETURN_REQUESTED",
    "CREDIT_NOTE_CREATED"
  ]
}

RETURN_REQUESTED

{
  "event": "RETURN_REQUESTED",
  "data": {
    "creditNoteInitiationRequest": {
      "clientId": "issuer-public-client-id",
      "companyId": "550e8400-e29b-41d4-a716-446655440000",
      "userId": "8ccf09a7-d969-4a09-880f-42d520a0999a",
      "created_at": "2026-08-03T14:00:00Z",
      "cheqiReceiptId": "CHQ-20260803-ABC123",
      "publicKey": "base64-issuer-public-key...",
      "encryptedCreditNoteInitiationRequest": "base64-ciphertext...",
      "encryptedSymmetricKey": "base64-wrapped-aes-key..."
    }
  }
}

The customer device created this encrypted request for the original receipt issuer. Unwrap encryptedSymmetricKey, decrypt encryptedCreditNoteInitiationRequest, and deserialize the plaintext as CreditNoteInitiationRequest.

The plaintext contract contains:

  • cheqiReceiptId: Cheqi identifier of the original receipt.
  • receiptId: issuer-supplied identifier of the original receipt.
  • customerNote: optional customer note.
  • lineItems: requested quantities and return reasons.
  • refundPreference: preferred refund method.
  • refundBankAccount: supplied only when required for a bank-transfer preference.

This request is not a credit note and is not a ReceiptEnvelope. Validate it against your records and return policy before issuing a credit note.

Issue through the new credit-note flow

When accepting a return, issue the credit note through POST /credit-note/encrypted:

  1. Resolve the original owner's current devices.
  2. Encrypt the credit-note generation input independently for every returned device recipient.
  3. Submit the encrypted generation request with parentCheqiReceiptId.
  4. Owner devices generate and store their local CHEQI credit note.
  5. One elected device builds and encrypts downstream ReceiptEnvelope bundles.
  6. Cheqi sends CREDIT_NOTE_CREATED after those encrypted deliveries are accepted.

Do not use the legacy EncryptedCreditNoteDto delivery shape. It is not part of the current webhook contract.

CREDIT_NOTE_CREATED

{
  "event": "CREDIT_NOTE_CREATED",
  "data": {
    "encryptedCreditNote": {
      "clientId": "your-public-client-id",
      "companyId": "550e8400-e29b-41d4-a716-446655440000",
      "created_at": "2026-08-03T15:00:00Z",
      "cheqiReceiptId": "CHQ-CN-20260803-DEF456",
      "encryptedEnvelope": "base64-ciphertext...",
      "encryptedEnvelopeKey": "base64-wrapped-aes-key...",
      "publicKey": "base64-recipient-public-key-snapshot...",
      "recipientKeyAlgorithm": "RSA_2048",
      "envelopeVersion": 1,
      "receiptGeneratorVersion": "0.3.0",
      "finalHash": "sha256-cheqi-credit-note-hash..."
    }
  }
}

Decrypt encryptedEnvelope with the same SDK envelope implementation used for receipt webhooks. The plaintext is a ReceiptEnvelope whose documents map contains:

  • CHEQI always.
  • UBL_CREDIT_NOTE when required by the recipient's accepted formats.

The documents map is authoritative. There is no separate format list or customer-details ciphertext.

finalHash is the definitive CHEQI credit-note hash submitted by the elected device together with the encrypted deliveries. A separate finalization event is not required.

Operational guidance

  • Verify X-Cheqi-Signature using the exact raw request body.
  • Persist the event before returning 2xx.
  • Process asynchronously and idempotently.
  • Keep historical private keys available for deliveries encrypted before a key rotation.
  • Never log decrypted return requests, document envelopes, or unwrapped AES keys.

See Webhook Events for the shared event contract and Webhook Security for signature verification.