feat: Add seamless checkout transition functionality to ECaP #383
feat: Add seamless checkout transition functionality to ECaP #383jingyli wants to merge 4 commits intoUniversal-Commerce-Protocol:mainfrom
Conversation
5a8b3de to
b97bf31
Compare
| "required": ["ucp", "url"], | ||
| "properties": { | ||
| "ucp": { "$ref": "#/components/schemas/ucp_success" }, | ||
| "url": { |
There was a problem hiding this comment.
While a generic uri format permits http://, allowing an unencrypted handoff at the cart-to-checkout inflection point is something we should avoid. It leaves session parameters and any delegated authority contexts wide open to interception.
One solution would be to introduce a reusable secure_url type as a schema components. We can enforce ^https:// to guarantee production integrity, while explicitly whitelisting localhost so local dev remains frictionless.
Any thoughts? Doesn't need to be part of this PR, I can create a standalone proposal.
There was a problem hiding this comment.
There are a couple of places in UCP today that emphasize the use of https:
- https://ucp.dev/latest/specification/overview/#transport-security
- https://ucp.dev/latest/specification/checkout/#format
I tightened the language of url in the spec documentation to also call out that it MUST be a HTTPS URL. I think the idea of enforcing it via schema directly makes sense, though agree with you that it can be treated as a standalone proposal/refactoring and should be consistently applied over all UCP URL fields.
| 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. |
There was a problem hiding this comment.
How I interpret the "Business MAY choose" case is that the business would advertise a URL like:
https://merchant.com/.../checkout/start?cart_id=cart_999
This effectively creates a lazy initiation mechanism, and allows the host to transition into checkout without a preprovisioned session.
However, the ECP spec (Section 3.1.2 and 3.2) is built on the assumption that the host has already received a JSON 'Checkout Response' containing the id before the iframe is loaded. By allowing a direct transition in embedded-cart.md without this response, we are potentially creating a gap.
Since the Binding Contract (Section 3.3.3) starts at the handshake, the host needs that checkout id immediately to anchor its orchestration, logging, and validation. Relying on the subsequent ec.start notification is too late, as it leaves a race condition where delegated actions can be triggered before the host has a session reference.
Recommendation: Require that the id (checkout_id) MUST be included in the ec.ready request params. This shifts the id exchange earlier, and should allow for accommodation of this use case.
There was a problem hiding this comment.
However, the ECP spec (Section 3.1.2 and 3.2) is built on the assumption that the host has already received a JSON 'Checkout Response' containing the id before the iframe is loaded. By allowing a direct transition in embedded-cart.md without this response, we are potentially creating a gap.
(Preface: this was also the part that took me some time to wrap my head around)
I don't think we are necessarily creating a gap here. To initiate ECP today, we need to append certain parameters onto the continue_url we have received via the Checkout response (ref). However, there are 2 flavours of continue_url that are prescribed by UCP:
- Server-side stateful URL (the one where checkout session is proactively created by the business)
- Stateless permalinks (no actual session is created until the redirect lands)
There is nothing wrong reusing the pattern here and offer both URL formats for full flexibility. What it would mean is that the checkout resource would only be returned to the host for the first during ec.start in the case of a stateless permalink transition URL.
Relying on the subsequent ec.start notification is too late, as it leaves a race condition where delegated actions can be triggered before the host has a session reference.
I don't think this race condition is ever possible given ec.start is a core lifecycle message that signals the readiness of the checkout UI for interaction. Without it, buyer cannot use Embedded Checkout to trigger a delegated action.
| } | ||
| } | ||
| }, | ||
| "url": "https://merchant.example.com/cart-to-checkout/checkout123", |
There was a problem hiding this comment.
Recommendation: We should not rely on the URL for (checkout) identity disambiguation.
While a merchant may bake an ID into the URL slug, that identity is opaque to the host's programmatic orchestration. To support agentic workflows and reliable logging, let's include the checkout id as an explicit field in the transition.checkout object (when known).
This makes it slightly more explicit that there is a JIT variant too where the id isn't provided until ec.ready.
There was a problem hiding this comment.
To support agentic workflows and reliable logging, let's include the checkout id as an explicit field in the transition.checkout object (when known).
Would you be able to help me understand this argument a bit more? I actually feel like having an explicit id here is a little bit weirder given:
- This would be the first time where the identifier of a core capability can be optional in UCP schema.
- If this
idis set, does it mean that in theory (since embedded context can be concluded after receivingep.cart.completeand host can move to a different transport implementation to continue with checkout): platforms have the ability to directly callupdate_checkoutagainst this ID with a request payload and bypasscreate_checkoutentirely?
b97bf31 to
a640b8b
Compare
|
Thanks @gsmith85 for the feedback! Comments are addressed and requesting another pass (especially on the 2 open threads around presence of |
Description
Follow-up to feedback received on #244. We need some mechanism to allow host to facilitate seamless transition from Embedded Cart to Embedded Checkout without needing to renegotiate via
create_checkoutif they would like.Category (Required)
ucp-schematool (resolver, linter, validator). (Requires Maintainer approval)Related Issues
Not an issue, but related to #244.
Checklist