Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 54 additions & 1 deletion docs/specification/catalog/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -153,9 +153,14 @@ Messages communicate business outcomes and provide context:
| Type | When to Use | Example Codes |
| :--- | :--- | :--- |
| `error` | Business-level errors | `NOT_FOUND`, `OUT_OF_STOCK`, `REGION_RESTRICTED` |
| `warning` | Important conditions affecting purchase | `DELAYED_FULFILLMENT`, `FINAL_SALE`, `AGE_RESTRICTED` |
| `warning` | Important conditions affecting purchase | `DELAYED_FULFILLMENT`, `FINAL_SALE` |
| `info` | Additional context without issues | `PROMOTIONAL_PRICING`, `LIMITED_AVAILABILITY` |

Warnings with `presentation: "disclosure"` carry notices (e.g., allergen
declarations, safety warnings) that platforms must not hide or dismiss. See
[Warning Presentation](../checkout.md#warning-presentation) for the full
rendering contract.

**Note**: All catalog errors use `severity: "recoverable"` - agents handle them programmatically (retry, inform user, show alternatives).

#### Message (Error)
Expand Down Expand Up @@ -250,6 +255,54 @@ identifiers were not found.
Agents correlate results using the `inputs` array on each variant. See
[Client Correlation](lookup.md#client-correlation).

#### Product Disclosure

When a product requires a disclosure (e.g., allergen notice, safety warning),
return it as a warning with `presentation: "disclosure"`. The `path` field targets the
relevant component in the response — when it targets a product, the
disclosure applies to all of its variants.

```json
{
"ucp": {...},
"products": [
{
"id": "prod_nut_butter",
"title": "Artisan Nut Butter Collection",
"variants": [
{
"id": "var_almond",
"title": "Almond Butter",
"price": { "amount": 1299, "currency": "USD" },
"availability": { "available": true }
},
{
"id": "var_cashew",
"title": "Cashew Butter",
"price": { "amount": 1499, "currency": "USD" },
"availability": { "available": true }
}
]
}
],
"messages": [
{
"type": "warning",
"code": "allergens",
"path": "$.products[0]",
"content": "**Contains: tree nuts.** Produced in a facility that also processes peanuts, milk, and soy.",
"content_type": "markdown",
"presentation": "disclosure",
"image_url": "https://merchant.com/allergen-tree-nuts.svg",
"url": "https://merchant.com/allergen-info"
}
]
}
```

See [Warning Presentation](../checkout.md#warning-presentation) for the
full rendering contract.

## Transport Bindings

The capabilities above are bound to specific transport protocols:
Expand Down
125 changes: 125 additions & 0 deletions docs/specification/checkout.md
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,131 @@ payment instrument, or by removing the claim from `context.eligibility` to
renegotiate the checkout (obtaining updated pricing, availability, etc.)
and then resubmitting for completion.

### Warning Presentation

The `presentation` field on warning messages controls the rendering
contract the platform **MUST** follow. When omitted, it defaults to
`"notice"`.

| | `notice` (default) | `disclosure` |
| :--- | :--- | :--- |
| Display content | **MUST** | **MUST** |
| Proximity to `path` | **MAY** | **MUST** |
| Dismissible | **MAY** | **MUST NOT** |
| Render `image_url` | **MAY** | **MUST** |
| Render `url` | **MAY** | **SHOULD** |
| Escalate if cannot honor | — | **MUST** via `continue_url` |

#### `notice` (default)

The default rendering contract for warnings. Platforms **MUST** display
the warning content to the buyer. Platforms **MAY** render notices in a
banner, tray, or toast, and **MAY** allow the buyer to dismiss them.

#### `disclosure`

Warnings with `presentation: "disclosure"` carry notices — safety
warnings, allergen declarations, compliance content, etc. — that
**MUST** follow the prescribed rendering contract below.

**Platform requirements:**

* **MUST** display the warning `content` to the buyer.
* **MUST** display the warning in proximity to the component referenced
by `path`, preserving the association between the disclosure and its
subject. When `path` is omitted, the disclosure applies to the response
as a whole.
* **MUST NOT** hide, collapse, or auto-dismiss the warning.
* **MUST** render `image_url` when present (e.g., warning symbol,
energy class label).
* **SHOULD** render `url` as a navigable reference link when present.

Warnings with `presentation: "disclosure"` **SHOULD** be given rendering
priority over notices.

Platforms that cannot honor the disclosure rendering contract **MUST**
escalate to merchant UI via `continue_url` rather than silently
downgrading to a notice.

**Business requirements:**

* **MUST** set `presentation: "disclosure"` when the warning content must
be displayed alongside a specific component and must not be hidden or
auto-dismissed.
* **SHOULD** use the `path` field to associate disclosures with the
relevant component in the response.
* **SHOULD** provide a `code` that identifies the disclosure category
(e.g., `prop65`, `allergens`, `energy_label`).
* **SHOULD** provide `image_url` when the disclosure has an associated
visual element (e.g., warning symbol, energy class label).
* **SHOULD** provide `url` when a reference link is available for the
buyer to learn more.

#### Disclosure and Acknowledgment

The `presentation` field controls how the warning is rendered, not
whether the checkout can proceed. When affirmative buyer acknowledgment
or authorization is also required, the business **MAY** combine the
disclosure with the escalation mechanisms described in the
[Checkout Status Lifecycle](#checkout-status-lifecycle) to ensure the
appropriate buyer input is obtained.

#### Jurisdiction and Applicability

It is the business's responsibility to determine which disclosures apply
to a given session and return only those that are relevant. Businesses
**SHOULD** use buyer-provided data (`context` and other inputs) and
product attributes to resolve jurisdiction-specific requirements.
Platforms do not affect or resolve disclosure applicability — they render
what they receive from the business.

#### Example

A checkout response containing both a recoverable error and a disclosure
warning on a line item:

```json
{
"ucp": { "version": "{{ ucp_version }}", "status": "success" },
"id": "chk_abc123",
"status": "incomplete",
"currency": "USD",
"line_items": [
{
"id": "li_1",
"item": { "id": "item_456", "title": "Artisan Nut Butter Collection", "image_url": "https://merchant.com/nut-butter.jpg" },
"quantity": 1,
"totals": [{ "type": "subtotal", "amount": 1299 }]
}
],
"totals": [{ "type": "total", "amount": 1299 }],
"messages": [
{
"type": "error",
"code": "field_required",
"path": "$.buyer.email",
"content": "Buyer email is required",
"severity": "recoverable"
},
{
"type": "warning",
"code": "allergens",
"path": "$.line_items[0]",
"content": "**Contains: tree nuts.** Produced in a facility that also processes peanuts, milk, and soy.",
"content_type": "markdown",
"presentation": "disclosure",
"image_url": "https://merchant.com/allergen-tree-nuts.svg",
"url": "https://merchant.com/allergen-info"
}
],
"links": []
}
```

The platform resolves the recoverable error programmatically while
rendering the allergen disclosure in proximity to the referenced line
item.

## Continue URL

The `continue_url` field enables checkout handoff from platform to business UI,
Expand Down
15 changes: 15 additions & 0 deletions source/schemas/shopping/types/message_warning.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,21 @@
],
"default": "plain",
"description": "Content format, default = plain."
},
"presentation": {
"type": "string",
"default": "notice",
"description": "Rendering contract for this warning. 'notice' (default): platform MUST display, MAY dismiss. 'disclosure': platform MUST display in proximity to the path-referenced component, MUST NOT hide or auto-dismiss. See specification for full contract."
},
"image_url": {
"type": "string",
"format": "uri",
"description": "URL to a required visual element (e.g., warning symbol, energy class label)."
},
"url": {
"type": "string",
"format": "uri",
"description": "Reference URL for more information (e.g., regulatory site, registry entry, policy page)."
}
}
}
Loading