---
title: "Events: orders, transactions and invoices"
description: "When order, payment transaction and invoice webhooks are sent, what they contain and in which order they may arrive on your side."
url: https://www.ciklik.academy/en/webhooks/evenements-commandes-transactions-factures/
lang: en
lastUpdated: 2026-10-09
---

# Events: orders, transactions and invoices

> Box and PrestaShop
>
> This page applies to both box stores and PrestaShop stores.

This page details the five keys of the purchase journey: the order, the payment transaction and the invoice. A complete purchase can produce, in this logical order but not necessarily in this order of arrival, a `created_checkoutorder`, one or more `created_checkouttransaction` then `updated_checkouttransaction`, and a `created_checkoutinvoice`. For the general configuration, see [Understanding a webhook delivery](https://www.ciklik.academy/en/webhooks/comprendre-un-envoi-de-webhook/).

## Order object

Every delivery related to an order carries the complete object. Lines and coupon are detailed in the next two sections.

| Field                                                         | Type                  | Nullable          | Description                                                                                                       |
| ------------------------------------------------------------- | --------------------- | ----------------- | ----------------------------------------------------------------------------------------------------------------- |
| `order_id`, `user_id`                                         | integer               | no                | Internal identifiers.                                                                                             |
| `user_uuid`                                                   | string                | no                | Public customer identifier (`cus_...`).                                                                           |
| `email`, `first_name`, `last_name`, `phone`                   | string                | yes, except email | Contact details, read from the order address.                                                                     |
| `status`                                                      | string                | no                | See the status table below.                                                                                       |
| `created`, `created_at`                                       | ISO 8601 date         | no                | Creation date, always in UTC.                                                                                     |
| `items`                                                       | array                 | no                | Lines, see *Order line object*.                                                                                   |
| `coupon`                                                      | object or empty array | no                | See *Coupon object*: the type changes depending on whether a coupon is applied or not.                            |
| `shipping`                                                    | string                | no                | Shipping costs, decimal point (`"4.90"`).                                                                         |
| `count`                                                       | integer               | no                | Number of lines.                                                                                                  |
| `total_tax_paid`, `total_discount_inc`, `total_shipping_paid` | string                | no                | Totals, **decimal comma** (`"31,81"`).                                                                            |
| `total_paid`                                                  | string                | yes               | Total paid, decimal comma; null until computed.                                                                   |
| `subscription_uuid`                                           | string                | yes               | Originating subscription, if any.                                                                                 |
| `revenue`, `refunded`                                         | string                | yes               | Subscription-related revenue and refunded amount, **decimal point**; null without a subscription.                 |
| `customerRevenue`, `customerRefund`                           | string                | no                | Customer-side revenue and refunded amount, **decimal point**; `"0.00"` without a subscription, never null.        |
| `subTransactionsSuccess`                                      | integer               | yes               | Number of successful transactions of the linked subscription, across all its orders; null without a subscription. |
| `totalTransactionsSuccess`                                    | integer               | no                | Number of successful transactions of the customer, across all subscriptions; never null.                          |
| `countTransactions`                                           | integer               | no                | Number of transactions of this order; never null.                                                                 |
| `next_billing`                                                | ISO 8601 date         | yes               | Next due date of the originating subscription.                                                                    |
| `choices`                                                     | (always null)         | yes               | Always null, reserved field.                                                                                      |
| `retry_link`                                                  | string                | yes               | Payment retry link; null without a customer secret.                                                               |
| `paid_transaction_id`, `paid_class_key`                       | string                | yes               | Identifier and payment method of the paid transaction.                                                            |
| `prestashop_order_id`                                         | integer               | yes               | Identifier on the PrestaShop side.                                                                                |

`status` takes one of eight values:

| Status                 | Meaning                                                          |
| ---------------------- | ---------------------------------------------------------------- |
| `pending`              | Awaiting payment.                                                |
| `in_creation`          | Being created: address or carrier not yet finalized.             |
| `in_process`           | Being processed.                                                 |
| `completed`            | Paid.                                                            |
| `failed`               | Failed.                                                          |
| `canceled`             | Canceled.                                                        |
| `need_action`          | An action from the customer is required to complete the payment. |
| `withdrawal_requested` | A withdrawal request is in progress.                             |

## Order line object

Each element of `items` corresponds to an ordered product or plan.

| Field                           | Type           | Nullable | Description                                                     |
| ------------------------------- | -------------- | -------- | --------------------------------------------------------------- |
| `id`                            | integer        | no       | Line identifier.                                                |
| `price`                         | number         | no       | Unit price excluding tax.                                       |
| `tax`                           | string         | no       | VAT rate, decimal as a string (`"0.200"`).                      |
| `quantity`                      | integer        | no       | Ordered quantity.                                               |
| `name`                          | string         | no       | Name of the product or plan at the time of the order.           |
| `type`                          | string         | no       | Type of the sold product: plan or product (technical value).    |
| `orderable`                     | object or null | yes      | See the note below; null if the product has been deleted since. |
| `affilae`, `external_id`, `ref` | string         | yes      | Affiliate tracking, external identifier, product reference.     |

> Non-contractual structure
>
> `orderable` is the internal reflection of the sold product or plan: a 39-column object, including `metadata` and `customizations`, which may change without notice. Only rely on `id`, `name`, `price` and `ref`.

## Coupon object

First applied coupon, if any. Without a coupon, `coupon` is `[]`; with a coupon, it is an object. **The type changes** from one delivery to the next: test for the empty array first.

| Field                               | Type            | Nullable | Description                                                                        |
| ----------------------------------- | --------------- | -------- | ---------------------------------------------------------------------------------- |
| `id`, `uuid`                        | integer, string | no       | Internal identifier and code entered by the customer.                              |
| `plans`                             | (always null)   | yes      | JSON column that is no longer populated.                                           |
| `price`, `percent_off`              | string          | yes      | Fixed discount, or percentage discount expressed as a fraction (`"0.10"` for 10%). |
| `duration`                          | string          | no       | Scope of the discount (`once`, `repeating`, `forever` on older coupons).           |
| `redeem_by`                         | integer         | no       | Redemption deadline, Unix timestamp.                                               |
| `display_amount`, `display_percent` | string          | yes      | Amount or percentage formatted for display.                                        |

## Transaction object

Each payment attempt produces a transaction. The delivered object carries the complete order under the `order` key.

| Field                                                                 | Type           | Nullable | Description                                             |
| --------------------------------------------------------------------- | -------------- | -------- | ------------------------------------------------------- |
| `order_id`, `tenant_id`                                               | integer        | no       | Associated order and store.                             |
| `order`                                                               | object or null | yes      | Complete order, see *Order object*; null if deleted.    |
| `gateway`                                                             | string         | no       | Payment method (`stripe`…).                             |
| `transaction_id`, `token`, `detail`, `source_id`, `payment_intent_id` | free-form      | yes      | Raw identifiers and details, depending on the provider. |
| `paid`                                                                | boolean        | no       | True once the payment is confirmed.                     |
| `amount`, `amount_refunded`                                           | string         | no       | Amounts, two decimals.                                  |
| `refunded`                                                            | boolean        | no       | True if the transaction has been refunded.              |
| `failure_message`, `failure_code`                                     | string         | yes      | Details of a payment failure.                           |
| `invoice_id`                                                          | integer        | yes      | Linked invoice; never appears in `changed`, see below.  |
| `statement_descriptor`                                                | string         | yes      | Label shown on the customer’s bank statement.           |
| `user_id`                                                             | integer        | yes      | Customer, when set.                                     |
| `created_at`, `updated_at`                                            | ISO 8601 date  | no       | Timestamps.                                             |

## Invoice object

The delivery is sent after the database commit, with the complete order under the `order` key.

| Field                                                    | Type           | Nullable | Description                                                              |
| -------------------------------------------------------- | -------------- | -------- | ------------------------------------------------------------------------ |
| `order_id`, `tenant_id`                                  | integer        | no       | Originating order and store concerned.                                   |
| `customer`, `company`                                    | object or null | yes      | See the note below, non-contractual structure.                           |
| `emitted_at`                                             | date           | no       | Issue date, at midnight UTC (`T00:00:00.000000Z`).                       |
| `number`                                                 | integer        | no       | Invoice number, specific to your store.                                  |
| `total_tax`, `total_discount`, `total`, `total_shipping` | string         | no       | Amounts with three decimals, decimal point (`"5.320"`).                  |
| `more`                                                   | string         | yes      | Additional mention.                                                      |
| `uuid`                                                   | string         | no       | Full number: prefix, year-month and number (`F2026-09-42`).              |
| `order`                                                  | object or null | yes      | Complete order, see *Order object*.                                      |
| `gateway`                                                | string         | yes      | Payment method of the paid transaction; null without a paid transaction. |

> Non-contractual structure
>
> `customer` and `company` are copied as-is at issue time: a snapshot of the customer’s contact details and of your store’s legal information on that date, in free-form structure, with no fixed schema.

## `created_checkoutorder`

Delivered object: complete order. Delay before sending: **10 seconds**, `changed` empty. Full example: in the OpenAPI contract (`/openapi/ciklik-webhooks.yaml`), webhook `created_checkoutorder`.

### When it is sent

On every actual creation of an order: checkout, subscription charge, composable or PrestaShop order.

### When it is not sent

No silent write identified at creation.

### What `changed` contains

Always an empty array.

### Cascading effects

None specific to creation. See the incoming cascades under `updated_checkoutorder`.

### Example

```json
{
    "order_id": 1,
    "user_id": 1,
    "user_uuid": "cus_Qx7hR3eaEowcv1DX",
    "first_name": "Claire",
    "last_name": "Martin",
    "phone": "+33612345678",
    "email": "claire.martin@example.com",
    "status": "pending",
    "created": "2026-09-10T08:15:42.000000Z",
    "items": [
        {
            "id": 1,
            "price": 29.9,
            "tax": "0.200",
            "quantity": 1,
            "name": "Box découverte",
            "type": "App\\Product",
            "orderable": {
                "id": 1,
                "name": "Box découverte",
                "tenant_id": 1,
                "id_category": null,
                "quantity": 250,
                "active": true,
                "description_short": "Trois thés à découvrir",
                "description": "Trois thés à découvrir chaque mois.",
                "slug": "box-decouverte",
                "meta_description": "Box découverte de thés",
                "meta_title": "Box découverte",
                "details": "Sachets de 50 g.",
                "virtual_product": false,
                "salable": true,
                "default_variation": null,
                "created_at": "2026-09-10T08:15:42.000000Z",
                "updated_at": "2026-09-10T08:15:42.000000Z",
                "deleted_at": null,
                "order": 1,
                "rating_cache": 0,
                "rating_count": 0,
                "affilae": null,
                "tax": 0.2,
                "price": "29.900",
                "gift_card": false,
                "gift_plan": null,
                "featured": false,
                "disable_seo": false,
                "old_price": null,
                "exodus_id": "1042",
                "details_json": null,
                "ref": "BOX-DEC-001",
                "features": {
                    "kcal": 0
                },
                "force_shipment": false,
                "composable": false,
                "selectable_quantities": null,
                "metadata": [],
                "customizations": []
            },
            "affilae": null,
            "external_id": "1042",
            "ref": "BOX-DEC-001"
        }
    ],
    "shipping": "4.90",
    "count": 1,
    "total_tax_paid": "5,32",
    "total_discount_inc": "2,99",
    "total_paid": "31,81",
    "total_shipping_paid": "4,90",
    "created_at": "2026-09-10T08:15:42.000000Z",
    "coupon": {
        "id": 1,
        "uuid": "BIENVENUE10",
        "plans": null,
        "price": null,
        "percent_off": "0.10",
        "duration": "once",
        "redeem_by": 1798757999,
        "display_amount": null,
        "display_percent": "10%"
    },
    "subscription_uuid": "sub_N8PxGUEdS2U7DP",
    "revenue": "0.00",
    "refunded": "0.00",
    "customerRevenue": "0.00",
    "customerRefund": "0.00",
    "totalTransactionsSuccess": 0,
    "subTransactionsSuccess": 0,
    "next_billing": "2026-10-10T08:15:42.000000Z",
    "countTransactions": 1,
    "choices": null,
    "retry_link": "https://boutique.example.com/orders/1/users/1?token=tok_iDXOKjsWGKGwc94K0WptRORT",
    "paid_transaction_id": null,
    "paid_class_key": null,
    "prestashop_order_id": 1587,
    "changed": []
}
```

## `updated_checkoutorder`

Delivered object: complete order, in its state at the time of sending. Delay before sending: none. Full example: in the OpenAPI contract (`/openapi/ciklik-webhooks.yaml`), webhook `updated_checkoutorder` (the rest of the delivery content is identical to that of `created_checkoutorder`).

> An `updated` can arrive before the `created`
>
> `created_checkoutorder` is sent with a delay of about 10 seconds and an empty `changed`; `updated_checkoutorder` is sent without delay. An `updated_checkoutorder` can therefore reach your receiving URL before the `created_checkoutorder` of the same order. Process each delivery by `order_id`, never by order of arrival: never assume that a `created` has already been received before acting on an `updated`.

### When it is sent

Change of status (payment confirmation, failure…), of carrier, of shipping costs or of pickup point, or any other field actually modified on the order.

### When it is not sent

Five silent writes to be aware of: transition to `withdrawal_requested` (withdrawal request), return to `completed` after the withdrawal is validated (**Validate the withdrawal** action on the order), linking of the invoice (`invoice_id`), marking of a retry (`source = retry`) and setting of the source at creation. There is also no `deleted_checkoutorder`: an order is never notified as deleted.

### What `changed` contains

The fields actually modified, most often `status`, `next_try`, `total_paid`, `transporter_id`, `shipping`, `shipping_tax` and `relay`, along with `updated_at`. `invoice_id` never appears there in the normal flow: its linking is, as above, silent.

### Cascading effects

- Orders **being created** (`in_creation`) are re-saved once or twice on every change of address or carrier on the linked subscription, or on any address linked to a subscription: `changed` then contains `transporter_id`, `shipping`, `shipping_tax` and `relay`. Details on [Events: subscriptions](https://www.ciklik.academy/en/webhooks/evenements-abonnements/).
- **Pending** orders (`pending`) are set to failed when a subscription is canceled, if the closing option is enabled for your store, and when it is deleted.
- **Pending and being-created** orders are set to failed when the subscription is cancelled from the back office (**Cancel the subscription** action) with the **Close pending orders** option, a broader scope than the automatic closing.

### Example

```json
{
    "status": "completed"
}
```

## `created_checkouttransaction`

Delivered object: complete transaction, with the entire order under the `order` key. Delay before sending: **10 seconds**. Full example: in the OpenAPI contract (`/openapi/ciklik-webhooks.yaml`), webhook `created_checkouttransaction`. This delivery is sent once the transaction is durably recorded, hence the delay.

### When it is sent

On the creation of a payment attempt: checkout, subscription charge.

### When it is not sent

No silent write identified at creation.

### What `changed` contains

Always an empty array.

### Cascading effects

None specific to this delivery.

### Example

```json
{
    "order_id": 1,
    "order": {
        "order_id": 1,
        "user_id": 1,
        "user_uuid": "cus_Qx7hR3eaEowcv1DX",
        "first_name": "Claire",
        "last_name": "Martin",
        "phone": "+33612345678",
        "email": "claire.martin@example.com",
        "status": "pending",
        "created": "2026-09-10T08:15:42.000000Z",
        "items": [
            {
                "id": 1,
                "price": 29.9,
                "tax": "0.200",
                "quantity": 1,
                "name": "Box découverte",
                "type": "App\\Product",
                "orderable": {
                    "id": 1,
                    "name": "Box découverte",
                    "tenant_id": 1,
                    "id_category": null,
                    "quantity": 250,
                    "active": true,
                    "description_short": "Trois thés à découvrir",
                    "description": "Trois thés à découvrir chaque mois.",
                    "slug": "box-decouverte",
                    "meta_description": "Box découverte de thés",
                    "meta_title": "Box découverte",
                    "details": "Sachets de 50 g.",
                    "virtual_product": false,
                    "salable": true,
                    "default_variation": null,
                    "created_at": "2026-09-10T08:15:42.000000Z",
                    "updated_at": "2026-09-10T08:15:42.000000Z",
                    "deleted_at": null,
                    "order": 1,
                    "rating_cache": 0,
                    "rating_count": 0,
                    "affilae": null,
                    "tax": 0.2,
                    "price": "29.900",
                    "gift_card": false,
                    "gift_plan": null,
                    "featured": false,
                    "disable_seo": false,
                    "old_price": null,
                    "exodus_id": "1042",
                    "details_json": null,
                    "ref": "BOX-DEC-001",
                    "features": {
                        "kcal": 0
                    },
                    "force_shipment": false,
                    "composable": false,
                    "selectable_quantities": null,
                    "metadata": [],
                    "customizations": []
                },
                "affilae": null,
                "external_id": "1042",
                "ref": "BOX-DEC-001"
            }
        ],
        "shipping": "4.90",
        "count": 1,
        "total_tax_paid": "5,32",
        "total_discount_inc": "2,99",
        "total_paid": "31,81",
        "total_shipping_paid": "4,90",
        "created_at": "2026-09-10T08:15:42.000000Z",
        "coupon": {
            "id": 1,
            "uuid": "BIENVENUE10",
            "plans": null,
            "price": null,
            "percent_off": "0.10",
            "duration": "once",
            "redeem_by": 1798757999,
            "display_amount": null,
            "display_percent": "10%"
        },
        "subscription_uuid": "sub_N8PxGUEdS2U7DP",
        "revenue": "0.00",
        "refunded": "0.00",
        "customerRevenue": "0.00",
        "customerRefund": "0.00",
        "totalTransactionsSuccess": 0,
        "subTransactionsSuccess": 0,
        "next_billing": "2026-10-10T08:15:42.000000Z",
        "countTransactions": 1,
        "choices": null,
        "retry_link": "https://boutique.example.com/orders/1/users/1?token=tok_iDXOKjsWGKGwc94K0WptRORT",
        "paid_transaction_id": null,
        "paid_class_key": null,
        "prestashop_order_id": 1587
    },
    "gateway": "stripe",
    "transaction_id": "ch_3QxK2mL9aBcDeFgH1a2b3c4d",
    "detail": null,
    "token": null,
    "tenant_id": 1,
    "paid": false,
    "amount": "31.81",
    "refunded": false,
    "source_id": "pm_1QxK2mL9aBcDeFgH",
    "failure_message": null,
    "failure_code": null,
    "invoice_id": null,
    "amount_refunded": "0.00",
    "statement_descriptor": "BOUTIQUE EXEMPLE",
    "user_id": 1,
    "created_at": "2026-09-10T08:15:42.000000Z",
    "updated_at": "2026-09-10T08:15:42.000000Z",
    "payment_intent_id": "pi_3QxK2mL9aBcDeFgH1a2b3c4d",
    "changed": []
}
```

## `updated_checkouttransaction`

Delivered object: complete transaction, with the entire order under the `order` key, in its state at the time of sending. Delay before sending: **10 seconds**. Full example: in the OpenAPI contract (`/openapi/ciklik-webhooks.yaml`), webhook `updated_checkouttransaction` (the rest of the delivery content is identical to that of `created_checkouttransaction`).

### When it is sent

The most frequent case: the transition to paid, which is read in `changed.paid`. Any other modification of the transaction (refund, payment failure) also triggers this delivery.

### When it is not sent

Linking the invoice to the transaction, that is setting `invoice_id`, is a silent write: do not rely on `changed.invoice_id` to know that an invoice has been issued, rely on `created_checkoutinvoice`.

### What `changed` contains

The transition to paid is read in `changed.paid` (`true`). The other fields follow the same principle: raw value as stored in the database.

### Cascading effects

None specific to this delivery.

### Example

```json
{
    "paid": true
}
```

## `created_checkoutinvoice`

Delivered object: complete invoice, with the entire order under the `order` key. Delay before sending: **15 seconds**. Full example: in the OpenAPI contract (`/openapi/ciklik-webhooks.yaml`), webhook `created_checkoutinvoice`.

### When it is sent

Only when an invoice is issued. There is neither `updated_checkoutinvoice` nor `deleted_checkoutinvoice`: once issued, an invoice is never modified in the content you receive.

### When it is not sent

Not applicable: this key has only one trigger, issuance.

### What `changed` contains

Always an empty array: by construction, there is never a second delivery to compare against.

### Cascading effects

None.

### Example

```json
{
    "order_id": 1,
    "customer": {
        "first_name": "Claire",
        "last_name": "Martin",
        "email": "claire.martin-dupont@example.com",
        "address": "27 avenue Jean Jaurès",
        "postcode": "69007",
        "city": "Lyon",
        "country": "France"
    },
    "tenant_id": 1,
    "emitted_at": "2026-09-10T00:00:00.000000Z",
    "company": {
        "name": "Boutique Exemple SAS",
        "address": "5 place Bellecour",
        "postcode": "69002",
        "city": "Lyon",
        "siret": "12345678900012",
        "vat": "FR12345678900"
    },
    "number": 42,
    "total_tax": "5.320",
    "total_discount": "2.990",
    "total": "31.810",
    "total_shipping": "4.900",
    "more": null,
    "uuid": "F2026-09-42",
    "order": {
        "order_id": 1,
        "user_id": 1,
        "user_uuid": "cus_Qx7hR3eaEowcv1DX",
        "first_name": "Claire",
        "last_name": "Martin",
        "phone": "+33612345678",
        "email": "claire.martin-dupont@example.com",
        "status": "completed",
        "created": "2026-09-10T08:15:42.000000Z",
        "items": [
            {
                "id": 1,
                "price": 29.9,
                "tax": "0.200",
                "quantity": 1,
                "name": "Box découverte",
                "type": "App\\Product",
                "orderable": {
                    "id": 1,
                    "name": "Box découverte",
                    "tenant_id": 1,
                    "id_category": null,
                    "quantity": 250,
                    "active": true,
                    "description_short": "Trois thés à découvrir",
                    "description": "Trois thés à découvrir chaque mois.",
                    "slug": "box-decouverte",
                    "meta_description": "Box découverte de thés",
                    "meta_title": "Box découverte",
                    "details": "Sachets de 50 g.",
                    "virtual_product": false,
                    "salable": true,
                    "default_variation": null,
                    "created_at": "2026-09-10T08:15:42.000000Z",
                    "updated_at": "2026-09-10T08:15:42.000000Z",
                    "deleted_at": null,
                    "order": 1,
                    "rating_cache": 0,
                    "rating_count": 0,
                    "affilae": null,
                    "tax": 0.2,
                    "price": "29.900",
                    "gift_card": false,
                    "gift_plan": null,
                    "featured": false,
                    "disable_seo": false,
                    "old_price": null,
                    "exodus_id": "1042",
                    "details_json": null,
                    "ref": "BOX-DEC-001",
                    "features": {
                        "kcal": 0
                    },
                    "force_shipment": false,
                    "composable": false,
                    "selectable_quantities": null,
                    "metadata": [],
                    "customizations": []
                },
                "affilae": null,
                "external_id": "1042",
                "ref": "BOX-DEC-001"
            }
        ],
        "shipping": "4.90",
        "count": 1,
        "total_tax_paid": "5,32",
        "total_discount_inc": "2,99",
        "total_paid": "31,81",
        "total_shipping_paid": "4,90",
        "created_at": "2026-09-10T08:15:42.000000Z",
        "coupon": {
            "id": 1,
            "uuid": "BIENVENUE10",
            "plans": null,
            "price": null,
            "percent_off": "0.10",
            "duration": "once",
            "redeem_by": 1798757999,
            "display_amount": null,
            "display_percent": "10%"
        },
        "subscription_uuid": "sub_N8PxGUEdS2U7DP",
        "revenue": "31.81",
        "refunded": "0.00",
        "customerRevenue": "31.81",
        "customerRefund": "0.00",
        "totalTransactionsSuccess": 1,
        "subTransactionsSuccess": 1,
        "next_billing": "2026-10-10T08:15:42.000000Z",
        "countTransactions": 1,
        "choices": null,
        "retry_link": "https://boutique.example.com/orders/1/users/1?token=tok_iDXOKjsWGKGwc94K0WptRORT",
        "paid_transaction_id": "ch_3QxK2mL9aBcDeFgH1a2b3c4d",
        "paid_class_key": "stripe",
        "prestashop_order_id": 1587
    },
    "gateway": "stripe",
    "changed": []
}
```

## See also

[Understanding a webhook delivery](https://www.ciklik.academy/en/webhooks/comprendre-un-envoi-de-webhook/)

[Events: subscriptions](https://www.ciklik.academy/en/webhooks/evenements-abonnements/)

[Payment links](https://www.ciklik.academy/en/paiements/les-liens-de-paiement/)
