> ## Documentation Index
> Fetch the complete documentation index at: https://docs.paylead.fr/llms.txt
> Use this file to discover all available pages before exploring further.

# Sales report automation

> Receive your daily sales report automatically, delivered to your system through a signed Webhook and a single-use, PGP-encrypted file.

Sales report automation delivers your transactions to your system on a recurring schedule, without any manual export. Paylead generates an encrypted file, notifies you through a signed [Webhook](/glossary#webhooks), and lets you download the file through a single-use URL that you decrypt with your own key. This guide describes how the service works and what you set up on your side.

## How it works

On a recurring schedule, Paylead exports the transactions accumulated since the previous run into a secure file, then notifies your endpoint. You verify the notification, download the file, and decrypt it.

```mermaid theme={null}
%%{init: {'themeVariables': {'actorBorder':'#0465ff','signalColor':'#378add'}}}%%
sequenceDiagram
    autonumber
    participant P as Paylead
    participant Y as Your system
    P->>P: Generate the day's encrypted report
    P->>Y: POST Webhook notification
    Y->>Y: Verify the HMAC signature
    Y->>P: Request the file via the pre-signed URL
    P-->>Y: Encrypted file (URL valid 24 hours)
    Y->>Y: Decrypt with your PGP private key
```

### Key points

* Each report covers the period since the previous generation: a daily schedule delivers the previous day's transactions, a monthly schedule delivers roughly the last 30 days. The exact window is the `period` field in the Webhook payload.
* By default it is generated once a day at 09:00, Europe/Paris time (UTC+1, or UTC+2 during daylight saving time). The trigger time and the frequency are both configurable.
* The file is encrypted with your PGP public key (asymmetric encryption), so only you can decrypt it.
* The Webhook can be signed with `HMAC-SHA256` (optional, strongly recommended) so you can verify its authenticity.
* The download URL is single-use and expires after 24 hours.

<Note>
  Before you start, you need:

  * An HTTPS endpoint that can receive Webhooks (`POST` requests with a JSON body).
  * The ability to generate a PGP key pair and decrypt PGP files.
</Note>

## The Webhook

### Method and endpoint

Paylead sends an HTTP `POST` request to the Webhook URL you provide.

### Payload

The request body is a JSON object.

```json theme={null}
{
  "type": "sales_report",
  "url": "<pre-signed download URL>",
  "content_type": "application/pgp-encrypted",
  "inner_content_type": "text/csv",
  "headers": ["transaction_id", "brand", "..."],
  "period": {
    "start_date": "2026-04-01T00:00:00Z",
    "end_date": "2026-04-30T23:59:59Z"
  },
  "brand_reference": "BRAND_REF_123",
  "expire_at": "2026-05-07T00:00:00Z"
}
```

<ResponseField name="type" type="string">
  Event type. Always `sales_report`.
</ResponseField>

<ResponseField name="url" type="string">
  Pre-signed URL used to download the report file.
</ResponseField>

<ResponseField name="content_type" type="string">
  Type of the delivered file. Always `application/pgp-encrypted`.
</ResponseField>

<ResponseField name="inner_content_type" type="string">
  Type of the file once decrypted. Always `text/csv`.
</ResponseField>

<ResponseField name="headers" type="array">
  List of the CSV column names, in order.
</ResponseField>

<ResponseField name="period" type="object">
  Period covered by the report.

  <Expandable title="period">
    <ResponseField name="start_date" type="string">
      Start of the period (ISO 8601).
    </ResponseField>

    <ResponseField name="end_date" type="string">
      End of the period (ISO 8601).
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="brand_reference" type="string">
  Reference of the [Brand](/glossary#brand) covered by the report.
</ResponseField>

<ResponseField name="expire_at" type="string">
  Expiration timestamp of the pre-signed URL.
</ResponseField>

### Authentication with HMAC

Signing Webhooks with `HMAC-SHA256` is optional.

<Tip>
  Paylead strongly recommends enabling HMAC signing. It lets you confirm that each Webhook was sent by Paylead and was not tampered with in transit.
</Tip>

When signing is enabled, each request carries a signature of the request body in the following header:

```http theme={null}
X-paylead-signature-256: <hmac-sha256-hex>
```

Verify this signature on every Webhook you receive, using the shared HMAC secret key that Paylead provides.

<Warning>
  Encode the secret to bytes as **UTF-8** to obtain the verification key. Do not base64-decode it, even though its format may look like base64.
</Warning>

The following example verifies a signature in Python. The values are illustrative.

```python theme={null}
import hashlib
import hmac

signature = "75d6c5e87f06bcf3f7b3460336927a9572f09e6407610f09c9e259e05ed2e380"
content = '{"url":"https://example.com/sales-report.csv","brand_reference":"BRAND_REF_123"'.encode("utf-8")
hmac_secret = "vmj8isJ5tDstao3s/L1yJovx5XsOGz/8NWo8RvYR5l4=".encode("utf-8")
expected_signature = hmac.new(hmac_secret, content, digestmod=hashlib.sha256).hexdigest()
assert expected_signature == signature
```

### Retry policy

Any `2xx` response is treated as a successful delivery. On failure, Paylead retries the request up to 8 times with exponential backoff (1 minute to 1 hour) for the status codes below. All other error codes are not retried.

| Code  | Reason                |
| ----- | --------------------- |
| `429` | Too Many Requests     |
| `500` | Internal Server Error |
| `502` | Bad Gateway           |
| `503` | Service Unavailable   |
| `504` | Gateway Timeout       |

## Report file format

The delivered file is a PGP-encrypted CSV. Each row is one commissioned transaction, with the [Brand](/glossary#brand), the [Cashback](/glossary#cashback) strategy, the [Campaign](/glossary#campaign), and the resulting merchant cost. Once decrypted, it contains the following columns.

| #  | Column                      | Description                            |
| -- | --------------------------- | -------------------------------------- |
| 1  | `transaction_id`            | Unique transaction identifier.         |
| 2  | `brand_country_code`        | Country code of the Brand.             |
| 3  | `brand`                     | Brand name.                            |
| 4  | `transaction_amount`        | Transaction amount (absolute value).   |
| 5  | `transaction_purchase_date` | Purchase date (Europe/Paris timezone). |
| 6  | `transaction_debit_date`    | Debit date.                            |
| 7  | `partner_name`              | Loyalty Program name.                  |
| 8  | `strategy`                  | Cashback strategy name.                |
| 9  | `strategy_reference`        | Strategy reference.                    |
| 10 | `strategy_objective`        | Strategy objective.                    |
| 11 | `cost_per_acquisition`      | Cost per acquisition (CPA) level.      |
| 12 | `paid_commissions`          | Merchant Cashback cost.                |
| 13 | `invoice_date`              | Invoice creation date.                 |
| 14 | `invoice_reference`         | Invoice reference.                     |
| 15 | `campaign_id`               | Campaign identifier.                   |
| 16 | `campaign_name`             | Campaign name.                         |
| 17 | `user_id`                   | Paylead user identifier.               |

## Set up the integration

Setup is a one-time exchange: you send Paylead an encryption key and an endpoint, Paylead sends you a signing secret, and you implement the verification and decryption steps. The delivery schedule (trigger time) and frequency are agreed with Paylead during setup; the defaults are once a day at 09:00 Europe/Paris.

### What you provide to Paylead

| Item           | Description                                                                                                      | Format                                                      |
| -------------- | ---------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------- |
| PGP public key | Used by Paylead to encrypt the report file. Must have the encryption capability `[E]`. Minimum validity: 1 year. | ASCII-armored `.asc` file. Ed25519 or RSA-4096 recommended. |
| Webhook URL    | HTTPS endpoint Paylead sends the Webhook notifications to.                                                       | HTTPS URL.                                                  |

### What Paylead provides

| Item            | Description                                                                                                                                                                   |
| --------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| HMAC secret key | Provided only when HMAC signing is enabled (recommended). Shared secret that lets you verify the Webhook signature. Generated by Paylead and delivered over a secure channel. |

### Checklist

To send to Paylead:

* PGP public key (ASCII-armored `.asc`, Ed25519 or RSA-4096, capability `[E]`, validity 1 year or more).
* Webhook endpoint URL (HTTPS).

To validate on your side:

* If HMAC signing is enabled (recommended): verify the signature in the `X-paylead-signature-256` header.
* Respond with an HTTP `2xx` code on correct receipt.
* Decrypt the PGP files with your private key.

## Notes

<Warning>
  **Download window.** The pre-signed URL is no longer accessible after 24 hours. Retrieve the file within this window.
</Warning>

<Warning>
  **Key rotation.** If you renew your PGP key pair, provide the new public key to Paylead in advance, so delivery stays continuous before the old key expires.
</Warning>
