---
schema_version: "1"
id: 436854b0d7b537618257d44afb00997a07ca1e8c46937b60f8244568eb2525f4
title: Order Post-Processing Events in the UCP Order Lifecycle
collection: developer
version: current
locale: en-us
portal_url: https://docs.salesforce.com/developer/current/en-us/commerce-cloud/b2c-commerce/guides/ucp/ucp-order-post-processing-events.md
canonical_url: https://developer.salesforce.com/docs/commerce/pwa-kit-managed-runtime/guide/ucp-order-post-processing-events.html
source_site: developer.salesforce.com
content_type: documentation
content_hash: 4b42355c074d80179d7c88a488d5370e12dffb774a5a8bccd2e4e58a2c5a832f
products:
  - Composable Storefront
  - Salesforce APIs
---
# Order Post-Processing Events in the UCP Order Lifecycle

An **agentic-commerce channel** is an AI assistant such as Google Gemini that transacts through the **Universal Commerce Protocol (UCP)**. When a shopper places an order through that channel, the agent platform keeps its own current-state copy of the order, which it can surface to the shopper. To keep that copy accurate after checkout, B2C Commerce must tell the agent platform whenever the order changes.

Most changes happen **after the purchase**, in your **Order Management System (OMS)**: the order is shipped, delivered, cancelled, or returned. This guide explains how those **order post-processing events drive UCP order-lifecycle updates**—how a shipment, cancellation, or return becomes a fresh, **full-order snapshot**—carrying a cryptographic signature—delivered to the agent platform so the shopper always sees an up-to-date order.

How those events *reach* B2C Commerce depends on which OMS manages the order. There are two models:

