This guide provides the technical API reference and payload schemas for pushing
full order status updates, fulfillment events, and adjustments to Google using
webhooks for version 2026-01-23 of the Universal Commerce Protocol
(UCP).
Before building your endpoints, ensure you have reviewed the Order lifecycle overview for the high-level concepts, mandatory events, and webhook endpoint details.
Auth and request signing
You can do symmetric key signing using an HMAC key shared by Google with you.
OR you can refer to the following instructions for an asymmetric signature:
- Select a key from the
signing_keysarray in the UCP profile. - Create a detached JWT (RFC 7797) over the request body using the selected key.
- Include the JWT in the
Request-Signatureheader. - Include the key ID in the JWT header's
kidclaim to allow the receiver to identify which key to use for verification.
Timestamp validation
When evaluating whether an order update is older than the latest recorded update
(which causes an order update rejection), Google evaluates the timestamp using
the created_time property in the payload.
Order created event
- Trigger: Immediately after the order is confirmed (
status: processing).
Example: This example shows an order created after a buyer completes the checkout.
{
"ucp": {
"version": "2026-01-23",
"capabilities": {
"dev.ucp.shopping.order": [{"version": "2026-01-23"}]
}
},
"id": "order_01",
"checkout_id": "checkout_01",
"created_time": "2026-03-23T19:00:00Z",
// Full line items must be included
"line_items": [
{
"id": "line_1",
"item":
{
"id": "product_123",
"title": "Running Shoes",
"price": 10000
},
"quantity": { "total": 1, "fulfilled": 0 },
"totals": [
{"type": "subtotal", "amount": 10000},
{"type": "total", "amount": 10000}
],
// The status of a line item must match total and fulfilled quantities (e.g., total 1, fulfilled 0 -> status: processing).
"status": "processing"
}
],
"totals": [
{"type": "subtotal", "amount": 10000},
{"type": "total", "amount": 10000}
],
"fulfillment": {
"expectations": [
{
"id": "exp_1",
"line_items": [{ "id": "line_1", "quantity": 1 }],
"method_type": "shipping",
"destination": {
"first_name": "Alice",
"last_name": "Example",
"street_address": "123 Main St",
"address_locality": "Austin",
"address_region": "TX",
"address_country": "US",
"postal_code": "78701"
},
"description": "Arrives in 2-3 business days",
"fulfillable_on": "now"
}
]
},
"permalink_url": "https://merchant.example.com/orders/789"
}
Fulfillment events
These events are sent as part of the fulfillment.events array.
Order shipped
When items in the order have been shipped. The tracking_number and
tracking_url fields are required for shipped events, as these are required to
group items on the "My orders" page accurately.
Order delivered
When items in the order have been delivered.
Example (shipped and delivered): This example shows an order update
after the item has been shipped and then delivered.
{
"ucp": {
"version": "2026-01-23",
"capabilities": {
"dev.ucp.shopping.order": [{"version": "2026-01-23"}]
}
},
"id": "order_01",
"checkout_id": "checkout_01",
"created_time": "2026-03-23T19:00:00Z",
"line_items": [
{
"id": "line_1",
"item":
{
"id": "product_123",
"title": "Running Shoes",
"price": 10000
},
"quantity": { "total": 1, "fulfilled": 1 },
"totals": [
{"type": "subtotal", "amount": 10000},
{"type": "total", "amount": 10000}
],
"status": "fulfilled"
}
],
"totals": [
{"type": "subtotal", "amount": 10000},
{"type": "total", "amount": 10000}
],
// Updated fulfillment details.
"fulfillment": {
"events": [
{
"id": "fulfill_evt_1",
"occurred_at": "2026-02-08T10:30:00Z",
"type": "shipped",
"line_items": [{ "id": "line_1", "quantity": 1 }],
"tracking_number": "123456789",
"tracking_url": "https://fedex.com/track/123456789",
"carrier": "FedEx",
"description": "Shipping departed from warehouse"
},
{
"id": "fulfill_evt_2",
"occurred_at": "2026-02-10T14:00:00Z",
"type": "delivered",
"line_items": [{ "id": "line_1", "quantity": 1 }],
"tracking_number": "123456789",
"tracking_url": "https://fedex.com/track/123456789",
"carrier": "FedEx",
"description": "Package delivered"
}
],
"expectations": [{ "...": "..." }]
},
"permalink_url": "https://merchant.example.com/orders/123"
}
Multi-item order examples
The following examples demonstrate how to structure updates for multi-item orders and split shipments. For rules on how package statuses are derived, see How package status is determined.
Multi-item order, same package delivery
This example shows an order update for a single package containing multiple
items. All line items are grouped within a single shipped event sharing the
same tracking number.
{
"ucp": {
"version": "2026-01-23",
"capabilities": {
"dev.ucp.shopping.order": [{"version": "2026-01-23"}]
}
},
"id": "order_multi_01",
"checkout_id": "checkout_multi_01",
"created_time": "2026-02-07T09:00:00Z",
"line_items": [
{
"id": "line_1",
"item": { "id": "product_1", "title": "Item 1", "price": 5000 },
"quantity": { "total": 1, "fulfilled": 1 },
"totals": [
{"type": "subtotal", "amount": 5000},
{"type": "total", "amount": 5000}
],
"status": "fulfilled"
},
{
"id": "line_2",
"item": { "id": "product_2", "title": "Item 2", "price": 5000 },
"quantity": { "total": 1, "fulfilled": 1 },
"totals": [
{"type": "subtotal", "amount": 5000},
{"type": "total", "amount": 5000}
],
"status": "fulfilled"
}
],
"totals": [
{"type": "subtotal", "amount": 10000},
{"type": "fee", "amount": 500},
{"type": "total", "amount": 10500}
],
"fulfillment": {
"expectations": [
{
"id": "exp_1",
"line_items": [
{ "id": "line_1", "quantity": 1 },
{ "id": "line_2", "quantity": 1 }
],
"method_type": "shipping",
"destination": {
"first_name": "Alice",
"last_name": "Example",
"street_address": "123 Main St",
"address_locality": "Austin",
"address_region": "TX",
"address_country": "US",
"postal_code": "78701"
},
"description": "Standard Shipping",
"fulfillable_on": "now"
}
],
"events": [
{
"id": "fulfill_evt_1",
"occurred_at": "2026-02-08T10:30:00Z",
"type": "shipped",
"line_items": [
{ "id": "line_1", "quantity": 1 },
{ "id": "line_2", "quantity": 1 }
],
"tracking_number": "123456789",
"tracking_url": "https://fedex.com/track/123456789",
"carrier": "FedEx",
"description": "Both items shipped together"
}
]
},
"permalink_url": "https://merchant.example.com/orders/456"
}
Multi-item order, split shipment
This example shows an order update for split shipments. There are multiple
shipped events, each referencing the specific line_items within that
respective package, with distinct tracking numbers. Since each package
represents a distinct fulfillment commitment (e.g., different speeds and costs
from a multi-group checkout), the expectations are also split.
{
"ucp": {
"version": "2026-01-23",
"capabilities": {
"dev.ucp.shopping.order": [{"version": "2026-01-23"}]
}
},
"id": "order_multi_02",
"checkout_id": "checkout_multi_02",
"created_time": "2026-02-07T09:00:00Z",
"line_items": [
{
"id": "line_1",
"item": { "id": "product_1", "title": "Item 1", "price": 5000 },
"quantity": { "total": 1, "fulfilled": 1 },
"totals": [
{"type": "subtotal", "amount": 5000},
{"type": "total", "amount": 5000}
],
"status": "fulfilled"
},
{
"id": "line_2",
"item": { "id": "product_2", "title": "Item 2", "price": 5000 },
"quantity": { "total": 1, "fulfilled": 1 },
"totals": [
{"type": "subtotal", "amount": 5000},
{"type": "total", "amount": 5000}
],
"status": "fulfilled"
}
],
"totals": [
{"type": "subtotal", "amount": 10000},
{"type": "fee", "amount": 1500},
{"type": "total", "amount": 11500}
],
"fulfillment": {
"expectations": [
{
"id": "exp_1",
"line_items": [{ "id": "line_1", "quantity": 1 }],
"method_type": "shipping",
"destination": {
"first_name": "Alice",
"last_name": "Example",
"street_address": "123 Main St",
"address_locality": "Austin",
"address_region": "TX",
"address_country": "US",
"postal_code": "78701"
},
"description": "Standard Shipping",
"fulfillable_on": "now"
},
{
"id": "exp_2",
"line_items": [{ "id": "line_2", "quantity": 1 }],
"method_type": "shipping",
"destination": {
"first_name": "Alice",
"last_name": "Example",
"street_address": "123 Main St",
"address_locality": "Austin",
"address_region": "TX",
"address_country": "US",
"postal_code": "78701"
},
"description": "Express Shipping",
"fulfillable_on": "now"
}
],
"events": [
{
"id": "fulfill_evt_1",
"occurred_at": "2026-02-08T10:30:00Z",
"type": "shipped",
"line_items": [{ "id": "line_1", "quantity": 1 }],
"tracking_number": "PKG1_TRACKING",
"tracking_url": "https://fedex.com/track/PKG1_TRACKING",
"carrier": "FedEx",
"description": "First item shipped in package 1"
},
{
"id": "fulfill_evt_2",
"occurred_at": "2026-02-09T14:00:00Z",
"type": "shipped",
"line_items": [{ "id": "line_2", "quantity": 1 }],
"tracking_number": "PKG2_TRACKING",
"tracking_url": "https://fedex.com/track/PKG2_TRACKING",
"carrier": "FedEx",
"description": "Second item shipped in package 2"
}
]
},
"permalink_url": "https://merchant.example.com/orders/457"
}
Adjustment event examples
The following examples demonstrate how to structure updates for refunds, returns, and cancellations. For a list of supported events and their definitions, see Adjustment events in the Order lifecycle overview.
Order cancellation and refund
This example shows an order where the item was canceled and refunded shortly after the order was placed.
{
"ucp": {
"version": "2026-01-23",
"capabilities": {
"dev.ucp.shopping.order": [{"version": "2026-01-23"}]
}
},
"id": "order_02",
"checkout_id": "checkout_02",
"created_time": "2026-03-23T19:00:00Z",
"line_items": [
{
"id": "line_2",
"item": {
"id": "product_456",
"title": "Smart Watch",
"price": 29900
},
"quantity": { "total": 1, "fulfilled": 0 },
"totals": [
{"type": "subtotal", "amount": 29900},
{"type": "tax", "amount": 2400},
{"type": "total", "amount": 32300}
],
"status": "processing"
}
],
"totals": [
{"type": "subtotal", "amount": 29900},
{"type": "tax", "amount": 2400},
{"type": "total", "amount": 32300}
],
"adjustments": [
{
"id": "adj_cancel_1",
"type": "cancellation",
"description": "Customer changed mind",
"line_items": [{ "id": "line_2", "quantity": 1 }],
"occurred_at": "2026-02-09T11:00:00Z",
"status": "completed"
},
{
"id": "adj_refund_1",
"type": "refund",
"description": "Refund for cancelled item",
"line_items": [{ "id": "line_2", "quantity": 1 }],
"amount": 32300,
"occurred_at": "2026-02-09T11:05:00Z",
"status": "completed"
}
],
"permalink_url": "https://merchant.example.com/orders/12345"
}
Order return and refund
This example shows an order where the item was shipped, delivered, and then returned and refunded.
{
"ucp": {
"version": "2026-01-23",
"capabilities": {
"dev.ucp.shopping.order": [{"version": "2026-01-23"}]
}
},
"id": "order_03",
"checkout_id": "checkout_03",
"created_time": "2026-03-23T19:00:00Z",
"line_items": [
{
"id": "line_3",
"item": {
"id": "product_789",
"title": "Wireless Earbuds",
"price": 14900
},
"quantity": { "total": 1, "fulfilled": 1 },
"totals": [
{"type": "subtotal", "amount": 14900},
{"type": "tax", "amount": 1200},
{"type": "total", "amount": 16100}
],
"status": "fulfilled"
}
],
"totals": [
{"type": "subtotal", "amount": 14900},
{"type": "tax", "amount": 1200},
{"type": "total", "amount": 16100}
],
"fulfillment": {
"events": [
{
"id": "fulfill_evt_1",
"occurred_at": "2026-02-05T09:00:00Z",
"type": "shipped",
"line_items": [{ "id": "line_3", "quantity": 1 }],
"tracking_number": "987654321",
"tracking_url": "https://fedex.com/track/987654321",
"carrier": "FedEx",
"description": "Item shipped"
},
{
"id": "fulfill_evt_2",
"occurred_at": "2026-02-07T16:00:00Z",
"type": "delivered",
"line_items": [{ "id": "line_3", "quantity": 1 }],
"tracking_number": "987654321",
"tracking_url": "https://fedex.com/track/987654321",
"carrier": "FedEx",
"description": "Item delivered"
},
{
"id": "fulfill_evt_3",
"occurred_at": "2026-02-09T09:00:00Z",
"type": "returned",
"line_items": [{ "id": "line_3", "quantity": 1 }],
"tracking_number": "987654321",
"tracking_url": "https://fedex.com/track/987654321",
"carrier": "FedEx",
"description": "Item returned"
}
],
"expectations": [{ "...": "..." }]
},
"adjustments": [
{
"id": "adj_return_1",
"type": "return",
"description": "Item not compatible",
"line_items": [{ "id": "line_3", "quantity": 1 }],
"occurred_at": "2026-02-09T09:00:00Z",
"status": "completed"
},
{
"id": "adj_refund_2",
"type": "refund",
"description": "Refund for returned item",
"line_items": [{ "id": "line_3", "quantity": 1 }],
"amount": 16100,
"occurred_at": "2026-02-10T10:00:00Z",
"status": "completed"
}
],
"permalink_url": "https://merchant.example.com/orders/67890"
}