@cartbase/storefront 0.2.0 → 0.4.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.
- package/package.json +1 -1
- package/src/api/carts.ts +5 -3
- package/src/api/checkout.ts +93 -43
- package/src/api/integrations.ts +4 -17
- package/src/cart-drawer/labels-bg.ts +1 -1
- package/src/cart-drawer/labels.ts +119 -119
- package/src/cart-drawer/summary-breakdown.tsx +197 -196
- package/src/checkout/checkout-client.tsx +13 -10
- package/src/checkout/index.ts +0 -1
- package/src/checkout/labels-bg.ts +1 -1
- package/src/checkout/labels.ts +263 -263
- package/src/checkout/order-summary.tsx +45 -45
- package/src/checkout/payment-method-list.tsx +92 -32
- package/src/checkout/use-checkout-orchestration.ts +100 -92
- package/src/lib/payment-constants.ts +53 -66
- package/src/order/labels-bg.ts +39 -39
- package/src/order/labels.ts +79 -79
- package/src/order/order-completed-template.tsx +17 -9
- package/src/order/order-payment-card.tsx +26 -35
- package/src/order/order-totals.tsx +250 -245
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cartbase/storefront",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "Storefront SDK + UI component library for Cartbase stores: typed API client, checkout orchestration, cart drawer, product/catalog components, tracking. Source-shipped TypeScript — add it to transpilePackages.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
package/src/api/carts.ts
CHANGED
|
@@ -200,9 +200,11 @@ export interface Cart {
|
|
|
200
200
|
credit_line_total: MajorUnitAmount
|
|
201
201
|
credit_line_subtotal: MajorUnitAmount
|
|
202
202
|
credit_line_tax_total: MajorUnitAmount
|
|
203
|
-
/**
|
|
204
|
-
|
|
205
|
-
|
|
203
|
+
/** The payment method fee — the chosen method's fee_amount (any method
|
|
204
|
+
* may carry one); non-zero only while a live method session is selected.
|
|
205
|
+
* Folded into `total`; its own totals row, never a line item. */
|
|
206
|
+
payment_method_fee_total: MajorUnitAmount
|
|
207
|
+
payment_method_fee_label: string | null
|
|
206
208
|
// — gift-card tender decoration (totals NEVER move; see gift-cards.ts) —
|
|
207
209
|
gift_cards: AppliedGiftCard[]
|
|
208
210
|
/** Σ of applied-card coverage (= the pp_giftcard session amount). */
|
package/src/api/checkout.ts
CHANGED
|
@@ -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
|
|
10
|
-
*
|
|
11
|
-
* drift/repair between the two:
|
|
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()` →
|
|
@@ -47,11 +47,10 @@ export interface StoreShippingOption {
|
|
|
47
47
|
name: string
|
|
48
48
|
provider_id: string | null
|
|
49
49
|
service_zone_id: string | null
|
|
50
|
-
shipping_option_type_id: string | null
|
|
51
50
|
shipping_profile_id: string | null
|
|
52
51
|
data: Record<string, unknown> | null
|
|
53
|
-
/**
|
|
54
|
-
type:
|
|
52
|
+
/** The option's display label (e.g. "Express") as `{ label }`, or null. */
|
|
53
|
+
type: { label: string } | null
|
|
55
54
|
/** Flat price in the cart currency; null without `cart_id` or when no price row matches. */
|
|
56
55
|
amount: MajorUnitAmount | null
|
|
57
56
|
/** Always "flat" today — calculated-rate carriers are not wired yet. */
|
|
@@ -137,28 +136,54 @@ export interface ListPaymentProvidersQuery {
|
|
|
137
136
|
cart_id?: string
|
|
138
137
|
}
|
|
139
138
|
|
|
140
|
-
/**
|
|
141
|
-
export interface
|
|
142
|
-
/** e.g. `pp_stripe
|
|
139
|
+
/** A connected PROCESSOR entry of GET /api/store/payment-providers. */
|
|
140
|
+
export interface StorePaymentProcessorEntry {
|
|
141
|
+
/** e.g. `pp_stripe`. `pp_giftcard` is internal and never listed. */
|
|
143
142
|
id: string
|
|
144
143
|
is_enabled: boolean
|
|
145
144
|
created_at?: string
|
|
146
145
|
}
|
|
147
146
|
|
|
147
|
+
/** A merchant PAYMENT METHOD entry (pp_* kill, 20260811250000): methods
|
|
148
|
+
* stand alone — no provider id anywhere. Initiate sessions with
|
|
149
|
+
* `payment_method_id`; `kind === "cod"` marks the pre-created
|
|
150
|
+
* collection-on-delivery method (courier cash collection); `instructions`
|
|
151
|
+
* is the merchant's checkout note, rendered under the method. */
|
|
152
|
+
export interface StorePaymentMethodEntry {
|
|
153
|
+
payment_method_id: string
|
|
154
|
+
name: string
|
|
155
|
+
kind: "manual" | "cod"
|
|
156
|
+
instructions: string | null
|
|
157
|
+
/** The method's fee (any method may carry one) — predict
|
|
158
|
+
* `payment_method_fee_total` from it before a session exists. */
|
|
159
|
+
fee_amount: number | null
|
|
160
|
+
fee_label: string | null
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/** Row of GET /api/store/payment-providers — a processor or a method. */
|
|
164
|
+
export type StorePaymentEntry = StorePaymentProcessorEntry | StorePaymentMethodEntry
|
|
165
|
+
|
|
166
|
+
/** True when the entry is a merchant payment method (vs a processor). */
|
|
167
|
+
export const isMethodEntry = (
|
|
168
|
+
entry: StorePaymentEntry
|
|
169
|
+
): entry is StorePaymentMethodEntry => "payment_method_id" in entry
|
|
170
|
+
|
|
148
171
|
export interface PaymentProviderListResponse extends ListEnvelope {
|
|
149
|
-
payment_providers:
|
|
172
|
+
payment_providers: StorePaymentEntry[]
|
|
150
173
|
}
|
|
151
174
|
|
|
152
175
|
/**
|
|
153
|
-
* List
|
|
154
|
-
*
|
|
155
|
-
*
|
|
156
|
-
*
|
|
157
|
-
*
|
|
176
|
+
* List everything payable (rule-filtered, display-ordered): connected
|
|
177
|
+
* processors + every ENABLED merchant method. → 200 list envelope;
|
|
178
|
+
* `count`/`limit` = full filtered list (no pagination). An empty list is
|
|
179
|
+
* honest: a fresh store cannot take money until the merchant connects a
|
|
180
|
+
* processor, flips the COD switch, or creates a manual method
|
|
181
|
+
* (no-payment-method-by-default).
|
|
158
182
|
* Auth: anon `x-client-id`.
|
|
159
|
-
* Settings:
|
|
160
|
-
*
|
|
161
|
-
*
|
|
183
|
+
* Settings: processor enablement (admin integrations), the Payments
|
|
184
|
+
* settings methods manager, checkout rules (`target_type=payment_method`,
|
|
185
|
+
* methods participate under their `payment_method_id`) +
|
|
186
|
+
* `checkout_method_order`.
|
|
162
187
|
*/
|
|
163
188
|
export async function listPaymentProviders(
|
|
164
189
|
client: StorefrontClient,
|
|
@@ -213,12 +238,18 @@ export async function createPaymentCollection(
|
|
|
213
238
|
}
|
|
214
239
|
|
|
215
240
|
export interface InitiatePaymentSessionInput {
|
|
216
|
-
/**
|
|
217
|
-
|
|
241
|
+
/** A connected processor (`pp_stripe`) — NEVER `pp_giftcard` (→ 400
|
|
242
|
+
* `invalid_provider`). Exactly ONE of `provider_id` /
|
|
243
|
+
* `payment_method_id` (→ 400 `invalid_data` otherwise). */
|
|
244
|
+
provider_id?: string
|
|
245
|
+
/** A merchant payment method (`payment_method_id` from the listing's
|
|
246
|
+
* method entries) — the session lands with `provider_id` NULL and the
|
|
247
|
+
* method snapshot (`payment_method_id`/`_name`/`_kind`) in `data`. */
|
|
248
|
+
payment_method_id?: string
|
|
218
249
|
/**
|
|
219
|
-
* Merged into the session's `data` blob.
|
|
250
|
+
* Merged into the session's `data` blob. Server-owned keys
|
|
220
251
|
* (`payment_intent_id`, `client_secret`, `status`, `stripe_customer_id`,
|
|
221
|
-
* `setup_future_usage
|
|
252
|
+
* `setup_future_usage`, and the method snapshot keys) are stripped.
|
|
222
253
|
*/
|
|
223
254
|
data?: Record<string, unknown>
|
|
224
255
|
/**
|
|
@@ -233,16 +264,19 @@ export interface InitiatePaymentSessionInput {
|
|
|
233
264
|
|
|
234
265
|
export interface StorePaymentSession {
|
|
235
266
|
id: string
|
|
236
|
-
|
|
237
|
-
|
|
267
|
+
/** The processor, or NULL for a merchant-method session (the method
|
|
268
|
+
* snapshot lives in `data`). */
|
|
269
|
+
provider_id: string | null
|
|
270
|
+
/** `collection.amount − gift_card_total` — the remainder this tender charges. */
|
|
238
271
|
amount: MajorUnitAmount
|
|
239
272
|
currency_code: string
|
|
240
273
|
/** `pending` until authorized at complete. */
|
|
241
274
|
status: string
|
|
242
275
|
authorized_at: string | null
|
|
243
276
|
/**
|
|
244
|
-
*
|
|
245
|
-
* (mount Stripe Elements with it), `status`.
|
|
277
|
+
* Tender blob. For Stripe: `payment_intent_id`, `client_secret`
|
|
278
|
+
* (mount Stripe Elements with it), `status`. For methods: the snapshot
|
|
279
|
+
* `payment_method_id` / `payment_method_name` / `payment_method_kind`.
|
|
246
280
|
*/
|
|
247
281
|
data: Record<string, unknown> | null
|
|
248
282
|
[key: string]: unknown
|
|
@@ -260,10 +294,11 @@ export interface InitiatePaymentSessionResponse {
|
|
|
260
294
|
* in place; terminal PIs self-heal by rotation.
|
|
261
295
|
* Auth: anon `x-client-id`.
|
|
262
296
|
* Errors: 404 `payment_collection_not_found`, 400 `invalid_provider`
|
|
263
|
-
* (pp_giftcard) | `
|
|
297
|
+
* (pp_giftcard / unknown processor) | `invalid_data` (tender XOR violated,
|
|
298
|
+
* unknown/disabled method) | `stripe_not_configured` | `validation_failed`.
|
|
264
299
|
* Settings: Stripe credentials (admin integrations); gift-card tender
|
|
265
|
-
* shrinks the session amount; COD fee appears on the cart the moment a
|
|
266
|
-
*
|
|
300
|
+
* shrinks the session amount; the COD fee appears on the cart the moment a
|
|
301
|
+
* live COD-method session exists.
|
|
267
302
|
*/
|
|
268
303
|
export async function initiatePaymentSession(
|
|
269
304
|
client: StorefrontClient,
|
|
@@ -312,28 +347,37 @@ export interface PrepareCheckoutInput {
|
|
|
312
347
|
* switching carriers never leaks stale fields into the order.
|
|
313
348
|
*/
|
|
314
349
|
carrier_metadata?: Record<string, unknown>
|
|
315
|
-
/**
|
|
316
|
-
|
|
350
|
+
/** A connected processor (`pp_stripe`) — never `pp_giftcard`. Exactly ONE
|
|
351
|
+
* of `payment_provider` / `payment_method_id`. */
|
|
352
|
+
payment_provider?: string
|
|
353
|
+
/** A merchant payment method — the session lands provider-less with the
|
|
354
|
+
* method snapshot (pp_* kill, 20260811250000). */
|
|
355
|
+
payment_method_id?: string
|
|
317
356
|
}
|
|
318
357
|
|
|
319
358
|
/** Response of prepare-checkout (verbatim src/lib/checkout-orchestration/prepare.ts). */
|
|
320
359
|
export interface PrepareCheckoutResult {
|
|
321
360
|
cart_id: string
|
|
322
361
|
payment_collection_id: string | null
|
|
323
|
-
/** Stripe Elements secret; null for
|
|
362
|
+
/** Stripe Elements secret; null for method sessions and zero-remainder carts. */
|
|
324
363
|
client_secret: string | null
|
|
325
|
-
/** The
|
|
364
|
+
/** The processor whose session was minted; null for method sessions and
|
|
365
|
+
* when zero-remainder skipped the session. */
|
|
326
366
|
provider_id: string | null
|
|
367
|
+
/** The method whose session was minted; null for processor sessions and
|
|
368
|
+
* when zero-remainder skipped the session. */
|
|
369
|
+
payment_method_id: string | null
|
|
327
370
|
}
|
|
328
371
|
|
|
329
372
|
/**
|
|
330
373
|
* Atomic Buy-click step 1 of 2. ONE call writes address (+billing mirror) +
|
|
331
374
|
* carrier metadata → shipping method (priced against the new destination) →
|
|
332
375
|
* payment collection at the shipped total → payment session at the FINAL
|
|
333
|
-
* amount. For
|
|
334
|
-
* amounts are re-synced after it. Zero-remainder carts (gift
|
|
335
|
-
* the total) skip the
|
|
336
|
-
* come back null and the cart
|
|
376
|
+
* amount. For the COD method the native fee applies once the session
|
|
377
|
+
* exists, so amounts are re-synced after it. Zero-remainder carts (gift
|
|
378
|
+
* cards cover the total) skip the tender session — `client_secret`,
|
|
379
|
+
* `provider_id` and `payment_method_id` come back null and the cart
|
|
380
|
+
* completes on the gift session.
|
|
337
381
|
*
|
|
338
382
|
* Fully compensated (wire-pattern): any failure rolls back session →
|
|
339
383
|
* collection → shipping method → addresses/metadata to the pre-call
|
|
@@ -341,13 +385,14 @@ export interface PrepareCheckoutResult {
|
|
|
341
385
|
* `checkout_error_logs` (step `prepare-checkout`).
|
|
342
386
|
*
|
|
343
387
|
* After prepare: Stripe → `stripe.confirmPayment(client_secret)` →
|
|
344
|
-
* `completeCart()`;
|
|
388
|
+
* `completeCart()`; merchant methods → `completeCart()` directly.
|
|
345
389
|
*
|
|
346
390
|
* Auth: anon `x-client-id`.
|
|
347
391
|
* Errors: 404 `cart_not_found` | `shipping_option_not_found`, 409
|
|
348
392
|
* `cart_completed`, 400 `validation_failed` | `invalid_provider` |
|
|
349
|
-
* `
|
|
350
|
-
*
|
|
393
|
+
* `invalid_data` (tender XOR violated) | `shipping_price_missing` |
|
|
394
|
+
* `stripe_not_configured`.
|
|
395
|
+
* Settings: Stripe credentials, the COD method's fee, gift-card tender,
|
|
351
396
|
* checkout rules (enforced at listings + complete, not here).
|
|
352
397
|
*/
|
|
353
398
|
export async function prepareCheckout(
|
|
@@ -358,10 +403,14 @@ export async function prepareCheckout(
|
|
|
358
403
|
return client.post(`/api/store/carts/${cartId}/prepare-checkout`, input)
|
|
359
404
|
}
|
|
360
405
|
|
|
361
|
-
/** Body of POST /api/store/carts/:id/sync-payment-amount (`.strict()`).
|
|
406
|
+
/** Body of POST /api/store/carts/:id/sync-payment-amount (`.strict()`).
|
|
407
|
+
* At most ONE of the two — the requested tender; omit both to sync
|
|
408
|
+
* whatever session is pending. */
|
|
362
409
|
export interface SyncPaymentAmountInput {
|
|
363
|
-
/** Rotate to this
|
|
410
|
+
/** Rotate to this processor when the pending session's tender differs. */
|
|
364
411
|
provider_id?: string
|
|
412
|
+
/** Rotate to this merchant method when the pending session's tender differs. */
|
|
413
|
+
payment_method_id?: string
|
|
365
414
|
}
|
|
366
415
|
|
|
367
416
|
/** Response matrix (verbatim src/lib/checkout-orchestration/sync.ts). */
|
|
@@ -371,6 +420,7 @@ export interface SyncPaymentAmountResult {
|
|
|
371
420
|
rotated?: boolean
|
|
372
421
|
client_secret?: string | null
|
|
373
422
|
provider_id?: string | null
|
|
423
|
+
payment_method_id?: string | null
|
|
374
424
|
/** No-op reasons: `cart-completed` | `no_payment_collection` | `no_pending_session`. */
|
|
375
425
|
reason?: string
|
|
376
426
|
}
|
package/src/api/integrations.ts
CHANGED
|
@@ -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`, `
|
|
11
|
-
*
|
|
12
|
-
*
|
|
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
|
|
|
@@ -1,119 +1,119 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Cart drawer labels — default English copy.
|
|
3
|
-
*
|
|
4
|
-
* Every user-facing string in the cart drawer comes from a `CartDrawerLabels`
|
|
5
|
-
* object. Stores override strings by passing a partial labels object to
|
|
6
|
-
* `CartDrawerProvider`. English is the baseline; stores wanting Bulgarian,
|
|
7
|
-
* German, etc. pass their own translations.
|
|
8
|
-
*
|
|
9
|
-
* Ported from `@1click/ui/src/cart-drawer/labels.ts` (v2.3.1). Cartbase
|
|
10
|
-
* additions: the summary-breakdown row labels (`discount`, `tax`, `
|
|
11
|
-
* `giftCard`, `remainingToPay`) — the decorated cart carries
|
|
12
|
-
* discount/tax/COD-fee/gift-card tender fields that the breakdown renders,
|
|
13
|
-
* so the copy for those rows lives here too.
|
|
14
|
-
*/
|
|
15
|
-
|
|
16
|
-
export type CartDrawerLabels = {
|
|
17
|
-
// Header
|
|
18
|
-
yourCart: string
|
|
19
|
-
item: string
|
|
20
|
-
items: string
|
|
21
|
-
closeCart: string
|
|
22
|
-
|
|
23
|
-
// Empty state
|
|
24
|
-
emptyCartTitle: string
|
|
25
|
-
emptyCartMessage: string
|
|
26
|
-
browseProducts: string
|
|
27
|
-
|
|
28
|
-
// Tiered progress
|
|
29
|
-
awayFromFreeShipping: string
|
|
30
|
-
allRewardsUnlocked: string
|
|
31
|
-
|
|
32
|
-
// Gift wrap / notes
|
|
33
|
-
addGiftWrap: string
|
|
34
|
-
giftNote: string
|
|
35
|
-
orderNote: string
|
|
36
|
-
giftNotePlaceholder: string
|
|
37
|
-
orderNotePlaceholder: string
|
|
38
|
-
|
|
39
|
-
// Rewards
|
|
40
|
-
estimatedRewardPoints: string
|
|
41
|
-
|
|
42
|
-
// Cross-sell
|
|
43
|
-
pairsWellWith: string
|
|
44
|
-
youllLoveThis: string
|
|
45
|
-
youMightAlsoLike: string
|
|
46
|
-
addToCart: string
|
|
47
|
-
|
|
48
|
-
// Summary / footer
|
|
49
|
-
subtotal: string
|
|
50
|
-
taxAndShipping: string
|
|
51
|
-
shipping: string
|
|
52
|
-
free: string
|
|
53
|
-
calculatedAtCheckout: string
|
|
54
|
-
total: string
|
|
55
|
-
secureCheckout: string
|
|
56
|
-
shippingAndTaxCalculatedAtCheckout: string
|
|
57
|
-
|
|
58
|
-
// Summary breakdown rows (Cartbase decorated-cart fields)
|
|
59
|
-
discount: string
|
|
60
|
-
tax: string
|
|
61
|
-
/** Fallback only — the server's `
|
|
62
|
-
|
|
63
|
-
/** Prefix for an applied gift-card row; rendered as `<giftCard> ••1234`. */
|
|
64
|
-
giftCard: string
|
|
65
|
-
/** Label for `gift_card_remainder` — what the remainder provider charges. */
|
|
66
|
-
remainingToPay: string
|
|
67
|
-
|
|
68
|
-
// Continue shopping
|
|
69
|
-
continueShopping: string
|
|
70
|
-
|
|
71
|
-
// A11y / buttons
|
|
72
|
-
remove: string
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
export const defaultCartDrawerLabels: CartDrawerLabels = {
|
|
76
|
-
yourCart: "Your cart",
|
|
77
|
-
item: "item",
|
|
78
|
-
items: "items",
|
|
79
|
-
closeCart: "Close cart",
|
|
80
|
-
|
|
81
|
-
emptyCartTitle: "Your cart is empty",
|
|
82
|
-
emptyCartMessage: "You haven't added any products yet.",
|
|
83
|
-
browseProducts: "Browse products",
|
|
84
|
-
|
|
85
|
-
awayFromFreeShipping: "away from free shipping",
|
|
86
|
-
allRewardsUnlocked: "All rewards unlocked",
|
|
87
|
-
|
|
88
|
-
addGiftWrap: "Add gift wrapping",
|
|
89
|
-
giftNote: "Gift note",
|
|
90
|
-
orderNote: "Order note",
|
|
91
|
-
giftNotePlaceholder: "Add a personal message...",
|
|
92
|
-
orderNotePlaceholder: "Special instructions for this order...",
|
|
93
|
-
|
|
94
|
-
estimatedRewardPoints: "Estimated reward points",
|
|
95
|
-
|
|
96
|
-
pairsWellWith: "Pairs well with",
|
|
97
|
-
youllLoveThis: "You'll love this",
|
|
98
|
-
youMightAlsoLike: "You might also like",
|
|
99
|
-
addToCart: "Add",
|
|
100
|
-
|
|
101
|
-
subtotal: "Subtotal",
|
|
102
|
-
taxAndShipping: "VAT included. Shipping calculated at checkout.",
|
|
103
|
-
shipping: "Shipping",
|
|
104
|
-
free: "FREE",
|
|
105
|
-
calculatedAtCheckout: "Calculated at checkout",
|
|
106
|
-
total: "Total",
|
|
107
|
-
secureCheckout: "Checkout",
|
|
108
|
-
shippingAndTaxCalculatedAtCheckout: "Shipping and tax calculated at checkout",
|
|
109
|
-
|
|
110
|
-
discount: "Discount",
|
|
111
|
-
tax: "VAT",
|
|
112
|
-
|
|
113
|
-
giftCard: "Gift card",
|
|
114
|
-
remainingToPay: "Remaining to pay",
|
|
115
|
-
|
|
116
|
-
continueShopping: "Continue shopping",
|
|
117
|
-
|
|
118
|
-
remove: "Remove",
|
|
119
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* Cart drawer labels — default English copy.
|
|
3
|
+
*
|
|
4
|
+
* Every user-facing string in the cart drawer comes from a `CartDrawerLabels`
|
|
5
|
+
* object. Stores override strings by passing a partial labels object to
|
|
6
|
+
* `CartDrawerProvider`. English is the baseline; stores wanting Bulgarian,
|
|
7
|
+
* German, etc. pass their own translations.
|
|
8
|
+
*
|
|
9
|
+
* Ported from `@1click/ui/src/cart-drawer/labels.ts` (v2.3.1). Cartbase
|
|
10
|
+
* additions: the summary-breakdown row labels (`discount`, `tax`, `paymentMethodFee`,
|
|
11
|
+
* `giftCard`, `remainingToPay`) — the decorated cart carries
|
|
12
|
+
* discount/tax/COD-fee/gift-card tender fields that the breakdown renders,
|
|
13
|
+
* so the copy for those rows lives here too.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
export type CartDrawerLabels = {
|
|
17
|
+
// Header
|
|
18
|
+
yourCart: string
|
|
19
|
+
item: string
|
|
20
|
+
items: string
|
|
21
|
+
closeCart: string
|
|
22
|
+
|
|
23
|
+
// Empty state
|
|
24
|
+
emptyCartTitle: string
|
|
25
|
+
emptyCartMessage: string
|
|
26
|
+
browseProducts: string
|
|
27
|
+
|
|
28
|
+
// Tiered progress
|
|
29
|
+
awayFromFreeShipping: string
|
|
30
|
+
allRewardsUnlocked: string
|
|
31
|
+
|
|
32
|
+
// Gift wrap / notes
|
|
33
|
+
addGiftWrap: string
|
|
34
|
+
giftNote: string
|
|
35
|
+
orderNote: string
|
|
36
|
+
giftNotePlaceholder: string
|
|
37
|
+
orderNotePlaceholder: string
|
|
38
|
+
|
|
39
|
+
// Rewards
|
|
40
|
+
estimatedRewardPoints: string
|
|
41
|
+
|
|
42
|
+
// Cross-sell
|
|
43
|
+
pairsWellWith: string
|
|
44
|
+
youllLoveThis: string
|
|
45
|
+
youMightAlsoLike: string
|
|
46
|
+
addToCart: string
|
|
47
|
+
|
|
48
|
+
// Summary / footer
|
|
49
|
+
subtotal: string
|
|
50
|
+
taxAndShipping: string
|
|
51
|
+
shipping: string
|
|
52
|
+
free: string
|
|
53
|
+
calculatedAtCheckout: string
|
|
54
|
+
total: string
|
|
55
|
+
secureCheckout: string
|
|
56
|
+
shippingAndTaxCalculatedAtCheckout: string
|
|
57
|
+
|
|
58
|
+
// Summary breakdown rows (Cartbase decorated-cart fields)
|
|
59
|
+
discount: string
|
|
60
|
+
tax: string
|
|
61
|
+
/** Fallback only — the server's `payment_method_fee_label` wins when present. */
|
|
62
|
+
paymentMethodFee: string
|
|
63
|
+
/** Prefix for an applied gift-card row; rendered as `<giftCard> ••1234`. */
|
|
64
|
+
giftCard: string
|
|
65
|
+
/** Label for `gift_card_remainder` — what the remainder provider charges. */
|
|
66
|
+
remainingToPay: string
|
|
67
|
+
|
|
68
|
+
// Continue shopping
|
|
69
|
+
continueShopping: string
|
|
70
|
+
|
|
71
|
+
// A11y / buttons
|
|
72
|
+
remove: string
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export const defaultCartDrawerLabels: CartDrawerLabels = {
|
|
76
|
+
yourCart: "Your cart",
|
|
77
|
+
item: "item",
|
|
78
|
+
items: "items",
|
|
79
|
+
closeCart: "Close cart",
|
|
80
|
+
|
|
81
|
+
emptyCartTitle: "Your cart is empty",
|
|
82
|
+
emptyCartMessage: "You haven't added any products yet.",
|
|
83
|
+
browseProducts: "Browse products",
|
|
84
|
+
|
|
85
|
+
awayFromFreeShipping: "away from free shipping",
|
|
86
|
+
allRewardsUnlocked: "All rewards unlocked",
|
|
87
|
+
|
|
88
|
+
addGiftWrap: "Add gift wrapping",
|
|
89
|
+
giftNote: "Gift note",
|
|
90
|
+
orderNote: "Order note",
|
|
91
|
+
giftNotePlaceholder: "Add a personal message...",
|
|
92
|
+
orderNotePlaceholder: "Special instructions for this order...",
|
|
93
|
+
|
|
94
|
+
estimatedRewardPoints: "Estimated reward points",
|
|
95
|
+
|
|
96
|
+
pairsWellWith: "Pairs well with",
|
|
97
|
+
youllLoveThis: "You'll love this",
|
|
98
|
+
youMightAlsoLike: "You might also like",
|
|
99
|
+
addToCart: "Add",
|
|
100
|
+
|
|
101
|
+
subtotal: "Subtotal",
|
|
102
|
+
taxAndShipping: "VAT included. Shipping calculated at checkout.",
|
|
103
|
+
shipping: "Shipping",
|
|
104
|
+
free: "FREE",
|
|
105
|
+
calculatedAtCheckout: "Calculated at checkout",
|
|
106
|
+
total: "Total",
|
|
107
|
+
secureCheckout: "Checkout",
|
|
108
|
+
shippingAndTaxCalculatedAtCheckout: "Shipping and tax calculated at checkout",
|
|
109
|
+
|
|
110
|
+
discount: "Discount",
|
|
111
|
+
tax: "VAT",
|
|
112
|
+
paymentMethodFee: "Payment method fee",
|
|
113
|
+
giftCard: "Gift card",
|
|
114
|
+
remainingToPay: "Remaining to pay",
|
|
115
|
+
|
|
116
|
+
continueShopping: "Continue shopping",
|
|
117
|
+
|
|
118
|
+
remove: "Remove",
|
|
119
|
+
}
|