-
Notifications
You must be signed in to change notification settings - Fork 270
feat(cart): Embedded protocol transport binding for cart capability #116
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
75127cb to
4252786
Compare
43afa1f to
ebfa5ed
Compare
| vulnz | ||
| yaml | ||
| yml | ||
| ZEGTBCTMJ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Intentional?
| yml | ||
| ZEGTBCTMJ | ||
| llms | ||
| paymentmethodchange |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don’t see this elsewhere in the PR
| llms | ||
| paymentmethodchange | ||
| reauth | ||
| reprepare |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not a word, I’d suggest rewriting the sentence it’s in instead.
| "schema": "https://ucp.dev/services/shopping/mcp.openrpc.json", | ||
| "endpoint": "https://merchant.example.com/ucp/mcp" | ||
| }, | ||
| "embedded": { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you remind me if a business implementing UCP must implement every part of the transport for a given service (e.g., every message in embedded protocol, endpoint/ action in REST/ MCP)? Up until now it had not occurred to me that this might be an issue, since the business I represent would happily implement all the MCP cart actions alongside checkout, but this may not be the case with embedded, where Shopify may prefer to/ temporarily have only the checkout embed messages hooked up.
|
|
||
| ### Authentication | ||
|
|
||
| #### `ect.auth` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don’t think I understand how this message works from the Cart’s perspective. If the Cart sends ec.ready with requires_auth, what do they do while they wait for this auth message to come in? Why wouldn’t the auth be part of the response to that ready message, if it is actually required?
More generally, it’s not clear to me why this would exist for Cart and not Checkout. If a business wanted to enact this same identity linking requirement in Checkout, I assume they would do it with a messages error indicating that identity linking is required, and they would expect a UCP consumer to attach the necessary information before escalating to an embedded cart. Why not follow that same approach here, rather than creating an additional request-response cycle between host and business?
| the `ect_` prefix to avoid namespace pollution and clearly distinguish ECaP | ||
| parameters from business-specific query parameters: | ||
|
|
||
| - `ect_version` (string, **REQUIRED**): The UCP version for this session |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we add a ect_auth param (as a parallel to ec_auth)? In ECP, that param serves to identify the embedder and to unlock customizations out-of-band from UCP (e.g., the branding overrides of an embedded checkout or cart); I feel this is needed in the initial request for cart in the same way it is for checkout (so the server render of the page can incorporate knowledge of the embedder).
|
|
||
| ### Transition Messages | ||
|
|
||
| #### `ect.transition.checkout` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As I noted in my previous review, I feel this message is quite odd. As described, it implies that the buyer would always see a web checkout, and that the same HTML page will morph from cart to checkout, which I do not believe will be a common implementation pattern. It also means that the cart creates the checkout and navigates to it, which requires a separate parallel way to do everything you might do in that transition (you added ec_delegate param as a response, but omitted ec_auth; similarly, there is no way to attach data to create_checkout that is not attached to the cart).
I would have expected a much simpler notification here instead, indicating that the user has attempted to checkout (e.g., something like ect.checkout_request). This puts the embedder in control to use whatever approach to checkout is most appropriate, exactly as they would if they were building their own, non-embedded cart; they can call create_checkout with anything they like, and can construct an ECP URL/ initiate an ECP escalation in the standard way.
docs/specification/embedded-cart.md
Outdated
| changed, items added/removed) in the cart UI. However, it's waiting | ||
| for host input (i.e. validating the update to see if it's compliant | ||
| with host's requirement) before applying the changes. Embedded Cart | ||
| **MUST NOT** fully apply the changes without receiving a response |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What does "fully apply the changes" mean? I think we need to be more specific here — the embedded checkout would obviously need to indicate something changed, otherwise the buyer would think their edit had been ignored. I also think there should be some sort of guidance on timeouts here, since the action being blocked is one that every implementation would expect to be synronous or near-instant (if I change line item quantity by 1, I do not want to have to wait for 2 seconds to see that change reflected).
docs/specification/embedded-cart.md
Outdated
| occurred partially and depending on host response, the final changes | ||
| occur in Embedded Cart. | ||
|
|
||
| #### `ec.line_items.change_request` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why does this exist in cart, but not checkout? I feel we are creating a strange patchwork, where one side has request messages for some fields (fulfillment.address_change_request, payment.credential_request) and the other side has messages for other fields (line_items.change_request). Is there a rule that guides what requests are available where, or is it just, "whatever the first implementers wanted in their particular UX"?
Additionally, should this not be a formal delegation, instead of something that is expected of all embedded carts? We did this for the checkout "let host handle some parts of updates" flows, and I think it applies equally well to this action.
docs/specification/embedded-cart.md
Outdated
| "id": "items_change_request_1", | ||
| "result": { | ||
| "cart": { | ||
| "line_items": [ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the host allowed to edit every detail of these lines, or only some aspects?
Currency as client input is flawed - merchants control accepted
currencies, not buyers. Allowing "show me price in $X" implies forex
operations that break at payment time when the merchant's actual accepted
currency differs.
Correct model: buyer provides context signals, merchant determines currency
and other market-relevant attributes such as product availability,
shipping and delivery times, price, etc.
Changes:
- Add extensible Context type with country, region, postal_code for
progressive disclosure
- Add context to checkout (optional on create/update, omit on complete)
- Make currency output-only (omit on all operations)
This primitive will be relevant for catalog, cart, and checkout.
Context signals are provisional hints—businesses SHOULD use them when authoritative data is absent, MAY ignore unsupported values without errors. This differs from authoritative selections (addresses) which require explicit validation and error feedback. Changes: - Make context input-only (omit from response via ucp_response annotation) - Add Context entity documentation to checkout spec - Update context.json description with SHOULD/MAY language - Update currency description to emphasize merchant determination Input-only context keeps the door open for future "resolved context" output that echoes back what the merchant determined, similar to how currency works.
ebfa5ed to
0237bef
Compare
…tem validation to keep ECaP simple for now. We will re-evaluate on the item validation piece as a follow-up.
Reopening the PR to avoid recreating the
working-draftbranch. This is a mirror copy of #109 and will also cross-reference/carry-over comments from the old PR.Summary
Cart capability (
dev.ucp.shopping.cart) is being introduced in #73. This adds an additional transport binding (EP) on the capability (building directly upon the referenced PR), on top of existing REST & MCP bindings.Motivation
Businesses need a way to embed their cart building UI into eligible platforms, especially when complex experiences (i.e. item recommendations & upsells) are involved during cart building. Embedded Cart Protocol (ECaP) addresses this need and also offers a seamless connection to existing Embedded Checkout Protocol to continue the purchase experience.
Goals
Non-Goals
Detailed Design
Key methods supported by ECaP:
ect.readyect.auth(Request),ect.auth.change(Notification)ect.startect.transition.checkoutect.line_items.change,ect.buyer.change,ect.context.change,ect.messages.changeProtocol transition
[protocol namespace].transition.[capability transitioning to]that can be generally extended if conversions between multiple capabilities are possible.ect.transition.checkoutthat would denote a cart transitioning to a checkout session on the business's iframe.Risks and Mitigations
servicesadvertisement. Also structurally it's also very similar to ECP so businesses already supporting ECP should be familiar with the design already.ect.authto exchange required authorization data instead of adding them as query parameters incontinue_urlto avoid hijacking attacks.Graduation Criteria
Working Draft → Candidate:
Candidate → Stable:
Implementation History
TBD