@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.
- package/README.md +3 -3
- package/package.json +231 -226
- package/src/api/auth.ts +1 -1
- package/src/api/carts.ts +5 -3
- package/src/api/checkout.ts +91 -40
- package/src/api/consent.ts +2 -2
- package/src/api/integrations.ts +4 -17
- package/src/api/regions.ts +1 -1
- package/src/cart-drawer/context.tsx +4 -4
- package/src/cart-drawer/cross-sell-carousel.tsx +1 -1
- package/src/cart-drawer/cross-sell-sidebar.tsx +1 -1
- package/src/cart-drawer/header.tsx +1 -1
- package/src/cart-drawer/item/index.tsx +2 -2
- package/src/cart-drawer/item/quantity.tsx +2 -2
- package/src/cart-drawer/item/upsell.tsx +3 -3
- package/src/cart-drawer/item/variant.tsx +2 -2
- package/src/cart-drawer/labels-bg.ts +2 -2
- package/src/cart-drawer/labels.ts +119 -119
- package/src/cart-drawer/summary-breakdown.tsx +197 -196
- package/src/cart-drawer/template.tsx +2 -2
- package/src/cart-drawer/tiered-progress.tsx +1 -1
- package/src/checkout/address-error-copy.ts +3 -3
- package/src/checkout/address-form.tsx +2 -2
- package/src/checkout/address-select.tsx +1 -1
- package/src/checkout/boxnow-locker-selector.tsx +3 -3
- package/src/checkout/checkout-client.tsx +15 -12
- package/src/checkout/company-details.tsx +1 -1
- package/src/checkout/compare-addresses.ts +1 -1
- package/src/checkout/discount-section.tsx +5 -5
- package/src/checkout/econt-office-selector.tsx +2 -2
- package/src/checkout/gift-card-section.tsx +2 -2
- package/src/checkout/index.ts +0 -1
- package/src/checkout/labels-bg.ts +2 -2
- package/src/checkout/labels.ts +263 -263
- package/src/checkout/line-item-card.tsx +2 -2
- package/src/checkout/order-summary.tsx +48 -48
- package/src/checkout/payment-button.tsx +4 -4
- package/src/checkout/payment-error-copy.ts +6 -6
- package/src/checkout/payment-method-list.tsx +93 -33
- package/src/checkout/payment-wrapper.tsx +8 -11
- package/src/checkout/promotion-error-copy.ts +2 -2
- package/src/checkout/shipping-method-list.tsx +2 -2
- package/src/checkout/stripe-wrapper.tsx +1 -1
- package/src/checkout/use-checkout-orchestration.ts +108 -98
- package/src/common/cart-button-client.tsx +1 -1
- package/src/common/cart-button.tsx +1 -1
- package/src/common/country-select.tsx +2 -2
- package/src/common/delete-button.tsx +1 -1
- package/src/common/index.ts +1 -1
- package/src/common/language-select.tsx +2 -2
- package/src/common/localized-link.tsx +1 -1
- package/src/lib/cart-helpers.ts +2 -2
- package/src/lib/cookie-names.ts +41 -0
- package/src/lib/get-product-price.ts +3 -3
- package/src/lib/payment-constants.ts +53 -66
- package/src/lib/store-api-error.ts +1 -1
- package/src/order/index.ts +1 -1
- package/src/order/labels-bg.ts +39 -39
- package/src/order/labels.ts +79 -79
- package/src/order/order-address-card.tsx +1 -1
- package/src/order/order-completed-template.tsx +20 -12
- package/src/order/order-confirmation-header.tsx +1 -1
- package/src/order/order-delivery-card.tsx +3 -3
- package/src/order/order-item.tsx +2 -2
- package/src/order/order-items-list.tsx +3 -3
- package/src/order/order-payment-card.tsx +27 -36
- package/src/order/order-timeline.tsx +2 -2
- package/src/order/order-totals.tsx +250 -245
- package/src/platform/identity.ts +18 -0
- package/src/platform/index.ts +8 -0
- package/src/platform/metadata.ts +26 -0
- package/src/platform/platform-init.tsx +46 -0
- package/src/products/image-gallery.tsx +1 -1
- package/src/products/mobile-actions.tsx +1 -1
- package/src/products/option-select.tsx +1 -1
- package/src/products/preview-price.tsx +1 -1
- package/src/products/product-actions.tsx +6 -6
- package/src/products/product-info.tsx +1 -1
- package/src/products/product-preview.tsx +1 -1
- package/src/products/product-price.tsx +2 -2
- package/src/products/product-tabs.tsx +1 -1
- package/src/products/purchase-options.tsx +1 -1
- package/src/products/related-products.tsx +3 -3
- package/src/products/variant-matching.ts +4 -4
- package/src/reviews-ui/labels.ts +1 -1
- package/src/reviews-ui/photo-upload.tsx +1 -1
- package/src/reviews-ui/review-list.tsx +1 -1
- package/src/reviews-ui/review-widget.tsx +1 -1
- package/src/reviews-ui/review-wizard.tsx +1 -1
- package/src/reviews-ui/wizard-state.ts +1 -1
- package/src/store/category-template.tsx +2 -2
- package/src/store/collection-template.tsx +2 -2
- package/src/store/labels.ts +2 -2
- package/src/store/paginated-products.tsx +1 -1
- package/src/store/search-params.ts +1 -1
- package/src/store/search-template.tsx +1 -1
- package/src/tracking/consent-banner.tsx +1 -1
- package/src/tracking/consent-init.tsx +1 -1
- package/src/tracking/consent.ts +6 -6
- package/src/tracking/fbq.ts +2 -2
- package/src/tracking/get-tracking-attribution.ts +1 -1
- package/src/tracking/get-tracking-config.ts +2 -2
- package/src/tracking/index.ts +2 -2
- package/src/tracking/meta-pixel.tsx +1 -1
- package/src/tracking/rybbit.tsx +1 -1
- package/src/tracking/types.ts +6 -6
|
@@ -29,7 +29,7 @@ import { isProductLine } from "../lib/cart-helpers"
|
|
|
29
29
|
* body inside a `<CartDrawer>` shell. That way the store owns its
|
|
30
30
|
* composition and still gets library updates to every primitive.
|
|
31
31
|
*
|
|
32
|
-
* Ported from `@1click/ui/src/cart-drawer/template.tsx` (v2.3.1).
|
|
32
|
+
* Ported from `@1click/ui/src/cart-drawer/template.tsx` (v2.3.1). Cartbase
|
|
33
33
|
* adaptations:
|
|
34
34
|
* - Amounts are EUR major units — `rewards.pointsPerCurrency` is points
|
|
35
35
|
* per 1 EUR (the source's `/100` minor-unit division is gone), and
|
|
@@ -130,7 +130,7 @@ export function CartDrawerTemplate({
|
|
|
130
130
|
.finally(() => setCrossSellLoaded(true))
|
|
131
131
|
}, [hasItems, crossSellLoaded, config.crossSell?.loader])
|
|
132
132
|
|
|
133
|
-
// Cross-sell add → the provider's SDK addItem (
|
|
133
|
+
// Cross-sell add → the provider's SDK addItem (Cartbase adds by variant
|
|
134
134
|
// id). Cards built without a variantId no-op.
|
|
135
135
|
const handleCrossSellAdd = useCallback(
|
|
136
136
|
(_productId: string, variantId?: string) => {
|
|
@@ -11,7 +11,7 @@ import { useCartDrawer } from "./context"
|
|
|
11
11
|
* originally extracted from mindpages-storefront
|
|
12
12
|
* src/modules/cart-drawer/cart-tiered-progress.tsx.
|
|
13
13
|
*
|
|
14
|
-
*
|
|
14
|
+
* Cartbase money note: `cart.total` and tier `threshold`s are EUR decimal
|
|
15
15
|
* major units (e.g. `{ threshold: 50 }` = €50) — configure tiers in major
|
|
16
16
|
* units, not cents.
|
|
17
17
|
*/
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* checkout address surface.
|
|
4
4
|
*
|
|
5
5
|
* Ported from `@1click/ui/src/checkout/address-error-copy.ts` (v2.3.1) and
|
|
6
|
-
* adapted to the
|
|
6
|
+
* adapted to the Cartbase error envelope: `StoreApiError` carries a structured
|
|
7
7
|
* `code` (POST /api/store/carts/:id — docs/storefront/carts.md), so
|
|
8
8
|
* translation is code-first; the substring patterns stay as the fallback for
|
|
9
9
|
* network failures and any legacy wire.
|
|
@@ -20,7 +20,7 @@ const NETWORK_FALLBACK =
|
|
|
20
20
|
"Няма връзка със сървъра. Моля, проверете интернет връзката и опитайте отново."
|
|
21
21
|
|
|
22
22
|
/**
|
|
23
|
-
*
|
|
23
|
+
* Cartbase cart-update error codes → BG copy (POST /api/store/carts/:id,
|
|
24
24
|
* docs/storefront/carts.md). Code-first, matched before any pattern.
|
|
25
25
|
*/
|
|
26
26
|
export const ADDRESS_ERROR_CODE_COPY: Record<string, string> = {
|
|
@@ -76,7 +76,7 @@ const PATTERNS: Array<{ match: RegExp; copy: string }> = [
|
|
|
76
76
|
copy: NETWORK_FALLBACK,
|
|
77
77
|
},
|
|
78
78
|
// The Next.js canned Server Components production message — surface a
|
|
79
|
-
// clean fallback instead of the English placeholder. (The
|
|
79
|
+
// clean fallback instead of the English placeholder. (The Cartbase SDK
|
|
80
80
|
// throws from the browser, so this only fires for stores that proxy the
|
|
81
81
|
// save through a server action.)
|
|
82
82
|
{
|
|
@@ -17,9 +17,9 @@ import { ErrorMessage } from "./error-message"
|
|
|
17
17
|
* (`CheckoutClient` / `useCheckoutOrchestration`).
|
|
18
18
|
*
|
|
19
19
|
* Ported from `@1click/ui/src/checkout/address-form.tsx` (v2.3.1) with the
|
|
20
|
-
*
|
|
20
|
+
* Cartbase type seam only: `@medusajs/types` → the SDK's `CustomerAddress` /
|
|
21
21
|
* `CartAddress` partials. The `countries` list comes from the orchestration
|
|
22
|
-
* hook's `regionCountries` —
|
|
22
|
+
* hook's `regionCountries` — Cartbase regions carry NO embedded countries
|
|
23
23
|
* array (api/regions.ts divergence), so the host supplies the list via the
|
|
24
24
|
* hook's `countries` option (single-entry `countryCode` fallback).
|
|
25
25
|
*/
|
|
@@ -15,7 +15,7 @@ import { useCheckoutLabels } from "./context"
|
|
|
15
15
|
* replace this one file locally.
|
|
16
16
|
*
|
|
17
17
|
* Ported from `@1click/ui/src/checkout/address-select.tsx` (v2.3.1) with
|
|
18
|
-
* the
|
|
18
|
+
* the Cartbase type seam: `@medusajs/types` address DTOs → the SDK's
|
|
19
19
|
* `CustomerAddress` (GET /api/store/customers/me — addresses embedded,
|
|
20
20
|
* docs/storefront/customers.md) and `CartAddress` partials. Field names are
|
|
21
21
|
* identical across both wires, so the compare/format logic is unchanged.
|
|
@@ -17,11 +17,11 @@ import { useCheckoutLabels } from "./context"
|
|
|
17
17
|
* BoxNowLockerSelector — full BoxNow locker picker for Bulgarian shipping.
|
|
18
18
|
*
|
|
19
19
|
* Ported from `@1click/ui/src/checkout/boxnow-locker-selector.tsx` (v2.3.1)
|
|
20
|
-
* with the
|
|
20
|
+
* with the Cartbase data seam: the locker directory comes from
|
|
21
21
|
* `listBoxNowLockers(client)` (`@cartbase/storefront/api/integrations`,
|
|
22
22
|
* GET /api/store/integrations/boxnow/lockers — backend owns BoxNow API auth
|
|
23
23
|
* + the 10-min cache; docs/storefront/integrations.md). The @1click data
|
|
24
|
-
* helper returned `{ok, lockers}`; the
|
|
24
|
+
* helper returned `{ok, lockers}`; the Cartbase SDK THROWS on 503 (not
|
|
25
25
|
* configured) / 502 (carrier failure), so the fetch wrapper catches and
|
|
26
26
|
* maps both to the same "temporarily unavailable" state. Availability
|
|
27
27
|
* should be discovered via `carriers.boxnow.lockers_url` on the
|
|
@@ -38,7 +38,7 @@ import { useCheckoutLabels } from "./context"
|
|
|
38
38
|
* - title (not name)
|
|
39
39
|
* - addressLine1 / addressLine2 (not address.street/num)
|
|
40
40
|
* - postalCode (not address.city.name)
|
|
41
|
-
* - lat / lng on the root (numbers or null — the
|
|
41
|
+
* - lat / lng on the root (numbers or null — the Cartbase route coerces
|
|
42
42
|
* malformed carrier coordinates to null, never NaN)
|
|
43
43
|
* - No isAPS / code / phones
|
|
44
44
|
*
|
|
@@ -13,7 +13,6 @@ import { CheckoutShippingMethodList } from "./shipping-method-list"
|
|
|
13
13
|
import { PaymentWrapper } from "./payment-wrapper"
|
|
14
14
|
import {
|
|
15
15
|
useCheckoutOrchestration,
|
|
16
|
-
type CheckoutCodConfig,
|
|
17
16
|
type CheckoutLogError,
|
|
18
17
|
type PaymentProviderLike,
|
|
19
18
|
} from "./use-checkout-orchestration"
|
|
@@ -27,7 +26,7 @@ import {
|
|
|
27
26
|
* automatically.
|
|
28
27
|
*
|
|
29
28
|
* Ported from `@1click/ui/src/checkout/checkout-client.tsx` (v2.3.1) with
|
|
30
|
-
* the
|
|
29
|
+
* the Cartbase data seam:
|
|
31
30
|
*
|
|
32
31
|
* - Takes the SDK `client` — every server call (address autosave,
|
|
33
32
|
* prepare-checkout, sync, complete, promo/gift-card apply, quantity
|
|
@@ -35,9 +34,9 @@ import {
|
|
|
35
34
|
* - The listings arrive as SDK DTOs: `listShippingOptions` /
|
|
36
35
|
* `listPaymentProviders` (both rule-filtered server-side) — fetch them
|
|
37
36
|
* in the host and pass down (docs/storefront/checkout.md).
|
|
38
|
-
* -
|
|
39
|
-
*
|
|
40
|
-
*
|
|
37
|
+
* - Fee prediction is NEVER hardcoded: the payment listing entries carry
|
|
38
|
+
* each method's own `fee_amount`/`fee_label` (the integrations `cod`
|
|
39
|
+
* block died 2026-08-11 — any method may carry a fee).
|
|
41
40
|
* - `onCartChange` closes the loop for summary mutations: the decorated
|
|
42
41
|
* cart returned by promo/gift-card/quantity calls is handed up so the
|
|
43
42
|
* host updates its cart state (`router.refresh()` in an RSC app) AND
|
|
@@ -55,14 +54,12 @@ type CheckoutClientProps = {
|
|
|
55
54
|
availableShippingMethods: StoreShippingOption[] | null
|
|
56
55
|
availablePaymentMethods: PaymentProviderLike[] | null
|
|
57
56
|
countryCode: string
|
|
58
|
-
/** Countries for the address form (
|
|
57
|
+
/** Countries for the address form (Cartbase regions embed none). */
|
|
59
58
|
countries?: Array<{ iso_2: string; display_name: string }>
|
|
60
59
|
paymentMethodFilter?: (
|
|
61
60
|
methods: PaymentProviderLike[] | null,
|
|
62
61
|
selectedShippingOption: StoreShippingOption | null
|
|
63
62
|
) => PaymentProviderLike[] | null
|
|
64
|
-
/** The integrations config `cod` block — drives the optimistic COD fee. */
|
|
65
|
-
codConfig?: CheckoutCodConfig
|
|
66
63
|
/** Show the gift-card widget in the summary (default true). */
|
|
67
64
|
showGiftCards?: boolean
|
|
68
65
|
logoByFulfillmentOptionId?: Record<string, { src: string; alt: string }>
|
|
@@ -81,6 +78,12 @@ type CheckoutClientProps = {
|
|
|
81
78
|
logError?: CheckoutLogError
|
|
82
79
|
/** Receives every decorated cart returned by a summary mutation. */
|
|
83
80
|
onCartChange?: (cart: Cart) => void
|
|
81
|
+
/**
|
|
82
|
+
* Extra payment tabs forwarded to CheckoutPaymentMethodList — the seam
|
|
83
|
+
* for embedded third-party providers rendered in the same radio-card
|
|
84
|
+
* style as card/cod. See the prop's JSDoc there.
|
|
85
|
+
*/
|
|
86
|
+
extraPaymentTabs?: Array<{ id: string; label: string; content: React.ReactNode }>
|
|
84
87
|
}
|
|
85
88
|
|
|
86
89
|
export function CheckoutClient({
|
|
@@ -92,7 +95,6 @@ export function CheckoutClient({
|
|
|
92
95
|
countryCode,
|
|
93
96
|
countries,
|
|
94
97
|
paymentMethodFilter,
|
|
95
|
-
codConfig,
|
|
96
98
|
showGiftCards = true,
|
|
97
99
|
logoByFulfillmentOptionId,
|
|
98
100
|
appearance,
|
|
@@ -102,6 +104,7 @@ export function CheckoutClient({
|
|
|
102
104
|
resolveTrackingMetadata,
|
|
103
105
|
logError,
|
|
104
106
|
onCartChange,
|
|
107
|
+
extraPaymentTabs,
|
|
105
108
|
}: CheckoutClientProps) {
|
|
106
109
|
const o = useCheckoutOrchestration({
|
|
107
110
|
client,
|
|
@@ -112,7 +115,6 @@ export function CheckoutClient({
|
|
|
112
115
|
countryCode,
|
|
113
116
|
countries,
|
|
114
117
|
paymentMethodFilter,
|
|
115
|
-
codConfig,
|
|
116
118
|
orderConfirmedPath,
|
|
117
119
|
onOrderPlaced,
|
|
118
120
|
resolveTrackingMetadata,
|
|
@@ -195,6 +197,7 @@ export function CheckoutClient({
|
|
|
195
197
|
}
|
|
196
198
|
total={o.optimisticTotal}
|
|
197
199
|
logError={logError}
|
|
200
|
+
extraTabs={extraPaymentTabs}
|
|
198
201
|
/>
|
|
199
202
|
</div>
|
|
200
203
|
|
|
@@ -208,8 +211,8 @@ export function CheckoutClient({
|
|
|
208
211
|
onOptimisticShippingClear={() =>
|
|
209
212
|
o.setOptimisticShippingCost(null)
|
|
210
213
|
}
|
|
211
|
-
|
|
212
|
-
|
|
214
|
+
optimisticMethodFee={o.optimisticMethodFee}
|
|
215
|
+
onOptimisticMethodFeeClear={() => o.setOptimisticMethodFee(null)}
|
|
213
216
|
showGiftCards={showGiftCards}
|
|
214
217
|
onCartChange={handleCartChange}
|
|
215
218
|
/>
|
|
@@ -13,7 +13,7 @@ import { useCheckoutLabels } from "./context"
|
|
|
13
13
|
* Ported from `@1click/ui/src/checkout/company-details.tsx` (v2.3.1)
|
|
14
14
|
* unchanged — pure form UI; the values ride `formData` and the
|
|
15
15
|
* orchestration hook persists them into `cart.metadata`
|
|
16
|
-
* (company_name/company_vat/company_mol/company_address).
|
|
16
|
+
* (company_name/company_vat/company_mol/company_address). Cartbase upgrade
|
|
17
17
|
* over the @1click KNOWN_ISSUES state: the hook ALSO syncs
|
|
18
18
|
* `company_name`/`company_eik` onto the signed-in customer profile
|
|
19
19
|
* (PATCH /api/store/customers/me — first-class columns,
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* shipping-address fields. Returns true if every field matches.
|
|
4
4
|
*
|
|
5
5
|
* Ported from `@1click/ui/src/data/util/compare-addresses.ts` (v2.3.1)
|
|
6
|
-
* unchanged. Lives in the checkout family because the
|
|
6
|
+
* unchanged. Lives in the checkout family because the Cartbase SDK has no
|
|
7
7
|
* data/util layer (the @1click data layer became `@cartbase/storefront/api`).
|
|
8
8
|
* Extra file beyond the pre-declared export list → exported from the
|
|
9
9
|
* family barrel only.
|
|
@@ -15,16 +15,16 @@ import { translatePromotionError } from "./promotion-error-copy"
|
|
|
15
15
|
* amount.
|
|
16
16
|
*
|
|
17
17
|
* Ported from `@1click/ui/src/checkout/discount-section.tsx` (v2.3.1) with
|
|
18
|
-
* the
|
|
18
|
+
* the Cartbase data seam:
|
|
19
19
|
*
|
|
20
20
|
* - `applyPromotions(codes)` (Medusa js-sdk server action, full-list
|
|
21
21
|
* replace) → `POST /api/store/carts/:id/promotions {promo_codes}` — the
|
|
22
|
-
*
|
|
22
|
+
* Cartbase route is ADDITIVE (upserts each code's link, then re-applies),
|
|
23
23
|
* so only the NEW code is sent; already-applied codes stay put. The SDK
|
|
24
24
|
* carts module ships no wrapper for this route yet, so the component
|
|
25
25
|
* calls it through the client transport with the documented DTO
|
|
26
26
|
* (verified against src/app/api/store/carts/[id]/promotions/route.ts).
|
|
27
|
-
* - `cart.promotions` on the
|
|
27
|
+
* - `cart.promotions` on the Cartbase wire is the raw pivot embed
|
|
28
28
|
* (`[{promotion: {..., application_method}}]`) — unwrapped here, with a
|
|
29
29
|
* flat-row fallback should the decoration ever flatten it.
|
|
30
30
|
* - Errors are code-first (`promotion_not_found` / `promotion_inactive` /
|
|
@@ -46,7 +46,7 @@ type AppliedPromotion = {
|
|
|
46
46
|
} | null
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
-
/** Unwrap the
|
|
49
|
+
/** Unwrap the Cartbase pivot embed; tolerate an already-flat row. */
|
|
50
50
|
function extractPromotions(cart: Cart): AppliedPromotion[] {
|
|
51
51
|
const raw = (cart.promotions ?? []) as Array<Record<string, unknown>>
|
|
52
52
|
return raw
|
|
@@ -84,7 +84,7 @@ export function DiscountSection({
|
|
|
84
84
|
setLoading(true)
|
|
85
85
|
setError("")
|
|
86
86
|
try {
|
|
87
|
-
// Additive apply — the
|
|
87
|
+
// Additive apply — the Cartbase route upserts the new code's link and
|
|
88
88
|
// re-applies every cart promotion; already-applied codes stay.
|
|
89
89
|
const { cart: updated } = await applyPromotions(client, cart.id, [code.trim()])
|
|
90
90
|
onCartChange?.(updated)
|
|
@@ -10,13 +10,13 @@ import { useCheckoutLabels } from "./context"
|
|
|
10
10
|
* EcontOfficeSelector — full Econt office picker for Bulgarian shipping.
|
|
11
11
|
*
|
|
12
12
|
* Ported from `@1click/ui/src/checkout/econt-office-selector.tsx` (v2.3.1)
|
|
13
|
-
* verbatim — this component has NO
|
|
13
|
+
* verbatim — this component has NO Cartbase data seam: the office directory
|
|
14
14
|
* comes straight from Econt's public Nomenclatures endpoint (client-side,
|
|
15
15
|
* cached globally per page load), and the CHOSEN office is handed to the
|
|
16
16
|
* orchestration hook, which writes it into `carrier_metadata` exactly once
|
|
17
17
|
* at Buy click (POST /api/store/carts/:id/prepare-checkout —
|
|
18
18
|
* docs/storefront/checkout.md). The geocode helpers moved into the checkout
|
|
19
|
-
* family (`./geocode`) because the
|
|
19
|
+
* family (`./geocode`) because the Cartbase lib family doesn't ship one.
|
|
20
20
|
*
|
|
21
21
|
* Behavior:
|
|
22
22
|
* - On mount, fetches the full Econt offices list from the public Econt
|
|
@@ -15,8 +15,8 @@ import { translateGiftCardError } from "./payment-error-copy"
|
|
|
15
15
|
* summary card, plus the applied-cards chip list (masked `last4`, per-card
|
|
16
16
|
* coverage, remove).
|
|
17
17
|
*
|
|
18
|
-
* NEW in the
|
|
19
|
-
*
|
|
18
|
+
* NEW in the Cartbase port (no @1click equivalent — gift-card tender is a
|
|
19
|
+
* Cartbase feature, docs/storefront/gift-cards.md). Built in the
|
|
20
20
|
* DiscountSection idiom so the two summary widgets read as one family.
|
|
21
21
|
*
|
|
22
22
|
* Contract discipline baked in:
|
package/src/checkout/index.ts
CHANGED
|
@@ -3,7 +3,7 @@ import type { CheckoutLabels } from "./labels"
|
|
|
3
3
|
/**
|
|
4
4
|
* Bulgarian translations for the checkout.
|
|
5
5
|
*
|
|
6
|
-
* Ported from `@1click/ui/src/checkout/labels-bg.ts` (v2.3.1) + the
|
|
6
|
+
* Ported from `@1click/ui/src/checkout/labels-bg.ts` (v2.3.1) + the Cartbase
|
|
7
7
|
* gift-card keys. Strings match the originals from mindpages-storefront's
|
|
8
8
|
* checkout-client monolith.
|
|
9
9
|
*
|
|
@@ -73,7 +73,7 @@ export const bulgarianCheckoutLabels: CheckoutLabels = {
|
|
|
73
73
|
discount: "Отстъпка",
|
|
74
74
|
discountCode: "Код за отстъпка",
|
|
75
75
|
discountSub: "Спестете с промо код",
|
|
76
|
-
|
|
76
|
+
paymentMethodFee: "Такса за плащане",
|
|
77
77
|
recommended: "Препоръчано за вас",
|
|
78
78
|
recommendedSoon: "Скоро тук",
|
|
79
79
|
recommendedSoonSub: "Персонализирани предложения за вас",
|