[skills] Migrate all cart/checkout references to Cart V2 - #855
Conversation
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>
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>
…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>
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>
| **⚠️ 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 |
There was a problem hiding this comment.
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) |
There was a problem hiding this comment.
and this needs careful checking
…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>
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>
# 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>
|
|
| 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
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
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
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
lineItemsinstead of the required Cart V2 API withcatalogItems.
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.
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
left a comment
There was a problem hiding this comment.
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 underbusinessInfo/customerInfo. - The explicit-error claims are true: add without
variantId→ 400ITEM_NOT_FOUND_IN_CATALOG; over-stock add/update → 428INSUFFICIENT_INVENTORY(when inventory is tracked). - The cart id really is the checkout id: the redirect session accepts it, and
get-checkout-urlreturns a working page. - The full bookings payment flow works verbatim: booking → create cart with booking id → calculate →
priceVerificationToken→ place-order returned a realorderId. membershipPayment.existingMembership { appId, membershipId }is now public in the latest SDK (selectedMembershipis 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.
| catalogItems: [{ catalogReference: { appId: RESTAURANTS_ORDERS_APP_ID, catalogItemId: itemId, options }, quantity }], | ||
| }, | ||
| }); | ||
| const line = (res?.cart?.lineItems ?? []).find((l) => l.catalogReference?.catalogItemId === itemId); |
There was a problem hiding this comment.
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);…, 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>
|
Pushed One gap left for a follow-up (tracked separately, not blocking this PR): the PR description lists |
All findings fixed in 325f7f9 (pushed to this branch) and re-verified live.
…#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>
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/ecomCartV1ProxyScala 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 withmain.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) andwix-docs-base44carry 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-pluginsSPI, 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.mdwix-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.mdwix-replatform/resources/rp-mapper/wix-business-solutions-taxonomy.mdyaml/wix-manage-evals/bookings/{booking-ecom-payment-integration,end-to-end-booking-flow}.yml,cms/cms-ecommerce-catalog-integration.yml— EvalForge coverage for the changedwix-managedocs (the coverage gate is blocking forwix-manage).Key changes (V1 → V2)
currentCart/cart/checkoutcurrentCartV2/cartV2addToCurrentCart({ lineItems })addLineItemsToCurrentCart({ catalogItems })/ecom/v1/carts/current/*,/ecom/v1/checkouts/ecom/v2/carts/current/*,/ecom/v2/cartscreateCheckout*→checkoutId;createOrderplace-order(token fromcalculate){ cart }(cart is optional)quantity,productName,price,image,url,descriptionLines,availability.statusquantityInfo.confirmedQuantity,name,pricing.unitPrice/totalPrice,attributes.image/.url/.descriptionLines, top-levelstatusMultiCurrencyPrice/formattedAmountConvertedMoney(amount/convertedAmount, no formatted string) — formatted client-sideAVAILABLE/NOT_AVAILABLE/…IN_STOCK/OUT_OF_STOCK/PARTIALLY_IN_STOCK/REMOVED_FROM_CATALOGmembershipOptions.selectedMembershipsmembershipPayment: { existingMembership: { membershipId, appId } }; read backpaymentConfig.membership200/ silent quantity clampType verification
Cart calls in the snippets were checked against the real public
@wix/ecomcart-v2 / current-cart-v2 types:membershipPayment(MembershipInput={ existingMembership: { appId, membershipId } }/futureMembership) and the read fieldpaymentConfig.membershipare the GA replacements for the deprecatedselectedMembership. 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.summary.paymentSummary.memberships(fromcalculate/estimate) reports memberships already applied, and an exhausted plan surfaces as asummary.violationsentry — the recipe uses that instead of a candidate/remaining read (which the cart doesn't expose).getCheckoutUrlis lowercase-Url;getCurrentCart().cartis optional (guarded).Testing
Docs/reference; all
.js/.jsxreference 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-appcart events + site-plugin → V2): #1093 — (wix-docs-base44's old/ecom/v1example was already resolved onmain: renamed towix-base44-connectorin #1059, cart-prose dropped in #1083.)