From a640b8b0d7e42dca5fd0a7300ef0259c5b32ec60 Mon Sep 17 00:00:00 2001 From: Jing Li Date: Fri, 24 Apr 2026 17:02:53 -0400 Subject: [PATCH 1/4] Initial commit to model transition to ECaP's ep.cart.complete message. --- docs/specification/embedded-cart.md | 52 +++++++++++++++++++ docs/specification/embedded-checkout.md | 3 +- .../services/shopping/embedded.openrpc.json | 22 ++++++++ 3 files changed, 76 insertions(+), 1 deletion(-) diff --git a/docs/specification/embedded-cart.md b/docs/specification/embedded-cart.md index 8ed212e6..46bce489 100644 --- a/docs/specification/embedded-cart.md +++ b/docs/specification/embedded-cart.md @@ -361,6 +361,8 @@ proceed to initiate a checkout session based on the completed cart by issuing a - **Type:** Notification - **Payload:** - `cart` (object, **REQUIRED**): The final state of the cart. + - `transition` (object, **OPTIONAL**): Advertisement for availability to transition + directly into Embedded Checkout. **Example Message:** @@ -381,6 +383,56 @@ proceed to initiate a checkout session based on the completed cart by issuing a } ``` +Business **MAY** also choose to specify a `transition` field to advertise a mechanism +for hosts to seamlessly transition into Embedded Checkout from the completed +Embedded Cart. This is represented by `transition` containing a minimal `checkout` object: + +- `ucp` (object, **REQUIRED**): Metadata to fully qualify the advertisement. + Business **MUST** include a checkout capability and an embedded service binding + with `config.delegate`. +- `url` (string, **REQUIRED**): URL representing shift to checkout. Business **MAY** choose + to specify a redirect URL without having the actual checkout session created. + +**Example Message With `transition`:** + +```json +{ + "jsonrpc": "2.0", + "method": "ep.cart.complete", + "params": { + "cart": { ...cart fields... }, + "transition": { + "checkout": { + "ucp": { + "version": "{{ ucp_version }}", + "status": "success", + "capabilities": { + "dev.ucp.shopping.checkout": [ { "version": "{{ ucp_version }}" } ] + }, + "services": { + { + "version": "{{ ucp_version }}", + "transport": "embedded", + "config": { + "delegate": [...] + } + } + } + }, + "url": "https://merchant.example.com/cart-to-checkout/checkout123", + } + } + } +} +``` + +When `transition` is received as part of `ep.cart.complete`, the host **MAY** choose +to initiate Embedded Checkout by appending `checkout.url` with relevant parameters - +see [Embedded Checkout - Loading an Embedded Checkout URL](embedded-checkout.md#loading-an-embedded-checkout-url). +Host also has full flexibility over how they want to render Embedded Checkout (i.e. +reuse the same embedded context as Embedded Cart or tear down the current one in favour +of bootstrapping a new embedded context). + ### State Change Messages State change notifications follow the shared EP pattern — see diff --git a/docs/specification/embedded-checkout.md b/docs/specification/embedded-checkout.md index e580f95e..6196637f 100644 --- a/docs/specification/embedded-checkout.md +++ b/docs/specification/embedded-checkout.md @@ -131,10 +131,11 @@ indicate ECP availability and allowed delegations for a specific session. ```json { "id": "checkout_abc123", - "status": "open", + "status": "incomplete", "continue_url": "https://merchant.example.com/checkout/abc123", "ucp": { "version": "{{ ucp_version }}", + "status": "success", "services": { "dev.ucp.shopping": [ { diff --git a/source/services/shopping/embedded.openrpc.json b/source/services/shopping/embedded.openrpc.json index 4210fea0..5982cee2 100644 --- a/source/services/shopping/embedded.openrpc.json +++ b/source/services/shopping/embedded.openrpc.json @@ -496,6 +496,28 @@ "$ref": "../../schemas/shopping/cart.json", "description": "Final cart state." } + }, + { + "name": "transition", + "schema": { + "type": "object", + "description": "Optional advertisement from business for seamless transition from cart to checkout.", + "required": ["checkout"], + "properties": { + "checkout": { + "type": "object", + "description": "Custom object containing data needed by host to facilitate the transition.", + "required": ["ucp", "url"], + "properties": { + "ucp": { "$ref": "#/components/schemas/ucp_success" }, + "url": { + "type": "string", + "description": "The transition URL." + } + } + } + } + } } ] }, From 57ef459ac735293068867130731883db3b9812e8 Mon Sep 17 00:00:00 2001 From: Jing Li Date: Wed, 29 Apr 2026 15:53:33 -0400 Subject: [PATCH 2/4] Address review feedback. --- docs/specification/embedded-cart.md | 17 ++++++++++------- source/services/shopping/embedded.openrpc.json | 3 ++- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/docs/specification/embedded-cart.md b/docs/specification/embedded-cart.md index 46bce489..eeb72015 100644 --- a/docs/specification/embedded-cart.md +++ b/docs/specification/embedded-cart.md @@ -410,14 +410,17 @@ Embedded Cart. This is represented by `transition` containing a minimal `checkou "dev.ucp.shopping.checkout": [ { "version": "{{ ucp_version }}" } ] }, "services": { - { - "version": "{{ ucp_version }}", - "transport": "embedded", - "config": { - "delegate": [...] + "dev.ucp.shopping": [ + { + "version": "{{ ucp_version }}", + "transport": "embedded", + "config": { + "delegate": [...] + } } - } - } + ] + }, + "payment_handlers": {...} }, "url": "https://merchant.example.com/cart-to-checkout/checkout123", } diff --git a/source/services/shopping/embedded.openrpc.json b/source/services/shopping/embedded.openrpc.json index 5982cee2..cfcefae8 100644 --- a/source/services/shopping/embedded.openrpc.json +++ b/source/services/shopping/embedded.openrpc.json @@ -506,12 +506,13 @@ "properties": { "checkout": { "type": "object", - "description": "Custom object containing data needed by host to facilitate the transition.", + "description": "Metadata required by the host to bootstrap and transition into an embedded checkout session.", "required": ["ucp", "url"], "properties": { "ucp": { "$ref": "#/components/schemas/ucp_success" }, "url": { "type": "string", + "format": "uri", "description": "The transition URL." } } From b046e1525cc516c591b813ba0f8a73a4a0d1906f Mon Sep 17 00:00:00 2001 From: Jing Li Date: Wed, 29 Apr 2026 21:56:54 -0400 Subject: [PATCH 3/4] Tighten language on checkout.url parameter. --- docs/specification/embedded-cart.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/specification/embedded-cart.md b/docs/specification/embedded-cart.md index eeb72015..18280bb5 100644 --- a/docs/specification/embedded-cart.md +++ b/docs/specification/embedded-cart.md @@ -390,8 +390,9 @@ Embedded Cart. This is represented by `transition` containing a minimal `checkou - `ucp` (object, **REQUIRED**): Metadata to fully qualify the advertisement. Business **MUST** include a checkout capability and an embedded service binding with `config.delegate`. -- `url` (string, **REQUIRED**): URL representing shift to checkout. Business **MAY** choose - to specify a redirect URL without having the actual checkout session created. +- `url` (string, **REQUIRED**): URL representing shift to checkout. Business **MUST** + specify a HTTPS URL and **MAY** choose a stateless URL like permalink. See + [Checkout Capability - Continue URL Format](checkout.md#format). **Example Message With `transition`:** From 336f8e571b9f844061c45339da6d9d32b6c32bc4 Mon Sep 17 00:00:00 2001 From: Jing Li Date: Wed, 29 Apr 2026 22:45:51 -0400 Subject: [PATCH 4/4] Remove payment_handler after giving it some more thought. --- docs/specification/embedded-cart.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/specification/embedded-cart.md b/docs/specification/embedded-cart.md index 18280bb5..2c68a488 100644 --- a/docs/specification/embedded-cart.md +++ b/docs/specification/embedded-cart.md @@ -420,8 +420,7 @@ Embedded Cart. This is represented by `transition` containing a minimal `checkou } } ] - }, - "payment_handlers": {...} + } }, "url": "https://merchant.example.com/cart-to-checkout/checkout123", }