@cartbase/storefront 0.1.2 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (106) hide show
  1. package/README.md +3 -3
  2. package/package.json +231 -226
  3. package/src/api/auth.ts +1 -1
  4. package/src/api/carts.ts +5 -3
  5. package/src/api/checkout.ts +91 -40
  6. package/src/api/consent.ts +2 -2
  7. package/src/api/integrations.ts +4 -17
  8. package/src/api/regions.ts +1 -1
  9. package/src/cart-drawer/context.tsx +4 -4
  10. package/src/cart-drawer/cross-sell-carousel.tsx +1 -1
  11. package/src/cart-drawer/cross-sell-sidebar.tsx +1 -1
  12. package/src/cart-drawer/header.tsx +1 -1
  13. package/src/cart-drawer/item/index.tsx +2 -2
  14. package/src/cart-drawer/item/quantity.tsx +2 -2
  15. package/src/cart-drawer/item/upsell.tsx +3 -3
  16. package/src/cart-drawer/item/variant.tsx +2 -2
  17. package/src/cart-drawer/labels-bg.ts +2 -2
  18. package/src/cart-drawer/labels.ts +119 -119
  19. package/src/cart-drawer/summary-breakdown.tsx +197 -196
  20. package/src/cart-drawer/template.tsx +2 -2
  21. package/src/cart-drawer/tiered-progress.tsx +1 -1
  22. package/src/checkout/address-error-copy.ts +3 -3
  23. package/src/checkout/address-form.tsx +2 -2
  24. package/src/checkout/address-select.tsx +1 -1
  25. package/src/checkout/boxnow-locker-selector.tsx +3 -3
  26. package/src/checkout/checkout-client.tsx +15 -12
  27. package/src/checkout/company-details.tsx +1 -1
  28. package/src/checkout/compare-addresses.ts +1 -1
  29. package/src/checkout/discount-section.tsx +5 -5
  30. package/src/checkout/econt-office-selector.tsx +2 -2
  31. package/src/checkout/gift-card-section.tsx +2 -2
  32. package/src/checkout/index.ts +0 -1
  33. package/src/checkout/labels-bg.ts +2 -2
  34. package/src/checkout/labels.ts +263 -263
  35. package/src/checkout/line-item-card.tsx +2 -2
  36. package/src/checkout/order-summary.tsx +48 -48
  37. package/src/checkout/payment-button.tsx +4 -4
  38. package/src/checkout/payment-error-copy.ts +6 -6
  39. package/src/checkout/payment-method-list.tsx +93 -33
  40. package/src/checkout/payment-wrapper.tsx +8 -11
  41. package/src/checkout/promotion-error-copy.ts +2 -2
  42. package/src/checkout/shipping-method-list.tsx +2 -2
  43. package/src/checkout/stripe-wrapper.tsx +1 -1
  44. package/src/checkout/use-checkout-orchestration.ts +108 -98
  45. package/src/common/cart-button-client.tsx +1 -1
  46. package/src/common/cart-button.tsx +1 -1
  47. package/src/common/country-select.tsx +2 -2
  48. package/src/common/delete-button.tsx +1 -1
  49. package/src/common/index.ts +1 -1
  50. package/src/common/language-select.tsx +2 -2
  51. package/src/common/localized-link.tsx +1 -1
  52. package/src/lib/cart-helpers.ts +2 -2
  53. package/src/lib/cookie-names.ts +41 -0
  54. package/src/lib/get-product-price.ts +3 -3
  55. package/src/lib/payment-constants.ts +53 -66
  56. package/src/lib/store-api-error.ts +1 -1
  57. package/src/order/index.ts +1 -1
  58. package/src/order/labels-bg.ts +39 -39
  59. package/src/order/labels.ts +79 -79
  60. package/src/order/order-address-card.tsx +1 -1
  61. package/src/order/order-completed-template.tsx +20 -12
  62. package/src/order/order-confirmation-header.tsx +1 -1
  63. package/src/order/order-delivery-card.tsx +3 -3
  64. package/src/order/order-item.tsx +2 -2
  65. package/src/order/order-items-list.tsx +3 -3
  66. package/src/order/order-payment-card.tsx +27 -36
  67. package/src/order/order-timeline.tsx +2 -2
  68. package/src/order/order-totals.tsx +250 -245
  69. package/src/platform/identity.ts +18 -0
  70. package/src/platform/index.ts +8 -0
  71. package/src/platform/metadata.ts +26 -0
  72. package/src/platform/platform-init.tsx +46 -0
  73. package/src/products/image-gallery.tsx +1 -1
  74. package/src/products/mobile-actions.tsx +1 -1
  75. package/src/products/option-select.tsx +1 -1
  76. package/src/products/preview-price.tsx +1 -1
  77. package/src/products/product-actions.tsx +6 -6
  78. package/src/products/product-info.tsx +1 -1
  79. package/src/products/product-preview.tsx +1 -1
  80. package/src/products/product-price.tsx +2 -2
  81. package/src/products/product-tabs.tsx +1 -1
  82. package/src/products/purchase-options.tsx +1 -1
  83. package/src/products/related-products.tsx +3 -3
  84. package/src/products/variant-matching.ts +4 -4
  85. package/src/reviews-ui/labels.ts +1 -1
  86. package/src/reviews-ui/photo-upload.tsx +1 -1
  87. package/src/reviews-ui/review-list.tsx +1 -1
  88. package/src/reviews-ui/review-widget.tsx +1 -1
  89. package/src/reviews-ui/review-wizard.tsx +1 -1
  90. package/src/reviews-ui/wizard-state.ts +1 -1
  91. package/src/store/category-template.tsx +2 -2
  92. package/src/store/collection-template.tsx +2 -2
  93. package/src/store/labels.ts +2 -2
  94. package/src/store/paginated-products.tsx +1 -1
  95. package/src/store/search-params.ts +1 -1
  96. package/src/store/search-template.tsx +1 -1
  97. package/src/tracking/consent-banner.tsx +1 -1
  98. package/src/tracking/consent-init.tsx +1 -1
  99. package/src/tracking/consent.ts +6 -6
  100. package/src/tracking/fbq.ts +2 -2
  101. package/src/tracking/get-tracking-attribution.ts +1 -1
  102. package/src/tracking/get-tracking-config.ts +2 -2
  103. package/src/tracking/index.ts +2 -2
  104. package/src/tracking/meta-pixel.tsx +1 -1
  105. package/src/tracking/rybbit.tsx +1 -1
  106. package/src/tracking/types.ts +6 -6