- **[Salesforce Order Management](https://help.salesforce.com/s/articleView?id=commerce.om_impl_self_provision.htm&type=5)** (Salesforce OMS)—updates are detected and forwarded **automatically**. You do nothing beyond your normal order operations.
- **[A third-party OMS](https://developer.salesforce.com/docs/commerce/pwa-kit-managed-runtime/commerce-apps/connect-third-party-oms.md)**—your OMS **posts** each event to a dedicated B2C Commerce API.

Whichever model you use, the outcome is identical: a full-order snapshot carrying a cryptographic signature, delivered asynchronously to the agent platform.

**note:** **Applies to UCP orders.** These updates are sent only for orders that originated on an agentic-commerce (UCP) channel. Orders on other channels are unaffected.

## Key Concept: Every Update Is a Full-Order Snapshot

UCP requires each update to be a **complete, current-state snapshot of the order**—not an incremental delta. So for every post-processing event, B2C Commerce **re-fetches the whole order**, **attaches the new entry**, and **sends the entire order** to the agent platform.

Two kinds of entry can be attached, and the agent surface renders them differently:

| Entry kind            | Where it lives          | Represents                  | Example event types                                                          |
| --------------------- | ----------------------- | --------------------------- | ---------------------------------------------------------------------------- |
| **Fulfillment event** | `fulfillment.events[]` | A delivery-state progression | `processing`, `shipped`, `in_transit`, `delivered`, `canceled`               |
| **Adjustment**        | `adjustments[]`         | A money movement            | `cancellation`, `return`, `refund`, `credit`                                 |

Both are **append-only logs**: each event adds an entry; earlier entries are never removed. The `fulfillment` object is always present on every snapshot.

**note:** **Values on adjustments carry a sign (+/−).** For a cancellation, return, or refund, the money returned to the buyer and the units removed are **negative**—`totals[].amount` and `line_items[].quantity` are negative. Fulfillment-event quantities are always **non-negative** (goods delivered *to* the buyer). The sign (+/−) is **intrinsic to the value**, not something the reader derives from the `type`.

## What the Platform Does vs. What You Do

| Concern                                                                                                                          | Salesforce OMS                                                                 | Third-party OMS                                                                                                                                                              |
| -------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Detect that a UCP order was shipped / cancelled / returned                                                                       | **Platform** (automatic)                                                       | **You** (via SCAPI)                                                                                                                                                          |
| Decide the event's type, values, and sign (+/−) convention                                                                       | **Platform** (derives them from the operation)                                 | **You** (via SCAPI)                                                                                                                                                          |
| Re-fetch the full, current order—this becomes the snapshot                                                                       | **Platform** (from Salesforce OMS)                                             | **Platform** (via your retrieval hook)                                                                                                                                       |
| Build the UCP entry and attach it to that snapshot                                                                               | **Platform**                                                                   | **Shared**—you supply the event's content and signs (+/−) via SCAPI; the platform validates, maps them to the UCP entry, and appends it to the snapshot                      |
| Deliver a full-order snapshot with a cryptographic signature to the agent platform                                               | **Platform**                                                                   | **Platform**                                                                                                                                                                 |
| Retry-free, asynchronous delivery that never blocks order operations                                                             | **Platform**                                                                   | **Platform**                                                                                                                                                                 |
| **Fulfillment operations** (ship, mark delivered, …) that produce fulfillment events                                             | **You** (fulfillment / operations)                                             | **You** (fulfillment / operations)                                                                                                                                           |
| **Adjustment actions** (cancel, return, refund) that produce adjustments—may be initiated by the **shopper**, a service rep, or your operations | **You, service rep, or shopper**                                              | **You, service rep, or shopper**                                                                                                                                            |

## Model A — Salesforce OMS (Automatic)

When your UCP orders are managed in **Salesforce OMS**, there is **nothing to build or configure** for these updates. As you ship, cancel, and process returns in Salesforce OMS, B2C Commerce detects each change and forwards it to the agent platform automatically.

The event kind and sign (+/−) are **derived from the order-management operation**:

| Order Management operation                         | UCP entry                                              | Sign (+/−)                          |
| -------------------------------------------------- | ------------------------------------------------------ | ----------------------------------- |
| An order (or part of it) **ships**                 | `shipped` fulfillment event on `fulfillment.events[]` | Quantities **positive**             |
| Units are **canceled**                            | `cancellation` adjustment on `adjustments[]`           | Quantities and amount **negative**  |
| Units are **returned** (or a return is initiated)  | `return` adjustment on `adjustments[]`                 | Quantities and amount **negative**  |

Notes on behavior:

- **The initiator doesn't matter.** A cancellation or return may be initiated by the **shopper** (self-service through the storefront or the agent platform), a service rep, or your operations team. In every case the resulting Salesforce OMS state change is what drives the UCP update—it is detected and forwarded automatically.
- **The platform fills in the details.** Timestamps come straight from the Order Management event, and cancellations and returns are reported as settled (completed) money movements—you don't author any of this.
- **Each action produces its own update.** When an order ships, you get a shipment update; when it is canceled or returned, you get an adjustment update. So a shipment and a cancellation on the same order arrive as two updates. But when several line items change together in one action—for example, a fulfillment that ships multiple items at once—that is a single update for the order, not one per line item. An order shipped in several parts produces one shipment update per part; because every update carries the full order, the fulfillment events accumulate in the log.

### Example — Shipment (Salesforce OMS)

A fulfillment ships two of the order's lines together. Even though multiple items ship, this is one action, so it produces a **single** UCP update—one `shipped` event listing all the shipped line items:

```json
{
  "fulfillment": {
    "events": [
      {
        "type": "shipped",
        "occurred_at": "2026-01-15T10:30:00Z",
        "line_items": [
          { "id": "10uVF0000002fn4YAA", "quantity": 1 },
          { "id": "10uVF0000002fn5ZBB", "quantity": 2 }
        ]
      }
    ]
  }
}
```

This shipment ships three units across two lines but arrives as one webhook—not three, and not one per line.

### Example — Return / Refund (Salesforce OMS)

Two lines are returned together—one unit at $30.00 and two units at $20.00 each—for a $70.00 refund. As with the shipment, this is one action, so it produces a **single** UCP update—one `return` adjustment listing all the returned lines:

```json
{
  "id": "adj_return_10uVF0000002fn4YAA",
  "type": "return",
  "occurred_at": "2026-01-15T10:30:00Z",
  "status": "completed",
  "line_items": [
    { "id": "10uVF0000002fn4YAA", "quantity": -1 },
    { "id": "10uVF0000002fn5ZBB", "quantity": -2 }
  ],
  "totals": [
    { "type": "total", "amount": -7000 }
  ]
}
```

Note the negative `amount` (`-7000`, that is, −$70.00 in cents) and negative quantities—money and units flowing back to the shopper. Both returned lines arrive as one webhook, not one per line. A **cancellation** looks the same with `"type": "cancellation"`.

## Model B — Third-Party OMS (the OMS Status Events API)

When your UCP orders are managed by a **third-party OMS**, B2C Commerce can't observe your OMS's internal changes. Instead, your OMS calls a dedicated API to **notify** B2C Commerce of each post-processing event. B2C Commerce then reassembles the current order (through your OMS retrieval integration), attaches the event you posted, and delivers the snapshot—carrying a cryptographic signature—to the agent platform.

Unlike the Salesforce OMS model—where B2C Commerce *derives* the event—**your OMS supplies the fully-formed event**: its type, timestamp, affected line items, tracking, totals, and signs (+/−).

**note:** **Your OMS must post every event, whatever initiated it.** A cancellation or return may be initiated by the shopper (self-service through the storefront or the agent platform), a service rep, or your operations. When a shopper cancels or returns through B2C Commerce, the platform runs your **cancel or return order hook** against your OMS—but that hook only executes the operation; it does **not** by itself notify the agent platform. Your OMS is responsible for posting the corresponding adjustment to this API so the UCP snapshot is updated.

### How to Post Events

The API, its authorization, request schema, response codes, and sample request bodies are documented in **[Connect a Third-Party Order Management System (OMS)](https://developer.salesforce.com/docs/commerce/pwa-kit-managed-runtime/commerce-apps/connect-third-party-oms.md#push-status-updates-to-the-platform)**, under *Push Status Updates to the Platform*, with the endpoint reference at **[`createOmsStatusEvent`](https://developer.salesforce.com/docs/commerce/commerce-api/references/orders?meta=createOmsStatusEvent)**. That guide is the authoritative reference for the endpoint; this page doesn't repeat it.

The essentials, for orientation:

- You `POST` **exactly one** `fulfillmentEvent` **or** `adjustment` per call to `oms-status-events`.
- A `fulfillmentEvent` becomes an entry in `fulfillment.events[]`; an `adjustment` becomes an entry in `adjustments[]`.
- **You author the whole event**—its type, timestamp, affected line items, tracking, totals, and **signs (+/−)**. Follow the sign (+/−) convention: quantities and amounts flowing back to the buyer are **negative**; fulfillment quantities are **non-negative**. This is the one place the platform can't derive intent for you, so the correctness of the UCP snapshot depends on the values you send.
- The endpoint is available only when your third-party OMS integration is **active for the site** (feature enabled and all order hooks registered); otherwise it returns **`409 Conflict`**.

**note:** **Inbound API vs UCP snapshot field names.** The `oms-status-events` request body uses camelCase (`occurredAt`, `lineItems`). The signed UCP snapshot uses snake_case (`occurred_at`, `line_items`). Don't copy one shape into the other.

### From Your API Call to the UCP Snapshot

What is specific to *this* topic—and not covered by the OMS connection guide—is what B2C Commerce does with the event after it accepts it:

1. It **reassembles the current order** by calling your OMS `retrieve` hook (the same hook used for order look-ups), so the snapshot reflects your OMS's live state.
2. It **appends the event you posted**—the `fulfillmentEvent` to `fulfillment.events[]`, the `adjustment` to `adjustments[]`. Entries your retrieval hook already returns are preserved.
3. It **applies the cryptographic signature and delivers** the full-order snapshot to the agent platform—the same signature-protected payload the Salesforce OMS model produces.

Because the reassembly runs through your retrieval hook, the snapshot is only as current as what that hook returns; the posted event is layered on top of it.

## What Arrives at the Agent Platform

Every update is one delivery containing the **full order**, with:

- the always-present **`fulfillment`** object (including any `events[]` such as `shipped`), and
- the **`adjustments[]`** log (any cancellations, returns, or refunds to date).

Delivery is:

- **Signature-protected**—each webhook carries a cryptographic signature (HTTP Message Signatures, RFC 9421) so the agent platform can verify it came from B2C Commerce. Saving UCP settings in Business Manager generates the signing keys advertised on the [business profile](https://developer.salesforce.com/docs/commerce/pwa-kit-managed-runtime/guide/ucp-configuration.md#security).
- **Asynchronous**—sending happens off to the side and never blocks or slows your order operations.

To mutate the payload immediately before signed delivery, implement `sfcc.ucp.orderWebhook.v1.modifyEventPayload`. If that hook fails or returns a non-OK status, the webhook is retried. See [Business Profile and Order Webhooks](https://developer.salesforce.com/docs/commerce/pwa-kit-managed-runtime/guide/ucp-implementation-considerations.md#business-profile-and-order-webhooks).

## Related Reading

- [Configuration and Discovery](https://developer.salesforce.com/docs/commerce/pwa-kit-managed-runtime/guide/ucp-configuration.md)—Business Manager UCP settings, OMS options, and signing keys
- [Implementation Considerations](https://developer.salesforce.com/docs/commerce/pwa-kit-managed-runtime/guide/ucp-implementation-considerations.md#business-profile-and-order-webhooks)—order webhook hook, including `modifyEventPayload`
- [Connect a Third-Party Order Management System (OMS)](https://developer.salesforce.com/docs/commerce/pwa-kit-managed-runtime/commerce-apps/connect-third-party-oms.md)—building and registering the order hooks the third-party model depends on, and the `oms-status-events` API
- [UCP order specification](https://ucp.dev/latest/specification/order/)
