# Return Webhooks

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

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

## `RETURN_REQUESTED`

```json
{
  "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`

```json
{
  "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](/webhooks/events) for the shared event contract and [Webhook Security](/webhooks/security) for signature verification.