Skip to content

Events: orders, transactions and invoices

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.

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

FieldTypeNullableDescription
order_id, user_idintegernoInternal identifiers.
user_uuidstringnoPublic customer identifier (cus_...).
email, first_name, last_name, phonestringyes, except emailContact details, read from the order address.
statusstringnoSee the status table below.
created, created_atISO 8601 datenoCreation date, always in UTC.
itemsarraynoLines, see Order line object.
couponobject or empty arraynoSee Coupon object: the type changes depending on whether a coupon is applied or not.
shippingstringnoShipping costs, decimal point ("4.90").
countintegernoNumber of lines.
total_tax_paid, total_discount_inc, total_shipping_paidstringnoTotals, decimal comma ("31,81").
total_paidstringyesTotal paid, decimal comma; null until computed.
subscription_uuidstringyesOriginating subscription, if any.
revenue, refundedstringyesSubscription-related revenue and refunded amount, decimal point; null without a subscription.
customerRevenue, customerRefundstringnoCustomer-side revenue and refunded amount, decimal point; "0.00" without a subscription, never null.
subTransactionsSuccessintegeryesNumber of successful transactions of the linked subscription, across all its orders; null without a subscription.
totalTransactionsSuccessintegernoNumber of successful transactions of the customer, across all subscriptions; never null.
countTransactionsintegernoNumber of transactions of this order; never null.
next_billingISO 8601 dateyesNext due date of the originating subscription.
choices(always null)yesAlways null, reserved field.
retry_linkstringyesPayment retry link; null without a customer secret.
paid_transaction_id, paid_class_keystringyesIdentifier and payment method of the paid transaction.
prestashop_order_idintegeryesIdentifier on the PrestaShop side.

status takes one of eight values:

StatusMeaning
pendingAwaiting payment.
in_creationBeing created: address or carrier not yet finalized.
in_processBeing processed.
completedPaid.
failedFailed.
canceledCanceled.
need_actionAn action from the customer is required to complete the payment.
withdrawal_requestedA withdrawal request is in progress.

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

FieldTypeNullableDescription
idintegernoLine identifier.
pricenumbernoUnit price excluding tax.
taxstringnoVAT rate, decimal as a string ("0.200").
quantityintegernoOrdered quantity.
namestringnoName of the product or plan at the time of the order.
typestringnoType of the sold product: plan or product (technical value).
orderableobject or nullyesSee the note below; null if the product has been deleted since.
affilae, external_id, refstringyesAffiliate tracking, external identifier, product reference.

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.

FieldTypeNullableDescription
id, uuidinteger, stringnoInternal identifier and code entered by the customer.
plans(always null)yesJSON column that is no longer populated.
price, percent_offstringyesFixed discount, or percentage discount expressed as a fraction ("0.10" for 10%).
durationstringnoScope of the discount (once, repeating, forever on older coupons).
redeem_byintegernoRedemption deadline, Unix timestamp.
display_amount, display_percentstringyesAmount or percentage formatted for display.

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

FieldTypeNullableDescription
order_id, tenant_idintegernoAssociated order and store.
orderobject or nullyesComplete order, see Order object; null if deleted.
gatewaystringnoPayment method (stripe…).
transaction_id, token, detail, source_id, payment_intent_idfree-formyesRaw identifiers and details, depending on the provider.
paidbooleannoTrue once the payment is confirmed.
amount, amount_refundedstringnoAmounts, two decimals.
refundedbooleannoTrue if the transaction has been refunded.
failure_message, failure_codestringyesDetails of a payment failure.
invoice_idintegeryesLinked invoice; never appears in changed, see below.
statement_descriptorstringyesLabel shown on the customer’s bank statement.
user_idintegeryesCustomer, when set.
created_at, updated_atISO 8601 datenoTimestamps.

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

FieldTypeNullableDescription
order_id, tenant_idintegernoOriginating order and store concerned.
customer, companyobject or nullyesSee the note below, non-contractual structure.
emitted_atdatenoIssue date, at midnight UTC (T00:00:00.000000Z).
numberintegernoInvoice number, specific to your store.
total_tax, total_discount, total, total_shippingstringnoAmounts with three decimals, decimal point ("5.320").
morestringyesAdditional mention.
uuidstringnoFull number: prefix, year-month and number (F2026-09-42).
orderobject or nullyesComplete order, see Order object.
gatewaystringyesPayment method of the paid transaction; null without a paid transaction.

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

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

No silent write identified at creation.

Always an empty array.

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

created_checkoutorder
{
"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": []
}

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).

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

Five silent writes to be aware of: transition to withdrawal_requested (withdrawal request), return to completed after a withdrawal is validated by the Ciklik team, 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.

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.

  • 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.
  • 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 Ciklik team pauses the subscription with order closing, a broader scope than cancellation.
changed of updated_checkoutorder
{
"status": "completed"
}

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.

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

No silent write identified at creation.

Always an empty array.

None specific to this delivery.

created_checkouttransaction
{
"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": []
}

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).

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.

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.

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

None specific to this delivery.

changed of updated_checkouttransaction
{
"paid": true
}

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.

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.

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

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

None.

created_checkoutinvoice
{
"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": []
}