# Order events for Stripe Agentic Commerce Suite Learn how order events are synchronized from commercetools to Stripe after checkout. After checkout, order status changes in commercetools are synchronized to Stripe as order events. Stripe surfaces order data to agent experiences, including those powered by Google. These updates ensure buyers see accurate order statuses within the agent interface. This page describes outbound status synchronization from commercetools to Stripe. For inbound order creation from Stripe to commercetools, see [Order import for Stripe Agentic Commerce Suite](/agentic-commerce/ai-hub/stripe/order-import.md). ## Event and status mapping Supported state changes from commercetools Messages are mapped to Stripe order event payloads. ### Fulfillment events In the Stripe payload, `type` is the top-level event category. A value of `fulfillment` means the event reports fulfillment progress for an Order, and the payload includes a `fulfillment` object. The following state changes produce a `type: "fulfillment"` event: | commercetools trigger message | State or status value | Stripe status | | --- | --- | --- | | `OrderStateChanged` | `Open` | `pending` | | `OrderStateChanged` | `Confirmed` | `confirmed` | | `OrderShipmentStateChanged` | `Shipped` | `shipped` | | `OrderShipmentStateChanged` | `Delivered` | `delivered` | ### Adjustment events In the Stripe payload, `type: "adjustment"` means the event reports a post-checkout order adjustment, and the payload includes an `adjustment` object. The following state changes produce a `type: "adjustment"` event: | commercetools trigger message | State or status value | Stripe adjustment type | | --- | --- | --- | | `OrderStateChanged` | `Cancelled` | `cancellation` | If a message type or status is not listed in these tables, the message is ignored and logged as skipped. ## Data extraction and fallback logic A fixed extraction order is applied to build each Stripe event payload. ### Order identification - **Primary field**: `custom.fields.stripeOrderId` on the commercetools Order. - **Fallback**: none. If `custom.fields.stripeOrderId` is missing or is not a string, processing is aborted for that message. ### Line item mapping Stripe requires `line_items` for every event. Standard Line Items and Custom Line Items are merged into this array. | Stripe field | Source field | Mapping logic | | --- | --- | --- | | `line_items[].id` | Standard Line Item | Maps to `variant.sku`. | | `line_items[].id` | Custom Line Item | Maps to the Custom Line Item `key`. | | `line_items[].quantity` | `quantity` | Uses the Order line item quantity directly. | ### Tracking information precedence For `confirmed`, `shipped`, and `delivered` events, tracking data is read from the first Delivery in `shippingInfo.deliveries[0]`. | Stripe field | Precedence and fallback | | --- | --- | | `carrier` | Uses `parcels[0].trackingData.carrier`. If unavailable, falls back to `delivery.custom.fields.carrier`, then to `""`. | | `tracking_number` | Uses `parcels[0].trackingData.trackingId`. If unavailable, falls back to `""`. | | `tracking_url` | Uses `delivery.custom.fields.tracking_url`. If unavailable, falls back to `""`. | ### Timestamps The following timestamp fields are sent to Stripe in the outbound event payload, generated from commercetools Message data: - `occurred_at` always uses the commercetools Message `createdAt` timestamp. - For `shipped`, `shipped_at` uses the same Message `createdAt` timestamp. - For `delivered`, `delivered_at` uses the same Message `createdAt` timestamp. ## Technical constraints ### Idempotency The `idempotency_key` is set to the commercetools Message `id`. If a message is retried, Stripe receives the same key so duplicate events are not created. ### Store scoping The `order.store.key` value is validated against the configured `ctpStoreKey`. If values do not match, the message is ignored to prevent cross-store updates. ### Fresh state validation For each message, a Get Order request is performed before generating the Stripe payload. This ensures the latest Order state is used. ## Stripe API request format - **Endpoint**: `POST /v2/delegated_commerce/orders/:stripeOrderId/order_events` ### Payload shape Each event contains either a `fulfillment` object or an `adjustment` object, depending on the value of the top-level `type` field. The two objects are never present in the same payload. A `fulfillment` event uses the following shape: ```json title="Fulfillment event payload" { "type": "fulfillment", "occurred_at": "2026-06-17T10:30:00.000Z", "idempotency_key": "ctp-message-id", "fulfillment": { "status": "pending | confirmed | shipped | delivered", "line_items": [ { "id": "SKU-123", "quantity": 1 } ], "tracking_number": "1Z999", "carrier": "Carrier Name", "tracking_url": "https://example.com/track/1Z999", "shipped_at": "2026-06-17T10:30:00.000Z", "delivered_at": "2026-06-18T16:40:00.000Z" } } ``` An `adjustment` event uses the following shape: ```json title="Adjustment event payload" { "type": "adjustment", "occurred_at": "2026-06-17T10:30:00.000Z", "idempotency_key": "ctp-message-id", "adjustment": { "type": "cancellation", "status": "completed", "description": "Order cancelled", "line_items": [ { "id": "SKU-123", "quantity": 1 } ] } } ``` ## Related pages - [Area overview page with navigation](/agentic-commerce.md) - [Previous page: Order import](/agentic-commerce/ai-hub/stripe/order-import.md)