Skip to content

feat(ep-commerce): server-cart shopper context + composable checkout#180

Open
field123 wants to merge 13 commits intomasterfrom
feat/server-cart-shopper-context
Open

feat(ep-commerce): server-cart shopper context + composable checkout#180
field123 wants to merge 13 commits intomasterfrom
feat/server-cart-shopper-context

Conversation

@field123
Copy link
Collaborator

@field123 field123 commented Mar 9, 2026

Summary

  • Shopper Context layer (Phase 0-3): ShopperContext global provider, cart hooks (useCart, useAddItem, useRemoveItem, useUpdateItem) with SWR caching, server utilities (resolveCartId, cart cookies), and ServerCartActionsProvider for Plasmic action wiring
  • Composable Checkout (Phase 0-2): EPCheckoutProvider orchestrator with 4-step state machine, form field components (customer info, shipping/billing address), shipping method selector, Stripe PaymentElements, order totals, step indicator, and checkout button
  • Build fixes: Replace inline type syntax with separate import type/export type for tsdx compatibility; fix logger call arity in form field components
  • Usage guidance: ux/ep-commerce-components.md documenting all ~25 components with type signatures, DataProvider names, refActions, and API route examples

Test plan

  • yarn build passes in plasmicpkgs/commerce-providers/elastic-path/
  • Verify ShopperContext provides overrides to descendant hooks
  • Verify useCart SWR fetch and cache invalidation on mutations
  • Verify EPCheckoutProvider step transitions and refActions
  • Verify form field validation (customer info, shipping/billing address)
  • Verify EPPaymentElements lazy-loads Stripe and reads clientSecret
  • Smoke test components in Plasmic Studio canvas with previewState props

field123 added 13 commits March 9, 2026 14:41
Replace the stale shopper auth specs with server-cart architecture:
- ShopperContext GlobalContext for Studio preview and checkout URL params
- Server-route-based cart hooks (useCart, useAddItem, useRemoveItem, useUpdateItem)
- httpOnly cookie management and X-Shopper-Context header utilities
- 4-phase migration plan (context → reads → mutations → credential removal)

All new code targets src/shopper-context/ in the EP commerce provider package.
Consumer app (storefront) implements API routes using exported server utilities.
…ties

ShopperContext GlobalContext provides override channel for cart identity
(Studio preview, checkout URLs). Server utilities (resolveCartId,
buildCartCookieHeader) enable httpOnly cookie-based cart management
in consumer API routes without exposing EP credentials to the browser.

- ShopperContext component with Symbol.for singleton pattern
- useShopperContext hook, useShopperFetch with X-Shopper-Context header
- Server-side resolve-cart-id (header > cookie > null priority)
- Server-side cart-cookie builder (httpOnly, SameSite=Lax)
- Plasmic GlobalContext registration
- 4 test suites (22 assertions), all passing
…alization

Server-route-based cart hooks replacing direct EP SDK calls:
- useCart: SWR hook fetching GET /api/cart via useShopperFetch, cache key
  includes cartId for Studio preview refetch
- useCheckoutCart: normalizes nested EP cart response into flat
  CheckoutCartData with formatted prices for Plasmic data binding
- EPCheckoutCartSummary: accepts optional cartData prop for server-route
  mode (two-component pattern avoids hooks violation)
- Design-time mock data (MOCK_SERVER_CART_DATA) for Studio preview
- swr added as peerDependency (>=1.0.0)
Server-route-based mutation hooks that replace direct EP SDK calls from
the browser. All cart operations go through /api/cart/* server routes so
client_secret never reaches the browser.

- useAddItem: POST /api/cart/items with auto cart refetch
- useRemoveItem: DELETE /api/cart/items/{id} with URL-encoded IDs
- useUpdateItem: PUT /api/cart/items/{id} debounced at 500ms
- Defensive isEmpty check in useCart for missing items field
- Barrel exports updated with new hooks and AddItemInput type
…e, server promo routes

P3-1: Add @deprecated JSDoc to old client-side cart hooks (use-cart, use-add-item,
use-remove-item, use-update-item) and cart-cookie utilities, directing developers
to the new server-route alternatives in shopper-context/.

P3-2: Add serverCartMode boolean prop to CommerceProvider. When enabled with no
clientId, renders children without EP SDK initialization — cart operations use
server routes via ShopperContext instead.

P3-3: Add useServerRoutes prop to EPPromoCodeInput. When enabled, promo apply/remove
go through POST/DELETE /api/cart/promo server routes via useShopperFetch() instead
of the client-side EP SDK. Refactored to two-component pattern (client/server inner
components) to avoid conditional hook calls.
…ActionsProvider

P3-4: Audited all getEPClient/useCommerce usage. All cart paths have
server-route alternatives. Product/search/inventory/bundle hooks remain
client-side (public data only, no client_secret exposed).

P3-5: Created ServerCartActionsProvider that bridges shopper-context
hooks (useAddItem, useRemoveItem, useUpdateItem) to Plasmic's global
actions system. CommerceProvider now uses it when serverCartMode=true,
giving designers access to addItem/updateItem/removeItem actions even
without EP SDK initialization.
Root orchestrator for the composable checkout flow. Wraps useCheckout()
and exposes complete checkout state via DataProvider + 9 refActions for
Plasmic interaction wiring. Design-time preview with mock data for all
4 checkout steps (customer info, shipping, payment, confirmation).

New files:
- CheckoutContext.tsx — shared payment context (EPCheckoutProvider ↔ EPPaymentElements)
- EPCheckoutProvider.tsx — component + registration metadata + 9 refActions
- EPCheckoutProvider.test.tsx — 9 tests covering render, preview states, refActions

Changes:
- use-checkout.tsx — cartId optional (server resolves from cookie)
- design-time-data.ts — composable checkout mock data for all steps
- registerCheckout.tsx — register EPCheckoutProvider
- composable/index.ts — barrel exports
…Totals (CC-P0-2..4)

EPCheckoutStepIndicator: repeater over 4 steps with per-step DataProvider
EPCheckoutButton: step-aware button with label/disabled/processing state
EPOrderTotalsBreakdown: financial totals from checkout/cart context
…-1..3)

EPCustomerInfoFields: headless firstName/lastName/email with validation
EPShippingAddressFields: shipping address with postcode validation by country
EPBillingAddressFields: billing address with shipping mirror mode
…mentElements (CC-P2-1..2)

EPShippingMethodSelector: repeater fetching shipping rates with selectMethod action
EPPaymentElements: Stripe Elements wrapper with lazy loading and design-time mock

All 9 composable checkout components complete (CC-P0 through CC-P2).
Replace `import { type Foo }` / `export { type Foo }` with separate
`import type` / `export type` statements across shopper-context and
checkout composable files. tsdx bundles older TS/Babel that does not
support the inline type-modifier syntax (TS 4.5+).

Fix three-arg log.debug() calls in form field components to match the
two-arg `(message, data?)` logger signature.

Add ux/ep-commerce-components.md usage guidance covering all 25+
components across shopper context, cart hooks, server utilities, and
composable checkout.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant