Skip to content

[skills] Migrate all cart/checkout references to Cart V2 - #855

Merged
ayal merged 33 commits into
mainfrom
cart-v2-migration
Aug 23, 2026
Merged

ayal merged 33 commits into
mainfrom
cart-v2-migration

Conversation

@rommy-amitai-w

@rommy-amitai-w rommy-amitai-w commented Aug 5, 2026 •

Copy link
Copy Markdown
Contributor

What

Migrates the ecommerce storefront skills' Cart V1 + Checkout V1 references to the unified Cart V2 API — both the API calls/shapes and the conceptual "cart → separate checkout" framing. Both V1 APIs are removed 2027-02-01 (migration guide · migration mapping).

Every rename was taken from those guides, cross-checked against the wix-private/ecom CartV1Proxy Scala V1↔V2 mappers, and validated against the real public @wix/ecom (@wix/auto_sdk_ecom_cart-v-2 / current-cart-v-2) TypeScript types (see below). Branch is merged up to date with main.

Scope

The storefront-facing ecommerce skills: Stores cart/checkout, Restaurants ordering, Bookings payment, Pricing-Plans membership, plus the CMS↔ecom and replatform-taxonomy references that describe the cart/checkout flow. wix-app (SITE_PLUGIN.md, backend-event/COMMON-EVENTS.md) and wix-docs-base44 carry their own ecom-V1 references and are handled in a separate follow-up PR (they sit outside these skills and need their own eval coverage). Catalog V3, the @wix/ecom/service-plugins SPI, and the Orders / Abandoned-Checkouts / Discount-Rules / Shipping APIs are a different axis and left as-is.

Files

  • wix-headless/references/inline-recipes/{how-to-code-a-store,how-to-code-restaurant-orders,how-to-code-pricing-plans}.md, wix-headless/references/SDK_HANDOFF.md
  • wix-vibe-headless/references/storefront/{INSTRUCTIONS.md, app/rest/wix-store-cart.js, app/context/CartContext.jsx, app/components/CartDrawer.jsx}
  • wix-vibe-headless/references/restaurants/{INSTRUCTIONS.md, app/rest/wix-restaurants-ordering.js, app/context/OrderCartContext.jsx, app/components/OrderCartDrawer.jsx}
  • wix-vibe-headless/references/bookings/{INSTRUCTIONS.md, app/rest/wix-bookings-checkout.js}
  • wix-manage/references/bookings/{booking-system-integration-gaps,end-to-end-booking-flow}.md, cms/cms-ecommerce-catalog-integration.md
  • wix-replatform/resources/rp-mapper/wix-business-solutions-taxonomy.md
  • yaml/wix-manage-evals/bookings/{booking-ecom-payment-integration,end-to-end-booking-flow}.yml, cms/cms-ecommerce-catalog-integration.yml — EvalForge coverage for the changed wix-manage docs (the coverage gate is blocking for wix-manage).

main rebuilt wix-vibe-headless (new hooks/components; REST helpers moved under app/rest/) but left it on Cart V1 — this branch re-applies the V2 migration onto that rebuilt structure: the REST helpers and the React cart consumers (context + drawers), keeping every exported helper signature unchanged so main's hooks/components ride V2 unchanged.

Key changes (V1 → V2)

Area V1 V2
SDK module currentCart / cart / checkout currentCartV2 / cartV2
Add addToCurrentCart({ lineItems }) addLineItemsToCurrentCart({ catalogItems })
REST base /ecom/v1/carts/current/*, /ecom/v1/checkouts /ecom/v2/carts/current/*, /ecom/v2/carts
Checkout createCheckout* → checkoutId; createOrder no checkout entity — cart id is the checkout id; place-order (token from calculate)
Read cart returns the cart returns { cart } (cart is optional)
Line item quantity, productName, price, image, url, descriptionLines, availability.status quantityInfo.confirmedQuantity, name, pricing.unitPrice/totalPrice, attributes.image/.url/.descriptionLines, top-level status
Money MultiCurrencyPrice / formattedAmount ConvertedMoney (amount/convertedAmount, no formatted string) — formatted client-side
Stock enum AVAILABLE/NOT_AVAILABLE/… IN_STOCK/OUT_OF_STOCK/PARTIALLY_IN_STOCK/REMOVED_FROM_CATALOG
Membership checkout membershipOptions.selectedMemberships line-item write membershipPayment: { existingMembership: { membershipId, appId } }; read back paymentConfig.membership
Invalid add silent 200 / silent quantity clamp rejected with an explicit error (catalog can't resolve the line)
Taxonomy model cart = phase 1, checkout = separate phase 2 cart = unified purchase-flow entity; checkout folded in

Type verification

Cart calls in the snippets were checked against the real public @wix/ecom cart-v2 / current-cart-v2 types:

  • membershipPayment (MembershipInput = { existingMembership: { appId, membershipId } } / futureMembership) and the read field paymentConfig.membership are the GA replacements for the deprecated selectedMembership. The pricing-plans recipe assumes them as GA (per the field owner promoting them); hold merge until that ships GA in the published @wix/ecom.
  • Membership credit/remaining balance is owned by the plan's Benefit-Programs domain, not the cart; summary.paymentSummary.memberships (from calculate/estimate) reports memberships already applied, and an exhausted plan surfaces as a summary.violations entry — the recipe uses that instead of a candidate/remaining read (which the cart doesn't expose).
  • getCheckoutUrl is lowercase-Url; getCurrentCart().cart is optional (guarded).

Testing

Docs/reference; all .js/.jsx reference files parse and their cart calls type-check against the real cart-v2 types. Independently reviewed against the SDK types + V2 REST docs + Scala proxy mappers. Not exercised against a live Wix site (npm embargo blocks a full build) — a live smoke test is recommended before relying on the vibe cart UI.


Companion PR (templates): wix/headless-templates#696
Follow-up PR (wix-app cart events + site-plugin → V2): #1093 — (wix-docs-base44's old /ecom/v1 example was already resolved on main: renamed to wix-base44-connector in #1059, cart-prose dropped in #1083.)

Cart V1 + Checkout V1 are replaced by the unified Cart V2 API (both V1 APIs
removed 2027-02-01). Updates the headless store recipe and the vibe-headless
storefront reference to Cart V2:

- currentCart -> currentCartV2; addToCurrentCart -> addLineItemsToCurrentCart
  (lineItems -> catalogItems)
- REST paths /ecom/v1/carts/current/* -> /ecom/v2/carts/current/*
- No checkout entity: drop createCheckoutFromCurrentCart; the cart id IS the
  checkout id, fed straight into the redirect session
- Line-item read shapes: quantity->quantityInfo.confirmedQuantity,
  productName->name, price->pricing, image->attributes.image,
  availability.status->status (IN_STOCK/PARTIALLY_IN_STOCK/OUT_OF_STOCK/REMOVED_FROM_CATALOG)
- update-line-items body now {lineItemId, quantity:{newQuantity}}

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
rommy-amitai-w and others added 3 commits August 6, 2026 10:26
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Extends the Cart V2 migration to every remaining Cart V1 / Checkout V1
reference across the skills repo (mappings verified against the ecom
CartV1Proxy Scala V1<->V2 mappers):

- inline-recipes: how-to-code-restaurant-orders (full cart+checkout flow),
  how-to-code-pricing-plans (membership moved to line-item selectedMembership)
- wix-vibe-headless: restaurants (REST client + INSTRUCTIONS), bookings
  (checkouts -> carts create/place-order)
- wix-manage: bookings integration + end-to-end flow, cms catalog integration
  (checkout/cart V1 REST -> cart-v2 create/calculate/place-order)
- wix-app: SITE_PLUGIN currentCart example, backend-event cart.onCart* -> cartV2
- SDK_HANDOFF + rp-mapper taxonomy: stale V1 references/links -> cart-v2

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…tro example

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@rommy-amitai-w rommy-amitai-w changed the title Migrate storefront cart/checkout references to Cart V2 Migrate all cart/checkout references to Cart V2 Aug 6, 2026
rommy-amitai-w and others added 7 commits August 6, 2026 11:12
…t review

- pricing-plans: apply membership via membershipPayment.existingMembership
  { appId, membershipId } (selectedMembership is deprecated); correct the
  eligibility source (paymentSummary.memberships = applied, not eligible —
  use member active-orders + live coverage)
- clarify Cart V2 has NO preformatted money (summary is ConvertedMoney too);
  amount=site currency, convertedAmount=display

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
V2 attributes.image is a scalar wix:image:// string, not { url } — the doc
comment in wix-store-cart.js kept the V1 .url accessor. Confirmed against
ItemAttributes typing + CartV2ToV1Mappers.scala.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- restaurant-orders: last V1 `currentCart` in Astro prose -> currentCartV2
- pricing-plans: note both membership-apply fields are unstable in the SDK
  typings (selectedMembership deprecated/past-removal; membershipPayment @internal)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
COMMON-EVENTS cart rows used .md?apiView=SDK; siblings use ?apiView=SDK.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ied)

A type harness compiled against the PUBLIC @wix/ecom types shows membershipPayment
is @internal (absent from public LineItemUpdate). selectedMembership { newMembership:
{ _id, appId } } is the only public (deprecated) field. Reverted the recipe to it.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Not just the doc link — the conceptual model. Cart V2 unifies cart + checkout,
so:
- `cart` row now describes the unified Cart V2 entity (whole purchase flow)
- `checkout` row: no longer a separate Wix entity; folded into the cart, map
  source checkout state onto `cart` (Checkout V1 removed 2027-02-01)
- `current-cart` -> Cart V2 (session-scoped), link to cart-v2
- entity/state bullets + "canonical target" prose updated to reflect unification

Keeps checkout as a taxonomy concept (source systems still have it) but points
it at Cart V2, so the replatform mapper stays usable.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…d amount)

V1 gave a ready `formattedAmount`; V2 cart money is raw ConvertedMoney, so the
recipes now tell users HOW to format, not just "format it yourself":
- how-to-code-a-store: new "Formatting cart prices" section with an
  Intl.NumberFormat helper keyed off the cart's currencyCode
- how-to-code-restaurant-orders: concrete formatting example + cross-ref
- wix-vibe-headless/SKILL.md: Cart V2 ConvertedMoney caveat in the canonical
  "Money/price fields" note (distinguish from the {value,currency,formattedValue}
  shape used by Stores/Bookings/Events)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@rommy-amitai-w rommy-amitai-w changed the title Migrate all cart/checkout references to Cart V2 [skills] Migrate all cart/checkout references to Cart V2 Aug 9, 2026
rommy-amitai-w and others added 10 commits August 9, 2026 16:53
The store recipe is a current-cart (visitor-session) flow on currentCartV2,
which exposes calculateCurrentCart; calculateCart is the cartId-based method on
the separate cartV2 module. Caught by independent review against the public types.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Editorial pass so the docs stop invoking the old two-entity model:
- add a "One entity now" note to the reader-facing recipes + vibe INSTRUCTIONS
  (cart V2 is the evolution of cart+checkout; say "cart" for the entity,
  "checkout" only for the hosted checkout page)
- rp-mapper taxonomy: drop the phantom `checkout` PRIMARY-ENTITY row (it's not a
  separate Wix entity in V2); move source-checkout→cart guidance to Mapper notes
- wix-manage booking/cms: retire stale "create checkout and order" /
  "checkout/order pattern" / "Cart and Checkout APIs" entity phrasing -> cart
Kept: the hosted-checkout page/redirect wording, literal identifiers
(getCheckoutUrl, ecomCheckout, checkout()), and intentional V1->V2 contrast.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Say the version once (intros/contrast/version-specific facts keep "Cart V2");
use plain "cart" for ordinary entity references. Here: current-cart taxonomy
row + the pricing-plans conclusion.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Fix an inaccurate mapper note: a source checkout's INPUT state (billing,
shipping, coupons) maps onto the cart; calculated prices/tax/totals are not
stored on the cart in V2 (computed via Calculate/Estimate -> CartSummary; final
figures live on the order). Also tightened the 'checkout state' trigger bullet.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
It's a routing-trigger list item (like 'cart contents'/'order lifecycle'); the
mapping mechanics + calculated-totals caveat live in Mapper notes, not here.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Per review: teach V2 on its own terms. Keep the single "One entity now" note
and add a migration-guide link there; drop the repeated "(V1 returned the cart
directly)" / "NOT V1's lineItems" / "The V1 flow created a checkout entity"
asides, restating the bug-prevention as pure V2 ("returns { cart } — destructure
it"; "the cart's _id is the checkout id"). Stores Catalog-V1 warnings left intact.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…taurant-orders conclusion

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Consistency: pricing-plans recipe, the 3 vibe INSTRUCTIONS, and vibe SKILL.md
now point migrators to the migration guide (matches the store/restaurant recipes).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The 'Checkout' section documents the checkout STEP (redirect to the hosted
checkout page), not a checkout entity. Rename heading -> 'Checkout — redirect to
the hosted checkout page' and change the bare 'see Checkout' pointer to 'see the
Checkout section below', so neither reads as a reference to a checkout entity.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- taxonomy Mapper note: state that BOTH price totals (summary.priceSummary) and
  payment figures (summary.paymentSummary — amount due, gift-card deductions) are
  computed by Calculate/Estimate Cart's CartSummary, not stored on the cart
- how-to-code-a-store: remove the "Simpler alternative (see PR note)" block (a
  PR-review artifact, meaningless in the shipped doc) and the redundant
  "(Cart V2 nests it under attributes)" parenthetical (the code already shows it)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Comment thread skills/wix-headless/references/inline-recipes/how-to-code-pricing-plans.md Outdated
Comment thread skills/wix-headless/references/inline-recipes/how-to-code-pricing-plans.md Outdated
Comment thread skills/wix-headless/references/inline-recipes/how-to-code-pricing-plans.md Outdated
**⚠️ CRITICAL: `options.options` is for MODIFIERS, not variant selection.** Product option selections (Size/Color) are resolved to a **variant** and referenced by `variantId`. `options.options` is only for free-text / TEXT_CHOICES add-on **modifiers**. Do **not** encode Size/Color as `options.options` — that is the coffee-grind bug (`200` + empty cart).

### Checkout
### Checkout — redirect to the hosted checkout page

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this part especially needs verification


**⚠️ CRITICAL: `origin` for `postFlowUrl`/`thankYouPageUrl` MUST be the `https://` published host — derive it from `window.location.origin`, NEVER `new URL(request.url).origin`.** The Headless redirect allowlist registers the site's **`https://`** host and treats **`http://<same host>` as a different, unlisted origin**. When the buyer returns from the hosted checkout (e.g. clicks "Continue Browsing"), the redirect goes through the allowlist — and an `http://` `postFlowUrl` **403s** with *"… isn't listed as an allowed redirect domain."* If you build the redirect session in a **server route** (`src/pages/api/*`), `new URL(request.url).origin` resolves to **`http://`** behind Wix's TLS-terminating proxy → guaranteed 403 on return. So **pass `window.location.origin` from the client** into the route (don't read the origin off the request), or force the scheme to `https`. Doc: <https://dev.wix.com/docs/go-headless/getting-started/setup/manage-urls/add-allowed-redirect-domains>.

### Formatting cart prices (Cart V2 has no preformatted amount)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and this needs careful checking

Comment thread skills/wix-vibe-headless/references/storefront/INSTRUCTIONS.md Outdated
rommy-amitai-w and others added 2 commits August 13, 2026 15:24
…bership field

- Strip remaining Cart V1 / Checkout V1 references and V1<->V2 contrasts; keep exactly one migration-guide referral per doc where ecom types are introduced.

- Correct add-to-cart failure mode to V2: an unresolved/invalid line item or an over-stock quantity is rejected with an explicit error (was the V1 silent 200-with-empty-lineItems / silent quantity clamp).

- pricing-plans: apply membership via membershipPayment.existingMembership (read back as membership) instead of the deprecated selectedMembership.newMembership.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…be helpers

- pricing-plans: drop the non-existent `eligibleMemberships[].credits.remaining` cart read (contradicted the "no eligible-memberships read on the V2 cart" note); fold the credit-exhaustion check into the member-plan eligibility path. Specify the membership read-back field as `paymentConfig.membership`.

- wix-store-cart.js: drop stray "(the V1 behavior)" contrast from the quantity-update note.

- wix-restaurants-ordering.js: fix doc comment "not AVAILABLE" -> status not IN_STOCK (matches the ItemStatus enum and the code's check).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
rommy-amitai-w and others added 3 commits August 16, 2026 10:34
Trim the step-3 'which plan to apply' bullet to the evidence (paymentSummary.memberships = already-applied, not candidates) + a pointer; the full member-plans/live-coverage recipe stays in the single LIVE-read note below.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ulate signals

Rewrite the pricing-plans credit-plan note to surface what calculate/estimate DOES expose (summary.paymentSummary.memberships; the line's paymentConfig.membership.redemptionCost + redemptionType; over-limit as a summary.violations entry) before noting the one gap (remaining-balance/candidate read lives only on the deprecated legacy eligibleMemberships flow).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…com-cart field

Point the remaining-balance note at the plan's Benefit-Program domain (same source as the coverage check) instead of the deprecated legacy eligibleMemberships; keep apply+calculate->violation as the primary path. The membership SPI is provider/server-side and stays out of this frontend recipe.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@rommy-amitai-w
rommy-amitai-w marked this pull request as ready for review August 16, 2026 14:50
rommy-amitai-w and others added 2 commits August 17, 2026 10:54
# Conflicts:
#	skills/wix-vibe-headless/references/bookings/INSTRUCTIONS.md
#	skills/wix-vibe-headless/references/bookings/app/rest/wix-bookings-checkout.js
#	skills/wix-vibe-headless/references/restaurants/INSTRUCTIONS.md
#	skills/wix-vibe-headless/references/storefront/INSTRUCTIONS.md
#	skills/wix-vibe-headless/references/storefront/app/rest/wix-store-cart.js
main rebuilt wix-vibe-headless (new hooks/components, files moved to app/rest/) but left the REST layer on Cart V1 / Checkout V1. Migrate the storefront/restaurants/bookings REST helpers to Cart V2 — add-line-items/catalogItems, get current cart -> { cart }, update-line-items { lineItemId, quantity: { newQuantity } }, remove { lineItemIds }, and drop create-checkout in favor of the cart-id-is-checkout-id redirect-session. Align the 3 INSTRUCTIONS to V2 (ConvertedMoney money, status enum, attributes.*) with one migration-guide referral each. Exported function signatures unchanged, so main's hooks/context ride V2 unchanged; main's structure/components/Orders API untouched.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
Contributor

⚠️ EvalForge Skill Gate: Coverage Warning

  • backend-event has no eval scenario at all. Add one under yaml/wix-app-evals/ tagged backend-event, or add that tag to a scenario that already exercises the area.
  • site-plugin has no eval scenario at all. Add one under yaml/wix-app-evals/ tagged site-plugin, or add that tag to a scenario that already exercises the area.

No eval run was started — a coverage failure is caught before any run cost.

The gate is in its soak period (blocking: false), so this check still passes.

@github-actions

github-actions Bot commented Aug 17, 2026 •

Copy link
Copy Markdown
Contributor

⚠️ EvalForge YAML Gate: Eval Comparison

Verdict: required | Tag: draft:wix/skills#855

Scenario Required Winner Cost (PR / prod) Tokens (PR / prod) Time (PR / prod) Runs (PR / prod)
bookings/booking-ecom-payment-integration ❌ - $0.153 / $0.224 144.0K / 203.9K 60.0s / 57.6s PR / prod
bookings/end-to-end-booking-flow ✅ ⬆️ with (high) $0.167 / $0.174 145.1K / 145.7K 68.8s / 72.0s PR / prod
cms/cms-ecommerce-catalog-integration ✅ ⬆️ with (high) $0.132 / $0.222 140.5K / 205.8K 32.6s / 51.1s PR / prod
bookings/booking-ecom-payment-integration

both sides failed assertions: LLM judge - no clear winner | pairwise judge: PR wins (undefined confidence) | Response A is meaningfully better because it uses the correct Cart V2 payment flow (explicitly required) while Response B uses deprecated Checkout V1 APIs. Although both responses received LLM judge failures, Response A's failure (score 4/10) was for incomplete conceptual handling with otherwise correct API usage, whereas Response B's failure (score 0/10) was for using fundamentally wrong API endpoints. This represents a material, objective difference in task completion and tool accuracy. | dimensions - 0: undefined, 1: undefined, 2: undefined, 3: undefined, 4: undefined, 5: undefined, 6: undefined, 7: undefined, 8: undefined, 9: undefined, 10: undefined, 11: undefined, 12: undefined, 13: undefined, 14: undefined, 15: undefined, 16: undefined, 17: undefined, 18: undefined, 19: undefined, 20: undefined, 21: undefined, 22: undefined, 23: undefined, 24: undefined, 25: undefined, 26: undefined, 27: undefined, 28: undefined, 29: undefined, 30: undefined, 31: undefined, 32: undefined, 33: undefined, 34: undefined, 35: undefined, 36: undefined, 37: undefined, 38: undefined, 39: undefined, 40: undefined, 41: undefined, 42: undefined, 43: undefined, 44: undefined, 45: undefined, 46: undefined, 47: undefined, 48: undefined, 49: undefined, 50: undefined, 51: undefined, 52: undefined, 53: undefined, 54: undefined, 55: undefined, 56: undefined, 57: undefined, 58: undefined, 59: undefined, 60: undefined, 61: undefined, 62: undefined, 63: undefined, 64: undefined, 65: undefined, 66: undefined, 67: undefined, 68: undefined, 69: undefined, 70: undefined, 71: undefined, 72: undefined, 73: undefined, 74: undefined, 75: undefined, 76: undefined, 77: undefined, 78: undefined, 79: undefined, 80: undefined, 81: undefined, 82: undefined, 83: undefined, 84: undefined, 85: undefined, 86: undefined, 87: undefined, 88: undefined, 89: undefined, 90: undefined, 91: undefined, 92: undefined, 93: undefined, 94: undefined, 95: undefined, 96: undefined, 97: undefined, 98: undefined, 99: undefined, 100: undefined, 101: undefined, 102: undefined, 103: undefined, 104: undefined, 105: undefined, 106: undefined, 107: undefined, 108: undefined, 109: undefined, 110: undefined, 111: undefined, 112: undefined, 113: undefined, 114: undefined, 115: undefined, 116: undefined, 117: undefined, 118: undefined, 119: undefined, 120: undefined, 121: undefined, 122: undefined, 123: undefined, 124: undefined, 125: undefined, 126: undefined, 127: undefined, 128: undefined, 129: undefined, 130: undefined, 131: undefined, 132: undefined, 133: undefined, 134: undefined, 135: undefined, 136: undefined, 137: undefined, 138: undefined, 139: undefined, 140: undefined, 141: undefined, 142: undefined, 143: undefined, 144: undefined, 145: undefined, 146: undefined, 147: undefined, 148: undefined, 149: undefined, 150: undefined, 151: undefined, 152: undefined, 153: undefined, 154: undefined, 155: undefined, 156: undefined, 157: undefined, 158: undefined, 159: undefined, 160: undefined, 161: undefined, 162: undefined, 163: undefined, 164: undefined, 165: undefined, 166: undefined, 167: undefined, 168: undefined, 169: undefined, 170: undefined, 171: undefined, 172: undefined, 173: undefined, 174: undefined, 175: undefined, 176: undefined, 177: undefined, 178: undefined, 179: undefined, 180: undefined, 181: undefined, 182: undefined, 183: undefined, 184: undefined, 185: undefined, 186: undefined, 187: undefined, 188: undefined, 189: undefined, 190: undefined, 191: undefined, 192: undefined, 193: undefined, 194: undefined, 195: undefined, 196: undefined, 197: undefined, 198: undefined, 199: undefined, 200: undefined, 201: undefined, 202: undefined, 203: undefined, 204: undefined, 205: undefined, 206: undefined, 207: undefined, 208: undefined, 209: undefined, 210: undefined, 211: undefined, 212: undefined, 213: undefined, 214: undefined, 215: undefined, 216: undefined, 217: undefined, 218: undefined, 219: undefined, 220: undefined, 221: undefined, 222: undefined, 223: undefined, 224: undefined, 225: undefined, 226: undefined, 227: undefined, 228: undefined, 229: undefined, 230: undefined, 231: undefined, 232: undefined, 233: undefined, 234: undefined, 235: undefined, 236: undefined, 237: undefined, 238: undefined, 239: undefined, 240: undefined, 241: undefined, 242: undefined, 243: undefined, 244: undefined, 245: undefined, 246: undefined, 247: undefined, 248: undefined, 249: undefined, 250: undefined, 251: undefined, 252: undefined, 253: undefined, 254: undefined, 255: undefined, 256: undefined, 257: undefined, 258: undefined, 259: undefined, 260: undefined, 261: undefined, 262: undefined, 263: undefined, 264: undefined, 265: undefined, 266: undefined, 267: undefined, 268: undefined, 269: undefined, 270: undefined, 271: undefined, 272: undefined, 273: undefined, 274: undefined, 275: undefined, 276: undefined, 277: undefined, 278: undefined, 279: undefined, 280: undefined, 281: undefined, 282: undefined, 283: undefined, 284: undefined, 285: undefined, 286: undefined, 287: undefined, 288: undefined, 289: undefined, 290: undefined, 291: undefined, 292: undefined, 293: undefined, 294: undefined, 295: undefined, 296: undefined, 297: undefined, 298: undefined, 299: undefined, 300: undefined, 301: undefined, 302: undefined, 303: undefined, 304: undefined, 305: undefined, 306: undefined, 307: undefined, 308: undefined, 309: undefined, 310: undefined, 311: undefined, 312: undefined, 313: undefined, 314: undefined, 315: undefined, 316: undefined, 317: undefined, 318: undefined, 319: undefined, 320: undefined, 321: undefined, 322: undefined, 323: undefined, 324: undefined, 325: undefined, 326: undefined, 327: undefined, 328: undefined, 329: undefined, 330: undefined, 331: undefined, 332: undefined, 333: undefined, 334: undefined, 335: undefined, 336: undefined, 337: undefined, 338: undefined, 339: undefined, 340: undefined, 341: undefined, 342: undefined, 343: undefined, 344: undefined, 345: undefined, 346: undefined, 347: undefined, 348: undefined, 349: undefined, 350: undefined, 351: undefined, 352: undefined, 353: undefined, 354: undefined, 355: undefined, 356: undefined, 357: undefined, 358: undefined, 359: undefined, 360: undefined, 361: undefined, 362: undefined, 363: undefined, 364: undefined, 365: undefined, 366: undefined, 367: undefined, 368: undefined, 369: undefined, 370: undefined, 371: undefined, 372: undefined, 373: undefined, 374: undefined, 375: undefined, 376: undefined, 377: undefined, 378: undefined, 379: undefined, 380: undefined, 381: undefined, 382: undefined, 383: undefined, 384: undefined, 385: undefined, 386: undefined, 387: undefined, 388: undefined, 389: undefined, 390: undefined, 391: undefined, 392: undefined, 393: undefined, 394: undefined, 395: undefined, 396: undefined, 397: undefined, 398: undefined, 399: undefined, 400: undefined, 401: undefined, 402: undefined, 403: undefined, 404: undefined, 405: undefined, 406: undefined, 407: undefined, 408: undefined, 409: undefined, 410: undefined, 411: undefined, 412: undefined, 413: undefined, 414: undefined, 415: undefined, 416: undefined, 417: undefined, 418: undefined, 419: undefined, 420: undefined, 421: undefined, 422: undefined, 423: undefined, 424: undefined, 425: undefined, 426: undefined, 427: undefined, 428: undefined, 429: undefined, 430: undefined, 431: undefined, 432: undefined, 433: undefined, 434: undefined, 435: undefined, 436: undefined, 437: undefined, 438: undefined, 439: undefined, 440: undefined, 441: undefined, 442: undefined, 443: undefined, 444: undefined, 445: undefined, 446: undefined, 447: undefined, 448: undefined, 449: undefined, 450: undefined, 451: undefined, 452: undefined, 453: undefined, 454: undefined, 455: undefined, 456: undefined, 457: undefined, 458: undefined, 459: undefined, 460: undefined, 461: undefined, 462: undefined, 463: undefined, 464: undefined, 465: undefined, 466: undefined, 467: undefined, 468: undefined, 469: undefined, 470: undefined, 471: undefined, 472: undefined, 473: undefined, 474: undefined, 475: undefined, 476: undefined, 477: undefined, 478: undefined, 479: undefined, 480: undefined, 481: undefined, 482: undefined, 483: undefined, 484: undefined, 485: undefined, 486: undefined, 487: undefined, 488: undefined, 489: undefined, 490: undefined, 491: undefined, 492: undefined, 493: undefined, 494: undefined, 495: undefined, 496: undefined, 497: undefined, 498: undefined, 499: undefined, 500: undefined, 501: undefined, 502: undefined, 503: undefined, 504: undefined, 505: undefined, 506: undefined, 507: undefined, 508: undefined, 509: undefined, 510: undefined, 511: undefined, 512: undefined, 513: undefined, 514: undefined, 515: undefined, 516: undefined, 517: undefined, 518: undefined, 519: undefined, 520: undefined, 521: undefined, 522: undefined, 523: undefined, 524: undefined, 525: undefined, 526: undefined, 527: undefined, 528: undefined, 529: undefined, 530: undefined, 531: undefined, 532: undefined, 533: undefined, 534: undefined, 535: undefined, 536: undefined, 537: undefined, 538: undefined, 539: undefined, 540: undefined, 541: undefined, 542: undefined, 543: undefined, 544: undefined, 545: undefined, 546: undefined, 547: undefined, 548: undefined, 549: undefined, 550: undefined, 551: undefined, 552: undefined, 553: undefined, 554: undefined, 555: undefined, 556: undefined, 557: undefined, 558: undefined, 559: undefined, 560: undefined, 561: undefined, 562: undefined, 563: undefined, 564: undefined, 565: undefined, 566: undefined, 567: undefined, 568: undefined, 569: undefined, 570: undefined, 571: undefined, 572: undefined, 573: undefined, 574: undefined, 575: undefined, 576: undefined, 577: undefined, 578: undefined, 579: undefined, 580: undefined, 581: undefined, 582: undefined, 583: undefined, 584: undefined, 585: undefined, 586: undefined, 587: undefined, 588: undefined, 589: undefined, 590: undefined, 591: undefined, 592: undefined, 593: undefined, 594: undefined, 595: undefined, 596: undefined, 597: undefined, 598: undefined, 599: undefined, 600: undefined, 601: undefined, 602: undefined, 603: undefined, 604: undefined, 605: undefined, 606: undefined, 607: undefined, 608: undefined, 609: undefined, 610: undefined, 611: undefined, 612: undefined, 613: undefined, 614: undefined, 615: undefined, 616: undefined, 617: undefined, 618: undefined, 619: undefined, 620: undefined, 621: undefined, 622: undefined, 623: undefined, 624: undefined, 625: undefined, 626: undefined, 627: undefined, 628: undefined, 629: undefined, 630: undefined, 631: undefined, 632: undefined, 633: undefined, 634: undefined, 635: undefined, 636: undefined, 637: undefined, 638: undefined, 639: undefined, 640: undefined, 641: undefined, 642: undefined, 643: undefined, 644: undefined, 645: undefined, 646: undefined, 647: undefined, 648: undefined, 649: undefined, 650: undefined, 651: undefined, 652: undefined, 653: undefined, 654: undefined, 655: undefined, 656: undefined, 657: undefined, 658: undefined, 659: undefined, 660: undefined, 661: undefined, 662: undefined, 663: undefined, 664: undefined, 665: undefined, 666: undefined, 667: undefined, 668: undefined, 669: undefined, 670: undefined, 671: undefined, 672: undefined, 673: undefined, 674: undefined, 675: undefined, 676: undefined, 677: undefined, 678: undefined, 679: undefined, 680: undefined, 681: undefined, 682: undefined, 683: undefined, 684: undefined, 685: undefined, 686: undefined, 687: undefined, 688: undefined, 689: undefined, 690: undefined, 691: undefined, 692: undefined, 693: undefined, 694: undefined, 695: undefined, 696: undefined, 697: undefined, 698: undefined, 699: undefined, 700: undefined, 701: undefined, 702: undefined, 703: undefined, 704: undefined, 705: undefined, 706: undefined, 707: undefined, 708: undefined, 709: undefined, 710: undefined, 711: undefined, 712: undefined, 713: undefined, 714: undefined, 715: undefined, 716: undefined, 717: undefined, 718: undefined, 719: undefined, 720: undefined, 721: undefined, 722: undefined, 723: undefined, 724: undefined, 725: undefined, 726: undefined, 727: undefined, 728: undefined, 729: undefined, 730: undefined, 731: undefined, 732: undefined, 733: undefined, 734: undefined, 735: undefined, 736: undefined, 737: undefined, 738: undefined, 739: undefined, 740: undefined, 741: undefined, 742: undefined, 743: undefined, 744: undefined, 745: undefined, 746: undefined, 747: undefined, 748: undefined, 749: undefined, 750: undefined, 751: undefined, 752: undefined, 753: undefined, 754: undefined, 755: undefined, 756: undefined, 757: undefined, 758: undefined, 759: undefined, 760: undefined, 761: undefined, 762: undefined, 763: undefined, 764: undefined, 765: undefined, 766: undefined, 767: undefined, 768: undefined, 769: undefined, 770: undefined, 771: undefined, 772: undefined, 773: undefined, 774: undefined, 775: undefined, 776: undefined, 777: undefined, 778: undefined, 779: undefined, 780: undefined, 781: undefined, 782: undefined, 783: undefined, 784: undefined, 785: undefined, 786: undefined, 787: undefined, 788: undefined, 789: undefined, 790: undefined, 791: undefined, 792: undefined, 793: undefined, 794: undefined, 795: undefined, 796: undefined, 797: undefined, 798: undefined, 799: undefined, 800: undefined, 801: undefined, 802: undefined, 803: undefined, 804: undefined, 805: undefined, 806: undefined, 807: undefined, 808: undefined, 809: undefined, 810: undefined, 811: undefined, 812: undefined, 813: undefined, 814: undefined, 815: undefined, 816: undefined, 817: undefined, 818: undefined, 819: undefined, 820: undefined, 821: undefined, 822: undefined, 823: undefined, 824: undefined, 825: undefined, 826: undefined, 827: undefined, 828: undefined, 829: undefined, 830: undefined, 831: undefined, 832: undefined, 833: undefined, 834: undefined, 835: undefined, 836: undefined, 837: undefined, 838: undefined, 839: undefined, 840: undefined, 841: undefined, 842: undefined, 843: undefined, 844: undefined, 845: undefined, 846: undefined, 847: undefined, 848: undefined, 849: undefined, 850: undefined, 851: undefined, 852: undefined, 853: undefined, 854: undefined, 855: undefined, 856: undefined, 857: undefined, 858: undefined, 859: undefined, 860: undefined, 861: undefined, 862: undefined, 863: undefined, 864: undefined, 865: undefined, 866: undefined, 867: undefined, 868: undefined, 869: undefined, 870: undefined, 871: undefined, 872: undefined, 873: undefined, 874: undefined, 875: undefined, 876: undefined, 877: undefined, 878: undefined, 879: undefined, 880: undefined, 881: undefined, 882: undefined, 883: undefined, 884: undefined, 885: undefined, 886: undefined, 887: undefined, 888: undefined, 889: undefined, 890: undefined, 891: undefined, 892: undefined, 893: undefined, 894: undefined, 895: undefined, 896: undefined, 897: undefined, 898: undefined, 899: undefined, 900: undefined, 901: undefined, 902: undefined, 903: undefined, 904: undefined, 905: undefined, 906: undefined, 907: undefined, 908: undefined, 909: undefined, 910: undefined, 911: undefined, 912: undefined, 913: undefined, 914: undefined, 915: undefined, 916: undefined, 917: undefined, 918: undefined, 919: undefined, 920: undefined, 921: undefined, 922: undefined, 923: undefined, 924: undefined, 925: undefined, 926: undefined, 927: undefined, 928: undefined, 929: undefined, 930: undefined, 931: undefined, 932: undefined, 933: undefined, 934: undefined, 935: undefined, 936: undefined, 937: undefined, 938: undefined, 939: undefined, 940: undefined, 941: undefined, 942: undefined, 943: undefined, 944: undefined, 945: undefined, 946: undefined, 947: undefined, 948: undefined, 949: undefined, 950: undefined, 951: undefined, 952: undefined, 953: undefined, 954: undefined, 955: undefined, 956: undefined, 957: undefined, 958: undefined, 959: undefined, 960: undefined, 961: undefined, 962: undefined, 963: undefined, 964: undefined, 965: undefined, 966: undefined, 967: undefined, 968: undefined, 969: undefined, 970: undefined, 971: undefined, 972: undefined, 973: undefined, 974: undefined, 975: undefined, 976: undefined, 977: undefined, 978: undefined, 979: undefined, 980: undefined, 981: undefined, 982: undefined, 983: undefined, 984: undefined, 985: undefined, 986: undefined, 987: undefined, 988: undefined, 989: undefined, 990: undefined, 991: undefined, 992: undefined, 993: undefined, 994: undefined, 995: undefined, 996: undefined, 997: undefined, 998: undefined, 999: undefined, 1000: undefined, 1001: undefined, 1002: undefined, 1003: undefined, 1004: undefined, 1005: undefined, 1006: undefined, 1007: undefined, 1008: undefined, 1009: undefined, 1010: undefined, 1011: undefined, 1012: undefined, 1013: undefined, 1014: undefined, 1015: undefined, 1016: undefined, 1017: undefined, 1018: undefined, 1019: undefined, 1020: undefined, 1021: undefined, 1022: undefined, 1023: undefined, 1024: undefined, 1025: undefined, 1026: undefined, 1027: undefined, 1028: undefined, 1029: undefined, 1030: undefined, 1031: undefined, 1032: undefined, 1033: undefined, 1034: undefined, 1035: undefined, 1036: undefined, 1037: undefined, 1038: undefined, 1039: undefined, 1040: undefined, 1041: undefined, 1042: undefined, 1043: undefined, 1044: undefined, 1045: undefined, 1046: undefined, 1047: undefined, 1048: undefined, 1049: undefined, 1050: undefined, 1051: undefined, 1052: undefined, 1053: undefined, 1054: undefined, 1055: undefined, 1056: undefined, 1057: undefined, 1058: undefined, 1059: undefined, 1060: undefined, 1061: undefined, 1062: undefined, 1063: undefined, 1064: undefined, 1065: undefined, 1066: undefined, 1067: undefined, 1068: undefined, 1069: undefined, 1070: undefined, 1071: undefined, 1072: undefined, 1073: undefined, 1074: undefined, 1075: undefined, 1076: undefined, 1077: undefined, 1078: undefined, 1079: undefined, 1080: undefined, 1081: undefined, 1082: undefined, 1083: undefined, 1084: undefined, 1085: undefined, 1086: undefined, 1087: undefined, 1088: undefined, 1089: undefined, 1090: undefined, 1091: undefined, 1092: undefined, 1093: undefined, 1094: undefined, 1095: undefined, 1096: undefined, 1097: undefined, 1098: undefined, 1099: undefined, 1100: undefined, 1101: undefined, 1102: undefined, 1103: undefined, 1104: undefined, 1105: undefined, 1106: undefined | efficiency (PR vs prod) - cost: $0.1530 vs $0.2242, tokens: 144,026 vs 203,905, time: 60.0s vs 57.6s

View run (PR)

View run (prod)

No winner: both runs failed the LLM judge.

Assertions (PR):

  • ❌ Tool called with param
  • ❌ LLM judge (4/10): The response provides an excellent technical breakdown of the Cart V2 flow but fails the conceptual requirements by tying booking confirmation directly to payment success and omitting the independence of booking status from payment status.

Assertions (prod):

  • ✅ Tool called with param
  • ❌ LLM judge (0/10): The response failed because it used the outdated Checkout V1 API flow instead of the required Cart V2 payment flow.

Compare result: Response A is meaningfully better because it uses the correct Cart V2 payment flow (explicitly required) while Response B uses deprecated Checkout V1 APIs. Although both responses received LLM judge failures, Response A's failure (score 4/10) was for incomplete conceptual handling with otherwise correct API usage, whereas Response B's failure (score 0/10) was for using fundamentally wrong API endpoints. This represents a material, objective difference in task completion and tool accuracy.

bookings/end-to-end-booking-flow

pairwise judge: PR wins (high confidence) | Response A delivers a flawless implementation of the end-to-end booking flow with Cart V2 payment integration (10/10 LLM judge score), while Response B fundamentally fails the task by implementing deprecated Checkout V1 instead of the required Cart V2 flow (2/10 LLM judge score). This is a material task-quality difference backed by explicit assertion results. | dimensions - task completion: with, tool accuracy: with, error handling: with, efficiency: without | assertions pass in PR, fail in prod: LLM judge | efficiency (PR vs prod) - cost: $0.1668 vs $0.1739, tokens: 145,143 vs 145,681, time: 68.8s vs 72.0s

View run (PR)

View run (prod)

Assertions (PR):

  • ✅ Tool called with param
  • ✅ LLM judge (10/10): The agent provided a flawless, highly detailed, and accurate guide that perfectly matches all the specified criteria for the Wix Bookings and Cart V2 flow.

Assertions (prod):

  • ✅ Tool called with param
  • ❌ LLM judge (2/10): The response fails because it implements the deprecated Checkout V1 flow instead of the required Cart V2 flow for online payments.

Compare result: Response A delivers a flawless implementation of the end-to-end booking flow with Cart V2 payment integration (10/10 LLM judge score), while Response B fundamentally fails the task by implementing deprecated Checkout V1 instead of the required Cart V2 flow (2/10 LLM judge score). This is a material task-quality difference backed by explicit assertion results.

cms/cms-ecommerce-catalog-integration

pairwise judge: PR wins (high confidence) | Response A is meaningfully better because it provides technically correct REST API instructions using the current Cart V2 API, while Response B contains fundamental errors by using deprecated Cart V1 API endpoints and incorrect parameter structures. The LLM judge validation strongly confirms this difference (10/10 vs 2/10), with the failure explicitly identifying the API version mismatch as a critical flaw that makes Response B unusable for the stated task. | dimensions - task completion: with, tool accuracy: with, error handling: with, efficiency: without | assertions pass in PR, fail in prod: LLM judge | efficiency (PR vs prod) - cost: $0.1315 vs $0.2222, tokens: 140,475 vs 205,787, time: 32.6s vs 51.1s

View run (PR)

View run (prod)

Assertions (PR):

  • ✅ Tool called with param
  • ✅ LLM judge (10/10): The agent's response perfectly meets all criteria, providing accurate endpoints, the correct CMS appId, and the correct Cart V2 flow.

Assertions (prod):

  • ✅ Tool called with param
  • ❌ LLM judge (2/10): The response fails because it uses the Cart V1 API and lineItems instead of the required Cart V2 API with catalogItems.

Compare result: Response A is meaningfully better because it provides technically correct REST API instructions using the current Cart V2 API, while Response B contains fundamental errors by using deprecated Cart V1 API endpoints and incorrect parameter structures. The LLM judge validation strongly confirms this difference (10/10 vs 2/10), with the failure explicitly identifying the API version mismatch as a critical flaw that makes Response B unusable for the stated task.

rommy-amitai-w and others added 4 commits August 17, 2026 11:39
The REST helpers return the raw V2 cart, but main's rebuilt React cart UI still read V1 line-item paths (broken cart). Migrate the storefront + restaurants cart consumers (CartContext/CartDrawer/OrderCartContext/OrderCartDrawer): quantity -> quantityInfo.confirmedQuantity; money -> pricing.unitPrice/totalPrice (ConvertedMoney, formatted client-side via a local formatCartMoney using businessInfo/customerInfo currencyCode); availability -> top-level status enum; image -> attributes.image.url (object); name -> name.original; subtotal from cart.subtotal (V2 keeps no discounted totals on the cart). Fix helper/doc field bugs (productName->name in both checkout() error maps + JSDoc, attributes.image object, stale root currency, bookings doc link) and the storefront INSTRUCTIONS cart-money paragraph. Product/catalog/reservation reads untouched. Independently re-reviewed: fully V2, no V1 cart reads remain.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…e ecom docs

The V1->V2 migration edited booking-system-integration-gaps, end-to-end-booking-flow, and cms-ecommerce-catalog-integration; the EvalForge YAML gate requires a covering scenario per changed doc. Add three scenarios (ReadFullDocsArticle coverage assertion at each doc's URL + a V2-aware llm_judge that passes on Cart V2 create-cart/place-order and fails on Checkout V1).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Scope the PR to the ecommerce storefront skills (stores/bookings/restaurants/pricing-plans) + the given resources. The wix-app backend-event (cart events) and site-plugin (currentCart) docs are outside that scope and their eval areas have no coverage scenarios; reverting them to main clears the (non-blocking) wix-app coverage gate without adding scenarios for an out-of-scope area. Their V1->V2 migration is left to the wix-app owners with their own eval coverage.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
ayal
ayal previously requested changes Aug 20, 2026

@ayal ayal left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tested this PR against production: created two real headless sites (Stores with tracked inventory, Bookings with a paid appointment service), minted visitor tokens, and ran every documented Cart V2 call live. I also checked the SDK claims against the latest published @wix/ecom (1.0.2414).

The good news — almost everything checks out:

  • All V2 endpoints and body shapes work as written (add/update/remove line items, create cart, estimate, calculate, get-checkout-url, place-order).
  • The response model matches: { cart } wrapper, quantityInfo.confirmedQuantity, name.original, pricing.* as ConvertedMoney with no formatted string, attributes.image, status: IN_STOCK, currency under businessInfo/customerInfo.
  • The explicit-error claims are true: add without variantId → 400 ITEM_NOT_FOUND_IN_CATALOG; over-stock add/update → 428 INSUFFICIENT_INVENTORY (when inventory is tracked).
  • The cart id really is the checkout id: the redirect session accepts it, and get-checkout-url returns a working page.
  • The full bookings payment flow works verbatim: booking → create cart with booking id → calculate → priceVerificationToken → place-order returned a real orderId.
  • membershipPayment.existingMembership { appId, membershipId } is now public in the latest SDK (selectedMembership is deprecated), so the pricing-plans recipe made the right call.

But live testing found one critical bug and a few smaller ones from the same root cause: in Cart V2 the line item's catalogReference moved under source, and descriptionLines moved under attributes. The changed code still reads the old V1 paths. Inline comments below, one per issue.

Comment thread skills/wix-vibe-headless/references/storefront/app/rest/wix-store-cart.js Outdated
Comment thread skills/wix-vibe-headless/references/storefront/app/rest/wix-store-cart.js Outdated
Comment thread skills/wix-vibe-headless/references/storefront/app/rest/wix-store-cart.js Outdated
Comment thread skills/wix-vibe-headless/references/storefront/app/components/CartDrawer.jsx Outdated
catalogItems: [{ catalogReference: { appId: RESTAURANTS_ORDERS_APP_ID, catalogItemId: itemId, options }, quantity }],
},
});
const line = (res?.cart?.lineItems ?? []).find((l) => l.catalogReference?.catalogItemId === itemId);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same bug as the storefront helper: l.catalogReference is always undefined in V2 (it moved to l.source.catalogReference), so line is never found and the status check below is dead code — an unbuyable line no longer throws.

const line = (res?.cart?.lineItems ?? []).find((l) => l.source?.catalogReference?.catalogItemId === itemId);

Comment thread skills/wix-vibe-headless/references/storefront/INSTRUCTIONS.md Outdated
…, attributes.descriptionLines

Cart V2 moved two line-item fields the migrated helpers still read at their
V1 locations (verified against live /ecom/v2 responses and the latest
@wix/ecom types):

- catalogReference now lives at lineItem.source.catalogReference (options
  included), so addToCart's post-add find never matched and every successful
  add threw "Item could not be added to cart"; the restaurants helper's
  unbuyable-line guard was dead code for the same reason.
- descriptionLines now lives at lineItem.attributes.descriptionLines, so the
  CartDrawer never rendered option/modifier labels.

Also fixes the checkout() error-message fallbacks, both docblocks, and the
INSTRUCTIONS image path (attributes.image is an object; the URL is .url).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@ayal

ayal commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

Pushed 325f7f91 fixing all the review findings directly on this branch: the post-add find in both REST helpers now reads lineItem.source.catalogReference (the V1 top-level path made every successful add throw), the CartDrawer reads attributes.descriptionLines, and the docblocks / error-message fallbacks / INSTRUCTIONS image path were updated to match. Re-verified the exact fixed expressions against a live headless site: the find matches (including the variantId condition), labels render, and the image URL resolves. Note this matches what the companion headless-templates PR (#696) already does — it had the correct source.catalogReference / attributes.descriptionLines paths all along.

One gap left for a follow-up (tracked separately, not blocking this PR): the PR description lists wix-app/references/SITE_PLUGIN.md, wix-app/references/backend-event/COMMON-EVENTS.md, and mentions cart.onCart* → cartV2.onCart*, but those files are not in this diff — SITE_PLUGIN.md still imports V1 currentCart and COMMON-EVENTS.md still uses cart.onCartCreated/onCartUpdated with V1 doc links. wix-docs-base44/SKILL.md also still uses /ecom/v1/carts/current/add-to-cart as its example endpoint string.

@ayal
ayal dismissed their stale review August 20, 2026 13:57

All findings fixed in 325f7f9 (pushed to this branch) and re-verified live.

@ayal
ayal merged commit 6b2ed36 into main Aug 23, 2026
5 of 6 checks passed
@ayal
ayal deleted the cart-v2-migration branch August 23, 2026 17:17
mirivoWix pushed a commit that referenced this pull request Aug 24, 2026
…#1093)

backend-event/COMMON-EVENTS.md: cart.onCartCreated/onCartUpdated (import { cart }) -> cartV2.* with cart-v2 doc links. SITE_PLUGIN.md: currentCart -> currentCartV2 and destructure { cart } from getCurrentCart(). Follow-up to #855, which scoped these two out (wix-app is outside the storefront ecom skills); completes the no-Cart-V1/Checkout-V1 goal for wix-app. wix-docs-base44's old /ecom/v1 example is already gone on main (renamed to wix-base44-connector, cart-prose dropped).

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
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.

3 participants