@@ -6,10 +6,10 @@
6
6
  * 1. **Orchestrated (recommended)** — `prepareCheckout()` is the atomic
7
7
  * Buy-click: ONE call writes address (+billing mirror), shipping method
8
8
  * (+ carrier metadata), payment collection and the payment session at
9
- * the FINAL amount (real Stripe PaymentIntent, or a plain row for
10
- * pp_cod/pp_manual). Then `completeCart()` (see `./carts`). Amount
11
- * drift/repair between the two: `syncPaymentAmount()` and
12
- * `refreshPaymentIfTerminal()`.
9
+ * the FINAL amount (real Stripe PaymentIntent for a processor, or a
10
+ * provider-less row for a merchant method). Then `completeCart()`
11
+ * (see `./carts`). Amount drift/repair between the two:
12
+ * `syncPaymentAmount()` and `refreshPaymentIfTerminal()`.
13
13
  *
14
14
  * 2. **Manual (Medusa-style)** — `listShippingOptions()` →
15
15
  * `addShippingMethod()` → `createPaymentCollection()` →
@@ -137,28 +137,54 @@ export interface ListPaymentProvidersQuery {
137
137
  cart_id?: string
138
138
  }
139
139
 
140
- /** Row of GET /api/store/payment-providers. */
141
- export interface StorePaymentProvider {
142
- /** e.g. `pp_stripe`, `pp_cod`, `pp_manual`. `pp_giftcard` is internal and never listed. */
140
+ /** A connected PROCESSOR entry of GET /api/store/payment-providers. */
141
+ export interface StorePaymentProcessorEntry {
142
+ /** e.g. `pp_stripe`. `pp_giftcard` is internal and never listed. */
143
143
  id: string
144
144
  is_enabled: boolean
145
145
  created_at?: string
146
146
  }
147
147
 
148
+ /** A merchant PAYMENT METHOD entry (pp_* kill, 20260811250000): methods
149
+ * stand alone — no provider id anywhere. Initiate sessions with
150
+ * `payment_method_id`; `kind === "cod"` marks the pre-created
151
+ * collection-on-delivery method (courier cash collection); `instructions`
152
+ * is the merchant's checkout note, rendered under the method. */
153
+ export interface StorePaymentMethodEntry {
154
+ payment_method_id: string
155
+ name: string
156
+ kind: "manual" | "cod"
157
+ instructions: string | null
158
+ /** The method's fee (any method may carry one) — predict
159
+ * `payment_method_fee_total` from it before a session exists. */
160
+ fee_amount: number | null
161
+ fee_label: string | null
162
+ }
163
+
164
+ /** Row of GET /api/store/payment-providers — a processor or a method. */
165
+ export type StorePaymentEntry = StorePaymentProcessorEntry | StorePaymentMethodEntry
166
+
167
+ /** True when the entry is a merchant payment method (vs a processor). */
168
+ export const isMethodEntry = (
169
+ entry: StorePaymentEntry
170
+ ): entry is StorePaymentMethodEntry => "payment_method_id" in entry
171
+
148
172
  export interface PaymentProviderListResponse extends ListEnvelope {
149
- payment_providers: StorePaymentProvider[]
173
+ payment_providers: StorePaymentEntry[]
150
174
  }
151
175
 
152
176
  /**
153
- * List enabled payment providers (rule-filtered, display-ordered). → 200
154
- * list envelope; `count`/`limit` = full filtered list (no pagination).
155
- * Without `region_id`: the tenant's enabled providers
156
- * (`tenant_payment_providers` enabled catalog rows). With `region_id`:
157
- * providers linked to that region.
177
+ * List everything payable (rule-filtered, display-ordered): connected
178
+ * processors + every ENABLED merchant method. → 200 list envelope;
179
+ * `count`/`limit` = full filtered list (no pagination). An empty list is
180
+ * honest: a fresh store cannot take money until the merchant connects a
181
+ * processor, flips the COD switch, or creates a manual method
182
+ * (no-payment-method-by-default).
158
183
  * Auth: anon `x-client-id`.
159
- * Settings: provider enablement (admin integrations — enabling the COD or
160
- * Stripe integration provisions `pp_cod`/`pp_stripe`), checkout rules
161
- * (`target_type=payment_method`) + `checkout_method_order`.
184
+ * Settings: processor enablement (admin integrations), the Payments
185
+ * settings methods manager, checkout rules (`target_type=payment_method`,
186
+ * methods participate under their `payment_method_id`) +
187
+ * `checkout_method_order`.
162
188
  */
163
189
  export async function listPaymentProviders(
164
190
  client: StorefrontClient,
@@ -213,12 +239,18 @@ export async function createPaymentCollection(
213
239
  }
214
240
 
215
241
  export interface InitiatePaymentSessionInput {
216
- /** `pp_stripe` | `pp_cod` | `pp_manual` — NEVER `pp_giftcard` (→ 400 `invalid_provider`). */
217
- provider_id: string
242
+ /** A connected processor (`pp_stripe`) — NEVER `pp_giftcard` (→ 400
243
+ * `invalid_provider`). Exactly ONE of `provider_id` /
244
+ * `payment_method_id` (→ 400 `invalid_data` otherwise). */
245
+ provider_id?: string
246
+ /** A merchant payment method (`payment_method_id` from the listing's
247
+ * method entries) — the session lands with `provider_id` NULL and the
248
+ * method snapshot (`payment_method_id`/`_name`/`_kind`) in `data`. */
249
+ payment_method_id?: string
218
250
  /**
219
- * Merged into the session's `data` blob. Provider-state keys
251
+ * Merged into the session's `data` blob. Server-owned keys
220
252
  * (`payment_intent_id`, `client_secret`, `status`, `stripe_customer_id`,
221
- * `setup_future_usage`) are server-owned and stripped.
253
+ * `setup_future_usage`, and the method snapshot keys) are stripped.
222
254
  */
223
255
  data?: Record<string, unknown>
224
256
  /**
@@ -233,16 +265,19 @@ export interface InitiatePaymentSessionInput {
233
265
 
234
266
  export interface StorePaymentSession {
235
267
  id: string
236
- provider_id: string
237
- /** `collection.amount gift_card_total` — the remainder this provider charges. */
268
+ /** The processor, or NULL for a merchant-method session (the method
269
+ * snapshot lives in `data`). */
270
+ provider_id: string | null
271
+ /** `collection.amount − gift_card_total` — the remainder this tender charges. */
238
272
  amount: MajorUnitAmount
239
273
  currency_code: string
240
274
  /** `pending` until authorized at complete. */
241
275
  status: string
242
276
  authorized_at: string | null
243
277
  /**
244
- * Provider blob. For Stripe: `payment_intent_id`, `client_secret`
245
- * (mount Stripe Elements with it), `status`. Plain row for pp_cod/pp_manual.
278
+ * Tender blob. For Stripe: `payment_intent_id`, `client_secret`
279
+ * (mount Stripe Elements with it), `status`. For methods: the snapshot
280
+ * `payment_method_id` / `payment_method_name` / `payment_method_kind`.
246
281
  */
247
282
  data: Record<string, unknown> | null
248
283
  [key: string]: unknown
@@ -260,10 +295,11 @@ export interface InitiatePaymentSessionResponse {
260
295
  * in place; terminal PIs self-heal by rotation.
261
296
  * Auth: anon `x-client-id`.
262
297
  * Errors: 404 `payment_collection_not_found`, 400 `invalid_provider`
263
- * (pp_giftcard) | `stripe_not_configured` | `validation_failed`.
298
+ * (pp_giftcard / unknown processor) | `invalid_data` (tender XOR violated,
299
+ * unknown/disabled method) | `stripe_not_configured` | `validation_failed`.
264
300
  * Settings: Stripe credentials (admin integrations); gift-card tender
265
- * shrinks the session amount; COD fee appears on the cart the moment a live
266
- * pp_cod session exists.
301
+ * shrinks the session amount; the COD fee appears on the cart the moment a
302
+ * live COD-method session exists.
267
303
  */
268
304
  export async function initiatePaymentSession(
269
305
  client: StorefrontClient,
@@ -312,28 +348,37 @@ export interface PrepareCheckoutInput {
312
348
  * switching carriers never leaks stale fields into the order.
313
349
  */
314
350
  carrier_metadata?: Record<string, unknown>
315
- /** `pp_stripe` | `pp_cod` | `pp_manual` — never `pp_giftcard` (→ 400 `invalid_provider`). */
316
- payment_provider: string
351
+ /** A connected processor (`pp_stripe`) — never `pp_giftcard`. Exactly ONE
352
+ * of `payment_provider` / `payment_method_id`. */
353
+ payment_provider?: string
354
+ /** A merchant payment method — the session lands provider-less with the
355
+ * method snapshot (pp_* kill, 20260811250000). */
356
+ payment_method_id?: string
317
357
  }
318
358
 
319
359
  /** Response of prepare-checkout (verbatim src/lib/checkout-orchestration/prepare.ts). */
320
360
  export interface PrepareCheckoutResult {
321
361
  cart_id: string
322
362
  payment_collection_id: string | null
323
- /** Stripe Elements secret; null for pp_cod/pp_manual and zero-remainder carts. */
363
+ /** Stripe Elements secret; null for method sessions and zero-remainder carts. */
324
364
  client_secret: string | null
325
- /** The provider whose session was minted; null when zero-remainder skipped the session. */
365
+ /** The processor whose session was minted; null for method sessions and
366
+ * when zero-remainder skipped the session. */
326
367
  provider_id: string | null
368
+ /** The method whose session was minted; null for processor sessions and
369
+ * when zero-remainder skipped the session. */
370
+ payment_method_id: string | null
327
371
  }
328
372
 
329
373
  /**
330
374
  * Atomic Buy-click step 1 of 2. ONE call writes address (+billing mirror) +
331
375
  * carrier metadata → shipping method (priced against the new destination) →
332
376
  * payment collection at the shipped total → payment session at the FINAL
333
- * amount. For pp_cod the native fee applies once the session exists, so
334
- * amounts are re-synced after it. Zero-remainder carts (gift cards cover
335
- * the total) skip the provider session — `client_secret`/`provider_id`
336
- * come back null and the cart completes on the gift session.
377
+ * amount. For the COD method the native fee applies once the session
378
+ * exists, so amounts are re-synced after it. Zero-remainder carts (gift
379
+ * cards cover the total) skip the tender session — `client_secret`,
380
+ * `provider_id` and `payment_method_id` come back null and the cart
381
+ * completes on the gift session.
337
382
  *
338
383
  * Fully compensated (wire-pattern): any failure rolls back session →
339
384
  * collection → shipping method → addresses/metadata to the pre-call
@@ -341,13 +386,14 @@ export interface PrepareCheckoutResult {
341
386
  * `checkout_error_logs` (step `prepare-checkout`).
342
387
  *
343
388
  * After prepare: Stripe → `stripe.confirmPayment(client_secret)` →
344
- * `completeCart()`; COD/manual → `completeCart()` directly.
389
+ * `completeCart()`; merchant methods → `completeCart()` directly.
345
390
  *
346
391
  * Auth: anon `x-client-id`.
347
392
  * Errors: 404 `cart_not_found` | `shipping_option_not_found`, 409
348
393
  * `cart_completed`, 400 `validation_failed` | `invalid_provider` |
349
- * `shipping_price_missing` | `stripe_not_configured`.
350
- * Settings: Stripe credentials, COD integration fee, gift-card tender,
394
+ * `invalid_data` (tender XOR violated) | `shipping_price_missing` |
395
+ * `stripe_not_configured`.
396
+ * Settings: Stripe credentials, the COD method's fee, gift-card tender,
351
397
  * checkout rules (enforced at listings + complete, not here).
352
398
  */
353
399
  export async function prepareCheckout(
@@ -358,10 +404,14 @@ export async function prepareCheckout(
358
404
  return client.post(`/api/store/carts/${cartId}/prepare-checkout`, input)
359
405
  }
360
406
 
361
- /** Body of POST /api/store/carts/:id/sync-payment-amount (`.strict()`). */
407
+ /** Body of POST /api/store/carts/:id/sync-payment-amount (`.strict()`).
408
+ * At most ONE of the two — the requested tender; omit both to sync
409
+ * whatever session is pending. */
362
410
  export interface SyncPaymentAmountInput {
363
- /** Rotate to this provider when it differs from the pending session's. */
411
+ /** Rotate to this processor when the pending session's tender differs. */
364
412
  provider_id?: string
413
+ /** Rotate to this merchant method when the pending session's tender differs. */
414
+ payment_method_id?: string
365
415
  }
366
416
 
367
417
  /** Response matrix (verbatim src/lib/checkout-orchestration/sync.ts). */
@@ -371,6 +421,7 @@ export interface SyncPaymentAmountResult {
371
421
  rotated?: boolean
372
422
  client_secret?: string | null
373
423
  provider_id?: string | null
424
+ payment_method_id?: string | null
374
425
  /** No-op reasons: `cart-completed` | `no_payment_collection` | `no_pending_session`. */
375
426
  reason?: string
376
427
  }
@@ -10,7 +10,7 @@
10
10
  * fetch — resolve the config server-side (RSC) and inline it. Render the
11
11
  * built-in banner only when `enabled && mode === "builtin"`. In `external`
12
12
  * mode the merchant's CMP owns the UI and must write the same `_1c_consent`
13
- * cookie (or call `setConsent()`) — all barter-side tag gating works off
13
+ * cookie (or call `setConsent()`) — all Cartbase-side tag gating works off
14
14
  * that one seam. Choices persist 12 months.
15
15
  */
16
16
 
@@ -45,7 +45,7 @@ export interface ConsentCopy {
45
45
  */
46
46
  export interface ConsentConfig {
47
47
  enabled: boolean
48
- /** `builtin` = barter renders the banner; `external` = merchant CMP owns UI. */
48
+ /** `builtin` = Cartbase renders the banner; `external` = merchant CMP owns UI. */
49
49
  mode: "builtin" | "external"
50
50
  /** `modal` = blocking centered modal; `banner-bottom` = non-blocking bar. */
51
51
  layout: "modal" | "banner-bottom"
@@ -7,9 +7,10 @@
7
7
  * src/lib/tracking/store-config-block.ts.
8
8
  *
9
9
  * The config payload is COMPOSED from an ordered block registry — each
10
- * block owns distinct top-level keys (`carriers`, `cod`, `tracking` today;
11
- * future blocks append). NOT wrapped in an envelope: the blocks ARE the
12
- * top-level keys.
10
+ * block owns distinct top-level keys (`carriers`, `tracking` today; future
11
+ * blocks append). NOT wrapped in an envelope: the blocks ARE the top-level
12
+ * keys. (The `cod` block died with the 'cod' integration, 2026-08-11
13
+ * method fees now ride the payment listing entries themselves.)
13
14
  *
14
15
  * SECURITY LAW: every block is an explicit allowlist — credentials
15
16
  * (carrier API keys, CAPI access_token, GA4 api_secret, Klaviyo
@@ -33,19 +34,6 @@ export interface PublicCarrierConfig {
33
34
  lockers_url?: string
34
35
  }
35
36
 
36
- /** COD checkout block — null unless enabled AND fee_amount > 0 (the exact
37
- * gate the totals engine applies, so the optimistic fee row never disagrees
38
- * with the charged total). */
39
- export interface PublicCodConfig {
40
- enabled: true
41
- /** EUR major units. */
42
- fee_amount: number
43
- fee_currency: "eur"
44
- fee_label: string
45
- /** Admin's checkout note, or null. */
46
- description: string | null
47
- }
48
-
49
37
  /** Public tag config — only ENABLED providers with a public id appear.
50
38
  * Secrets can never appear here (explicit allowlist). */
51
39
  export interface StoreTrackingBlock {
@@ -64,7 +52,6 @@ export interface StoreIntegrationsConfig {
64
52
  /** Keyed by provider slug (e.g. `boxnow`, `econt`). Disabled carriers are
65
53
  * ABSENT, never `enabled: false`. */
66
54
  carriers: Record<string, PublicCarrierConfig>
67
- cod: PublicCodConfig | null
68
55
  tracking: StoreTrackingBlock
69
56
  }
70
57
 
@@ -10,7 +10,7 @@ import type { StorefrontClient } from "./http"
10
10
  import type { IsoDateString, ListEnvelope, PaginationQuery } from "./types"
11
11
 
12
12
  /**
13
- * A store region (`barter_commerce.regions` row). NOTE: barter regions carry
13
+ * A store region (`barter_commerce.regions` row). NOTE: Cartbase regions carry
14
14
  * NO embedded `countries` array on the store surface (divergence from
15
15
  * Medusa's Store API — tax scoping is by `tax_regions` server-side).
16
16
  */
@@ -43,7 +43,7 @@ import { defaultCartDrawerLabels, type CartDrawerLabels } from "./labels"
43
43
  * snapshot never updated past the failed mutation. See
44
44
  * https://react.dev/reference/react/useOptimistic.
45
45
  *
46
- * Ported from `@1click/ui/src/cart-drawer/context.tsx` (v2.3.1). Barter
46
+ * Ported from `@1click/ui/src/cart-drawer/context.tsx` (v2.3.1). Cartbase
47
47
  * data seam: the Medusa server actions (`../data/cart`) are replaced by
48
48
  * `@cartbase/storefront/api/carts` calls made through a `StorefrontClient`
49
49
  * passed to the provider. Every mutation returns the FULL decorated cart
@@ -54,7 +54,7 @@ import { defaultCartDrawerLabels, type CartDrawerLabels } from "./labels"
54
54
  * is unit-agnostic and unchanged).
55
55
  *
56
56
  * The source's `logEvent` ops funnel (backend error log endpoint) has no
57
- * barter SDK equivalent yet — the same single-funnel discipline is kept
57
+ * Cartbase SDK equivalent yet — the same single-funnel discipline is kept
58
58
  * via the `onOptimisticError` prop: every failed optimistic mutation
59
59
  * (every PDP add, cross-sell add, drawer remove, drawer quantity change)
60
60
  * flows through it with per-action context. Wire it to the store's ops
@@ -158,7 +158,7 @@ type CartDrawerContextValue = {
158
158
  quantity?: number,
159
159
  display?: OptimisticAddDisplay
160
160
  ) => Promise<boolean>
161
- /** POST line-items/:id with `{quantity}` — barter contract: 0 deletes. */
161
+ /** POST line-items/:id with `{quantity}` — Cartbase contract: 0 deletes. */
162
162
  updateQuantity: (lineId: string, quantity: number) => Promise<boolean>
163
163
  removeItem: (lineId: string) => Promise<boolean>
164
164
  /** Re-read the decorated cart (totals/gift-card tender are live per read). */
@@ -503,7 +503,7 @@ export function CartDrawerProvider({
503
503
  return runOptimistic(
504
504
  { type: "update_quantity", lineId, quantity },
505
505
  async () => {
506
- // Barter contract: body is `{quantity}` only (metadata is NOT
506
+ // Cartbase contract: body is `{quantity}` only (metadata is NOT
507
507
  // accepted on update, only on add); quantity 0 deletes the line.
508
508
  const res = await sdkUpdateLineItem(client, id, lineId, { quantity })
509
509
  confirm(res.cart)
@@ -14,7 +14,7 @@ import { useCartDrawer } from "./context"
14
14
  * cross-sell zone below the line items on desktop.
15
15
  *
16
16
  * Ported from `@1click/ui/src/cart-drawer/cross-sell-carousel.tsx` (v2.3.1).
17
- * Barter data seam: same as the sidebar — feed from
17
+ * Cartbase data seam: same as the sidebar — feed from
18
18
  * `@cartbase/storefront/api/products` `listProducts` or `api/search`
19
19
  * `listRelatedProducts` via `toCrossSellProduct`
20
20
  * (`./cross-sell-sidebar`; the card shapes are identical), wire `onAdd`
@@ -12,7 +12,7 @@ import { useCartDrawer } from "./context"
12
12
  * drawer's left sidebar.
13
13
  *
14
14
  * Ported from `@1click/ui/src/cart-drawer/cross-sell-sidebar.tsx` (v2.3.1).
15
- * Barter data seam: source stores fed this from Medusa product fetches —
15
+ * Cartbase data seam: source stores fed this from Medusa product fetches —
16
16
  * feed it from `@cartbase/storefront/api/products` `listProducts` (curated
17
17
  * collection/tag) or `@cartbase/storefront/api/search` `listRelatedProducts`
18
18
  * (anchor-product complements), mapped through `toCrossSellProduct` below.
@@ -6,7 +6,7 @@ import { useCartDrawer } from "./context"
6
6
  /**
7
7
  * Cart drawer header — store title, item count badge, close button.
8
8
  *
9
- * Ported from `@1click/ui/src/cart-drawer/header.tsx` (v2.3.1). Barter
9
+ * Ported from `@1click/ui/src/cart-drawer/header.tsx` (v2.3.1). Cartbase
10
10
  * adjustment: the badge counts PRODUCT lines via the shared
11
11
  * `productItemCount` predicate (the source summed all lines) so a
12
12
  * backend-injected COD-fee line can never inflate the item count —
@@ -15,13 +15,13 @@ import { CartItemVariant } from "./variant"
15
15
  * CartItem — a single cart line row: thumbnail, title, variant, quantity
16
16
  * stepper, price (with dual-currency + optional strikethrough), remove button.
17
17
  *
18
- * Ported from `@1click/ui/src/cart-drawer/item/index.tsx` (v2.3.1). Barter
18
+ * Ported from `@1click/ui/src/cart-drawer/item/index.tsx` (v2.3.1). Cartbase
19
19
  * data seam: `item` is the SDK's decorated `CartLineItem`
20
20
  * (`@cartbase/storefront/api/carts`) — per-line `total`/`original_total` are
21
21
  * server-computed EUR major units. Remove goes through the provider's
22
22
  * SDK-wired `removeItem` (DELETE line-items/:id, returns the full decorated
23
23
  * cart) instead of the Medusa server action. The variant row renders the
24
- * line's flat `variant_title` — barter cart lines carry the variant title
24
+ * line's flat `variant_title` — Cartbase cart lines carry the variant title
25
25
  * string, not an embedded variant object.
26
26
  *
27
27
  * `children` is rendered below the main row — intended for per-item upsell
@@ -15,9 +15,9 @@ import { useCartDrawer } from "../context"
15
15
  * automatically (confirmed snapshot unchanged).
16
16
  *
17
17
  * Ported from `@1click/ui/src/cart-drawer/item/quantity.tsx` (v2.3.1).
18
- * Barter data seam: `updateQuantity` wraps
18
+ * Cartbase data seam: `updateQuantity` wraps
19
19
  * `POST /api/store/carts/:id/line-items/:lineId` with body `{quantity}` —
20
- * the barter contract accepts ONLY `quantity` (no metadata on update) and
20
+ * the Cartbase contract accepts ONLY `quantity` (no metadata on update) and
21
21
  * quantity 0 deletes the line (unreachable here: the stepper floor is 1;
22
22
  * removal is the dedicated remove button).
23
23
  */
@@ -12,12 +12,12 @@ import { useCartDrawer } from "../context"
12
12
  * onAdd handler.
13
13
  *
14
14
  * Ported from `@1click/ui/src/cart-drawer/item/upsell.tsx` (v2.3.1).
15
- * Barter data seam: source stores fed this from Medusa product fetches —
15
+ * Cartbase data seam: source stores fed this from Medusa product fetches —
16
16
  * feed it from `@cartbase/storefront/api/search` `listRelatedProducts`
17
17
  * (per-anchor complements: manual admin picks + deterministic fallback)
18
18
  * mapped via `toCrossSellProduct` (`../cross-sell-sidebar`). `variantId`
19
19
  * was added to `UpsellProduct` and to the `onAdd` signature so the handler
20
- * can call the provider's `addItem(variantId)` directly — barter carts add
20
+ * can call the provider's `addItem(variantId)` directly — Cartbase carts add
21
21
  * by variant id, not product id. Prices are EUR major units.
22
22
  */
23
23
 
@@ -28,7 +28,7 @@ export type UpsellProduct = {
28
28
  thumbnail: string | null
29
29
  price: number
30
30
  currencyCode: string
31
- /** Variant to add (barter add-to-cart is by variant id). */
31
+ /** Variant to add (Cartbase add-to-cart is by variant id). */
32
32
  variantId?: string
33
33
  }
34
34
 
@@ -5,8 +5,8 @@
5
5
  * under the product title in a cart line.
6
6
  *
7
7
  * Ported from `@1click/ui/src/cart-drawer/item/variant.tsx` (v2.3.1).
8
- * Barter data seam: the source rendered `variant.options[].value` from an
9
- * embedded Medusa variant object; barter cart lines carry the flat
8
+ * Cartbase data seam: the source rendered `variant.options[].value` from an
9
+ * embedded Medusa variant object; Cartbase cart lines carry the flat
10
10
  * `variant_title` string (SDK `CartLineItem.variant_title`) instead, so
11
11
  * that is the primary prop. Callers that fetched the full variant (PDP
12
12
  * context) can still pass structural `options` and get the original
@@ -6,7 +6,7 @@ import type { CartDrawerLabels } from "./labels"
6
6
  * Ships alongside the English defaults so Bulgarian stores get the
7
7
  * translated copy with a single import instead of hand-writing every
8
8
  * string. Strings match the originals from mindpages-storefront, plus the
9
- * barter summary-breakdown row additions.
9
+ * Cartbase summary-breakdown row additions.
10
10
  *
11
11
  * Usage in a store's layout:
12
12
  *
@@ -62,7 +62,7 @@ export const bulgarianCartDrawerLabels: CartDrawerLabels = {
62
62
 
63
63
  discount: "Отстъпка",
64
64
  tax: "ДДС",
65
- codFee: "Такса наложен платеж",
65
+ paymentMethodFee: "Такса за плащане",
66
66
  giftCard: "Подаръчна карта",
67
67
  remainingToPay: "Остава за плащане",
68
68