@cimplify/sdk 0.8.6 → 0.8.7
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/dist/react.d.mts +27 -1
- package/dist/react.d.ts +27 -1
- package/dist/react.js +196 -16
- package/dist/react.mjs +196 -17
- package/package.json +1 -1
package/dist/react.d.mts
CHANGED
|
@@ -77,6 +77,22 @@ interface CimplifyCheckoutProps {
|
|
|
77
77
|
}
|
|
78
78
|
declare function CimplifyCheckout({ client, businessId, cartId, locationId, linkUrl, orderTypes, enrollInLink, onComplete, onError, onStatusChange, appearance, demoMode, className, }: CimplifyCheckoutProps): React.ReactElement;
|
|
79
79
|
|
|
80
|
+
interface PriceProps {
|
|
81
|
+
/** The amount in base (business) currency. */
|
|
82
|
+
amount: number | string;
|
|
83
|
+
/** Optional CSS class name for the wrapping span. */
|
|
84
|
+
className?: string;
|
|
85
|
+
/** Optional prefix rendered before the formatted price (e.g. "+"). */
|
|
86
|
+
prefix?: string;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Price — renders a single price value in the user's chosen display currency.
|
|
90
|
+
*
|
|
91
|
+
* Reads `displayCurrency` and `convertPrice` from CimplifyProvider context
|
|
92
|
+
* so every price on the page stays consistent with the selected currency.
|
|
93
|
+
*/
|
|
94
|
+
declare function Price({ amount, className, prefix }: PriceProps): React.ReactElement;
|
|
95
|
+
|
|
80
96
|
interface CimplifyContextValue {
|
|
81
97
|
client: CimplifyClient;
|
|
82
98
|
business: Business | null;
|
|
@@ -87,6 +103,16 @@ interface CimplifyContextValue {
|
|
|
87
103
|
setCurrentLocation: (location: Location) => void;
|
|
88
104
|
isReady: boolean;
|
|
89
105
|
isDemoMode: boolean;
|
|
106
|
+
/** The business's pricing currency (always the base, for API calls). */
|
|
107
|
+
baseCurrency: string;
|
|
108
|
+
/** The currency prices are displayed in. Equals baseCurrency when no FX override is set. */
|
|
109
|
+
displayCurrency: string;
|
|
110
|
+
/** Set a display currency override for FX conversion. Pass null to reset to base currency. */
|
|
111
|
+
setDisplayCurrency: (currency: string | null) => void;
|
|
112
|
+
/** Convert a base-currency amount to the display currency. No-op when currencies match. */
|
|
113
|
+
convertPrice: (amount: number | string) => number;
|
|
114
|
+
/** Current FX rate (baseCurrency → displayCurrency). Null when no conversion is active. */
|
|
115
|
+
fxRate: number | null;
|
|
90
116
|
}
|
|
91
117
|
interface CimplifyProviderProps {
|
|
92
118
|
client?: CimplifyClient;
|
|
@@ -376,4 +402,4 @@ declare function useCheckout(): {
|
|
|
376
402
|
isLoading: boolean;
|
|
377
403
|
};
|
|
378
404
|
|
|
379
|
-
export { Ad, AdPosition, type AdProps, AdProvider, AdSlot, type AddToCartOptions, AddressElement, AuthElement, CimplifyCheckout, type CimplifyCheckoutProps, type CimplifyContextValue, CimplifyProvider, type CimplifyProviderProps, ElementsProvider, PaymentElement, type UseBundleOptions, type UseBundleResult, type UseCartItem, type UseCartOptions, type UseCartResult, type UseCategoriesOptions, type UseCategoriesResult, type UseCollectionOptions, type UseCollectionResult, type UseCollectionsOptions, type UseCollectionsResult, type UseCompositeOptions, type UseCompositeResult, type UseLocationsOptions, type UseLocationsResult, type UseOrderOptions, type UseOrderResult, type UseProductOptions, type UseProductResult, type UseProductsOptions, type UseProductsResult, type UseQuoteInput, type UseQuoteOptions, type UseQuoteResult, type UseSearchOptions, type UseSearchResult, useAds, useBundle, useCart, useCategories, useCheckout, useCimplify, useCollection, useCollections, useComposite, useElements, useElementsReady, useLocations, useOptionalCimplify, useOrder, useProduct, useProducts, useQuote, useSearch };
|
|
405
|
+
export { Ad, AdPosition, type AdProps, AdProvider, AdSlot, type AddToCartOptions, AddressElement, AuthElement, CimplifyCheckout, type CimplifyCheckoutProps, type CimplifyContextValue, CimplifyProvider, type CimplifyProviderProps, ElementsProvider, PaymentElement, Price, type PriceProps, type UseBundleOptions, type UseBundleResult, type UseCartItem, type UseCartOptions, type UseCartResult, type UseCategoriesOptions, type UseCategoriesResult, type UseCollectionOptions, type UseCollectionResult, type UseCollectionsOptions, type UseCollectionsResult, type UseCompositeOptions, type UseCompositeResult, type UseLocationsOptions, type UseLocationsResult, type UseOrderOptions, type UseOrderResult, type UseProductOptions, type UseProductResult, type UseProductsOptions, type UseProductsResult, type UseQuoteInput, type UseQuoteOptions, type UseQuoteResult, type UseSearchOptions, type UseSearchResult, useAds, useBundle, useCart, useCategories, useCheckout, useCimplify, useCollection, useCollections, useComposite, useElements, useElementsReady, useLocations, useOptionalCimplify, useOrder, useProduct, useProducts, useQuote, useSearch };
|
package/dist/react.d.ts
CHANGED
|
@@ -77,6 +77,22 @@ interface CimplifyCheckoutProps {
|
|
|
77
77
|
}
|
|
78
78
|
declare function CimplifyCheckout({ client, businessId, cartId, locationId, linkUrl, orderTypes, enrollInLink, onComplete, onError, onStatusChange, appearance, demoMode, className, }: CimplifyCheckoutProps): React.ReactElement;
|
|
79
79
|
|
|
80
|
+
interface PriceProps {
|
|
81
|
+
/** The amount in base (business) currency. */
|
|
82
|
+
amount: number | string;
|
|
83
|
+
/** Optional CSS class name for the wrapping span. */
|
|
84
|
+
className?: string;
|
|
85
|
+
/** Optional prefix rendered before the formatted price (e.g. "+"). */
|
|
86
|
+
prefix?: string;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Price — renders a single price value in the user's chosen display currency.
|
|
90
|
+
*
|
|
91
|
+
* Reads `displayCurrency` and `convertPrice` from CimplifyProvider context
|
|
92
|
+
* so every price on the page stays consistent with the selected currency.
|
|
93
|
+
*/
|
|
94
|
+
declare function Price({ amount, className, prefix }: PriceProps): React.ReactElement;
|
|
95
|
+
|
|
80
96
|
interface CimplifyContextValue {
|
|
81
97
|
client: CimplifyClient;
|
|
82
98
|
business: Business | null;
|
|
@@ -87,6 +103,16 @@ interface CimplifyContextValue {
|
|
|
87
103
|
setCurrentLocation: (location: Location) => void;
|
|
88
104
|
isReady: boolean;
|
|
89
105
|
isDemoMode: boolean;
|
|
106
|
+
/** The business's pricing currency (always the base, for API calls). */
|
|
107
|
+
baseCurrency: string;
|
|
108
|
+
/** The currency prices are displayed in. Equals baseCurrency when no FX override is set. */
|
|
109
|
+
displayCurrency: string;
|
|
110
|
+
/** Set a display currency override for FX conversion. Pass null to reset to base currency. */
|
|
111
|
+
setDisplayCurrency: (currency: string | null) => void;
|
|
112
|
+
/** Convert a base-currency amount to the display currency. No-op when currencies match. */
|
|
113
|
+
convertPrice: (amount: number | string) => number;
|
|
114
|
+
/** Current FX rate (baseCurrency → displayCurrency). Null when no conversion is active. */
|
|
115
|
+
fxRate: number | null;
|
|
90
116
|
}
|
|
91
117
|
interface CimplifyProviderProps {
|
|
92
118
|
client?: CimplifyClient;
|
|
@@ -376,4 +402,4 @@ declare function useCheckout(): {
|
|
|
376
402
|
isLoading: boolean;
|
|
377
403
|
};
|
|
378
404
|
|
|
379
|
-
export { Ad, AdPosition, type AdProps, AdProvider, AdSlot, type AddToCartOptions, AddressElement, AuthElement, CimplifyCheckout, type CimplifyCheckoutProps, type CimplifyContextValue, CimplifyProvider, type CimplifyProviderProps, ElementsProvider, PaymentElement, type UseBundleOptions, type UseBundleResult, type UseCartItem, type UseCartOptions, type UseCartResult, type UseCategoriesOptions, type UseCategoriesResult, type UseCollectionOptions, type UseCollectionResult, type UseCollectionsOptions, type UseCollectionsResult, type UseCompositeOptions, type UseCompositeResult, type UseLocationsOptions, type UseLocationsResult, type UseOrderOptions, type UseOrderResult, type UseProductOptions, type UseProductResult, type UseProductsOptions, type UseProductsResult, type UseQuoteInput, type UseQuoteOptions, type UseQuoteResult, type UseSearchOptions, type UseSearchResult, useAds, useBundle, useCart, useCategories, useCheckout, useCimplify, useCollection, useCollections, useComposite, useElements, useElementsReady, useLocations, useOptionalCimplify, useOrder, useProduct, useProducts, useQuote, useSearch };
|
|
405
|
+
export { Ad, AdPosition, type AdProps, AdProvider, AdSlot, type AddToCartOptions, AddressElement, AuthElement, CimplifyCheckout, type CimplifyCheckoutProps, type CimplifyContextValue, CimplifyProvider, type CimplifyProviderProps, ElementsProvider, PaymentElement, Price, type PriceProps, type UseBundleOptions, type UseBundleResult, type UseCartItem, type UseCartOptions, type UseCartResult, type UseCategoriesOptions, type UseCategoriesResult, type UseCollectionOptions, type UseCollectionResult, type UseCollectionsOptions, type UseCollectionsResult, type UseCompositeOptions, type UseCompositeResult, type UseLocationsOptions, type UseLocationsResult, type UseOrderOptions, type UseOrderResult, type UseProductOptions, type UseProductResult, type UseProductsOptions, type UseProductsResult, type UseQuoteInput, type UseQuoteOptions, type UseQuoteResult, type UseSearchOptions, type UseSearchResult, useAds, useBundle, useCart, useCategories, useCheckout, useCimplify, useCollection, useCollections, useComposite, useElements, useElementsReady, useLocations, useOptionalCimplify, useOrder, useProduct, useProducts, useQuote, useSearch };
|
package/dist/react.js
CHANGED
|
@@ -748,6 +748,110 @@ function CimplifyCheckout({
|
|
|
748
748
|
] });
|
|
749
749
|
}
|
|
750
750
|
|
|
751
|
+
// src/utils/price.ts
|
|
752
|
+
var CURRENCY_SYMBOLS = {
|
|
753
|
+
// Major world currencies
|
|
754
|
+
USD: "$",
|
|
755
|
+
EUR: "\u20AC",
|
|
756
|
+
GBP: "\xA3",
|
|
757
|
+
JPY: "\xA5",
|
|
758
|
+
CNY: "\xA5",
|
|
759
|
+
CHF: "CHF",
|
|
760
|
+
CAD: "C$",
|
|
761
|
+
AUD: "A$",
|
|
762
|
+
NZD: "NZ$",
|
|
763
|
+
HKD: "HK$",
|
|
764
|
+
SGD: "S$",
|
|
765
|
+
INR: "\u20B9",
|
|
766
|
+
BRL: "R$",
|
|
767
|
+
MXN: "MX$",
|
|
768
|
+
KRW: "\u20A9",
|
|
769
|
+
RUB: "\u20BD",
|
|
770
|
+
TRY: "\u20BA",
|
|
771
|
+
THB: "\u0E3F",
|
|
772
|
+
PLN: "z\u0142",
|
|
773
|
+
SEK: "kr",
|
|
774
|
+
NOK: "kr",
|
|
775
|
+
DKK: "kr",
|
|
776
|
+
CZK: "K\u010D",
|
|
777
|
+
HUF: "Ft",
|
|
778
|
+
ILS: "\u20AA",
|
|
779
|
+
AED: "\u062F.\u0625",
|
|
780
|
+
SAR: "\uFDFC",
|
|
781
|
+
MYR: "RM",
|
|
782
|
+
PHP: "\u20B1",
|
|
783
|
+
IDR: "Rp",
|
|
784
|
+
VND: "\u20AB",
|
|
785
|
+
TWD: "NT$",
|
|
786
|
+
// African currencies
|
|
787
|
+
GHS: "GH\u20B5",
|
|
788
|
+
NGN: "\u20A6",
|
|
789
|
+
KES: "KSh",
|
|
790
|
+
ZAR: "R",
|
|
791
|
+
XOF: "CFA",
|
|
792
|
+
XAF: "FCFA",
|
|
793
|
+
EGP: "E\xA3",
|
|
794
|
+
MAD: "MAD",
|
|
795
|
+
TZS: "TSh",
|
|
796
|
+
UGX: "USh",
|
|
797
|
+
RWF: "FRw",
|
|
798
|
+
ETB: "Br",
|
|
799
|
+
ZMW: "ZK",
|
|
800
|
+
BWP: "P",
|
|
801
|
+
MUR: "\u20A8",
|
|
802
|
+
SCR: "\u20A8",
|
|
803
|
+
NAD: "N$",
|
|
804
|
+
SZL: "E",
|
|
805
|
+
LSL: "L",
|
|
806
|
+
MWK: "MK",
|
|
807
|
+
AOA: "Kz",
|
|
808
|
+
CDF: "FC",
|
|
809
|
+
GMD: "D",
|
|
810
|
+
GNF: "FG",
|
|
811
|
+
LRD: "L$",
|
|
812
|
+
SLL: "Le",
|
|
813
|
+
MZN: "MT",
|
|
814
|
+
SDG: "SDG",
|
|
815
|
+
SSP: "SSP",
|
|
816
|
+
SOS: "Sh.So.",
|
|
817
|
+
DJF: "Fdj",
|
|
818
|
+
ERN: "Nfk",
|
|
819
|
+
CVE: "$",
|
|
820
|
+
STN: "Db",
|
|
821
|
+
KMF: "CF",
|
|
822
|
+
BIF: "FBu"
|
|
823
|
+
};
|
|
824
|
+
function getCurrencySymbol(currencyCode2) {
|
|
825
|
+
return CURRENCY_SYMBOLS[currencyCode2.toUpperCase()] || currencyCode2;
|
|
826
|
+
}
|
|
827
|
+
function formatPrice(amount, currency = "GHS", locale = "en-US") {
|
|
828
|
+
const numAmount = typeof amount === "string" ? parseFloat(amount) : amount;
|
|
829
|
+
if (isNaN(numAmount)) {
|
|
830
|
+
return `${getCurrencySymbol(currency)}0.00`;
|
|
831
|
+
}
|
|
832
|
+
try {
|
|
833
|
+
return new Intl.NumberFormat(locale, {
|
|
834
|
+
style: "currency",
|
|
835
|
+
currency: currency.toUpperCase(),
|
|
836
|
+
minimumFractionDigits: 2,
|
|
837
|
+
maximumFractionDigits: 2
|
|
838
|
+
}).format(numAmount);
|
|
839
|
+
} catch {
|
|
840
|
+
return `${getCurrencySymbol(currency)}${numAmount.toFixed(2)}`;
|
|
841
|
+
}
|
|
842
|
+
}
|
|
843
|
+
function parsePrice(value) {
|
|
844
|
+
if (value === void 0 || value === null) {
|
|
845
|
+
return 0;
|
|
846
|
+
}
|
|
847
|
+
if (typeof value === "number") {
|
|
848
|
+
return isNaN(value) ? 0 : value;
|
|
849
|
+
}
|
|
850
|
+
const cleaned = value.replace(/[^\d.-]/g, "");
|
|
851
|
+
const parsed = parseFloat(cleaned);
|
|
852
|
+
return isNaN(parsed) ? 0 : parsed;
|
|
853
|
+
}
|
|
854
|
+
|
|
751
855
|
// src/types/common.ts
|
|
752
856
|
function money(value) {
|
|
753
857
|
return value;
|
|
@@ -1359,19 +1463,6 @@ var MOBILE_MONEY_PROVIDER = {
|
|
|
1359
1463
|
AIRTEL: "airtel"
|
|
1360
1464
|
};
|
|
1361
1465
|
|
|
1362
|
-
// src/utils/price.ts
|
|
1363
|
-
function parsePrice(value) {
|
|
1364
|
-
if (value === void 0 || value === null) {
|
|
1365
|
-
return 0;
|
|
1366
|
-
}
|
|
1367
|
-
if (typeof value === "number") {
|
|
1368
|
-
return isNaN(value) ? 0 : value;
|
|
1369
|
-
}
|
|
1370
|
-
const cleaned = value.replace(/[^\d.-]/g, "");
|
|
1371
|
-
const parsed = parseFloat(cleaned);
|
|
1372
|
-
return isNaN(parsed) ? 0 : parsed;
|
|
1373
|
-
}
|
|
1374
|
-
|
|
1375
1466
|
// src/utils/payment.ts
|
|
1376
1467
|
var PAYMENT_SUCCESS_STATUSES = /* @__PURE__ */ new Set([
|
|
1377
1468
|
"success",
|
|
@@ -4320,6 +4411,8 @@ function createCimplifyClient(config = {}) {
|
|
|
4320
4411
|
return new CimplifyClient(config);
|
|
4321
4412
|
}
|
|
4322
4413
|
var LOCATION_STORAGE_KEY = "cimplify_location_id";
|
|
4414
|
+
var DISPLAY_CURRENCY_STORAGE_KEY = "cimplify_display_currency";
|
|
4415
|
+
var FX_REFRESH_INTERVAL = 12e4;
|
|
4323
4416
|
var DEFAULT_CURRENCY = "USD";
|
|
4324
4417
|
var DEFAULT_COUNTRY = "US";
|
|
4325
4418
|
function createDefaultClient() {
|
|
@@ -4348,6 +4441,27 @@ function setStoredLocationId(locationId) {
|
|
|
4348
4441
|
}
|
|
4349
4442
|
window.localStorage.setItem(LOCATION_STORAGE_KEY, locationId);
|
|
4350
4443
|
}
|
|
4444
|
+
function getStoredDisplayCurrency() {
|
|
4445
|
+
if (typeof window === "undefined" || !window.localStorage) {
|
|
4446
|
+
return null;
|
|
4447
|
+
}
|
|
4448
|
+
const value = window.localStorage.getItem(DISPLAY_CURRENCY_STORAGE_KEY);
|
|
4449
|
+
if (!value) {
|
|
4450
|
+
return null;
|
|
4451
|
+
}
|
|
4452
|
+
const normalized = value.trim().toUpperCase();
|
|
4453
|
+
return normalized.length > 0 ? normalized : null;
|
|
4454
|
+
}
|
|
4455
|
+
function setStoredDisplayCurrency(currency) {
|
|
4456
|
+
if (typeof window === "undefined" || !window.localStorage) {
|
|
4457
|
+
return;
|
|
4458
|
+
}
|
|
4459
|
+
if (!currency) {
|
|
4460
|
+
window.localStorage.removeItem(DISPLAY_CURRENCY_STORAGE_KEY);
|
|
4461
|
+
return;
|
|
4462
|
+
}
|
|
4463
|
+
window.localStorage.setItem(DISPLAY_CURRENCY_STORAGE_KEY, currency.toUpperCase());
|
|
4464
|
+
}
|
|
4351
4465
|
function resolveInitialLocation(locations) {
|
|
4352
4466
|
if (locations.length === 0) {
|
|
4353
4467
|
return null;
|
|
@@ -4377,6 +4491,54 @@ function CimplifyProvider({
|
|
|
4377
4491
|
onLocationChangeRef.current = onLocationChange;
|
|
4378
4492
|
}, [onLocationChange]);
|
|
4379
4493
|
const isDemoMode = resolvedClient.getPublicKey().trim().length === 0;
|
|
4494
|
+
const baseCurrency = business?.default_currency || DEFAULT_CURRENCY;
|
|
4495
|
+
const [displayCurrencyOverride, setDisplayCurrencyOverride] = React2.useState(
|
|
4496
|
+
() => getStoredDisplayCurrency()
|
|
4497
|
+
);
|
|
4498
|
+
const [fxRate, setFxRate] = React2.useState(null);
|
|
4499
|
+
const displayCurrency = displayCurrencyOverride && displayCurrencyOverride !== baseCurrency ? displayCurrencyOverride : baseCurrency;
|
|
4500
|
+
const setDisplayCurrency = React2.useCallback(
|
|
4501
|
+
(currency) => {
|
|
4502
|
+
const normalized = currency?.trim().toUpperCase() || null;
|
|
4503
|
+
setDisplayCurrencyOverride(normalized);
|
|
4504
|
+
setStoredDisplayCurrency(normalized);
|
|
4505
|
+
if (!normalized || normalized === baseCurrency) {
|
|
4506
|
+
setFxRate(null);
|
|
4507
|
+
}
|
|
4508
|
+
},
|
|
4509
|
+
[baseCurrency]
|
|
4510
|
+
);
|
|
4511
|
+
React2.useEffect(() => {
|
|
4512
|
+
if (displayCurrency === baseCurrency || isDemoMode) {
|
|
4513
|
+
setFxRate(null);
|
|
4514
|
+
return;
|
|
4515
|
+
}
|
|
4516
|
+
let cancelled = false;
|
|
4517
|
+
async function fetchRate() {
|
|
4518
|
+
const result = await resolvedClient.fx.getRate(
|
|
4519
|
+
baseCurrency,
|
|
4520
|
+
displayCurrency
|
|
4521
|
+
);
|
|
4522
|
+
if (!cancelled && result.ok) {
|
|
4523
|
+
setFxRate(result.value.rate);
|
|
4524
|
+
}
|
|
4525
|
+
}
|
|
4526
|
+
void fetchRate();
|
|
4527
|
+
const intervalId = setInterval(() => void fetchRate(), FX_REFRESH_INTERVAL);
|
|
4528
|
+
return () => {
|
|
4529
|
+
cancelled = true;
|
|
4530
|
+
clearInterval(intervalId);
|
|
4531
|
+
};
|
|
4532
|
+
}, [resolvedClient, baseCurrency, displayCurrency, isDemoMode]);
|
|
4533
|
+
const convertPrice = React2.useCallback(
|
|
4534
|
+
(amount) => {
|
|
4535
|
+
const num = typeof amount === "string" ? parseFloat(amount) : amount;
|
|
4536
|
+
if (isNaN(num)) return 0;
|
|
4537
|
+
if (!fxRate || displayCurrency === baseCurrency) return num;
|
|
4538
|
+
return Math.round(num * fxRate * 100) / 100;
|
|
4539
|
+
},
|
|
4540
|
+
[fxRate, displayCurrency, baseCurrency]
|
|
4541
|
+
);
|
|
4380
4542
|
const setCurrentLocation = React2.useCallback(
|
|
4381
4543
|
(location) => {
|
|
4382
4544
|
setCurrentLocationState(location);
|
|
@@ -4446,22 +4608,32 @@ function CimplifyProvider({
|
|
|
4446
4608
|
() => ({
|
|
4447
4609
|
client: resolvedClient,
|
|
4448
4610
|
business,
|
|
4449
|
-
currency:
|
|
4611
|
+
currency: baseCurrency,
|
|
4450
4612
|
country: business?.country_code || DEFAULT_COUNTRY,
|
|
4451
4613
|
locations,
|
|
4452
4614
|
currentLocation,
|
|
4453
4615
|
setCurrentLocation,
|
|
4454
4616
|
isReady,
|
|
4455
|
-
isDemoMode
|
|
4617
|
+
isDemoMode,
|
|
4618
|
+
baseCurrency,
|
|
4619
|
+
displayCurrency,
|
|
4620
|
+
setDisplayCurrency,
|
|
4621
|
+
convertPrice,
|
|
4622
|
+
fxRate
|
|
4456
4623
|
}),
|
|
4457
4624
|
[
|
|
4458
4625
|
resolvedClient,
|
|
4459
4626
|
business,
|
|
4627
|
+
baseCurrency,
|
|
4460
4628
|
locations,
|
|
4461
4629
|
currentLocation,
|
|
4462
4630
|
setCurrentLocation,
|
|
4463
4631
|
isReady,
|
|
4464
|
-
isDemoMode
|
|
4632
|
+
isDemoMode,
|
|
4633
|
+
displayCurrency,
|
|
4634
|
+
setDisplayCurrency,
|
|
4635
|
+
convertPrice,
|
|
4636
|
+
fxRate
|
|
4465
4637
|
]
|
|
4466
4638
|
);
|
|
4467
4639
|
return /* @__PURE__ */ jsxRuntime.jsx(CimplifyContext.Provider, { value: contextValue, children });
|
|
@@ -4476,6 +4648,13 @@ function useCimplify() {
|
|
|
4476
4648
|
function useOptionalCimplify() {
|
|
4477
4649
|
return React2.useContext(CimplifyContext);
|
|
4478
4650
|
}
|
|
4651
|
+
function Price({ amount, className, prefix }) {
|
|
4652
|
+
const { displayCurrency, convertPrice } = useCimplify();
|
|
4653
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("span", { className, children: [
|
|
4654
|
+
prefix,
|
|
4655
|
+
formatPrice(convertPrice(amount), displayCurrency)
|
|
4656
|
+
] });
|
|
4657
|
+
}
|
|
4479
4658
|
var productsCache = /* @__PURE__ */ new Map();
|
|
4480
4659
|
var productsInflight = /* @__PURE__ */ new Map();
|
|
4481
4660
|
function buildProductsCacheKey(client, locationId, options) {
|
|
@@ -6513,6 +6692,7 @@ exports.CimplifyCheckout = CimplifyCheckout;
|
|
|
6513
6692
|
exports.CimplifyProvider = CimplifyProvider;
|
|
6514
6693
|
exports.ElementsProvider = ElementsProvider;
|
|
6515
6694
|
exports.PaymentElement = PaymentElement;
|
|
6695
|
+
exports.Price = Price;
|
|
6516
6696
|
exports.useAds = useAds;
|
|
6517
6697
|
exports.useBundle = useBundle;
|
|
6518
6698
|
exports.useCart = useCart;
|
package/dist/react.mjs
CHANGED
|
@@ -742,6 +742,110 @@ function CimplifyCheckout({
|
|
|
742
742
|
] });
|
|
743
743
|
}
|
|
744
744
|
|
|
745
|
+
// src/utils/price.ts
|
|
746
|
+
var CURRENCY_SYMBOLS = {
|
|
747
|
+
// Major world currencies
|
|
748
|
+
USD: "$",
|
|
749
|
+
EUR: "\u20AC",
|
|
750
|
+
GBP: "\xA3",
|
|
751
|
+
JPY: "\xA5",
|
|
752
|
+
CNY: "\xA5",
|
|
753
|
+
CHF: "CHF",
|
|
754
|
+
CAD: "C$",
|
|
755
|
+
AUD: "A$",
|
|
756
|
+
NZD: "NZ$",
|
|
757
|
+
HKD: "HK$",
|
|
758
|
+
SGD: "S$",
|
|
759
|
+
INR: "\u20B9",
|
|
760
|
+
BRL: "R$",
|
|
761
|
+
MXN: "MX$",
|
|
762
|
+
KRW: "\u20A9",
|
|
763
|
+
RUB: "\u20BD",
|
|
764
|
+
TRY: "\u20BA",
|
|
765
|
+
THB: "\u0E3F",
|
|
766
|
+
PLN: "z\u0142",
|
|
767
|
+
SEK: "kr",
|
|
768
|
+
NOK: "kr",
|
|
769
|
+
DKK: "kr",
|
|
770
|
+
CZK: "K\u010D",
|
|
771
|
+
HUF: "Ft",
|
|
772
|
+
ILS: "\u20AA",
|
|
773
|
+
AED: "\u062F.\u0625",
|
|
774
|
+
SAR: "\uFDFC",
|
|
775
|
+
MYR: "RM",
|
|
776
|
+
PHP: "\u20B1",
|
|
777
|
+
IDR: "Rp",
|
|
778
|
+
VND: "\u20AB",
|
|
779
|
+
TWD: "NT$",
|
|
780
|
+
// African currencies
|
|
781
|
+
GHS: "GH\u20B5",
|
|
782
|
+
NGN: "\u20A6",
|
|
783
|
+
KES: "KSh",
|
|
784
|
+
ZAR: "R",
|
|
785
|
+
XOF: "CFA",
|
|
786
|
+
XAF: "FCFA",
|
|
787
|
+
EGP: "E\xA3",
|
|
788
|
+
MAD: "MAD",
|
|
789
|
+
TZS: "TSh",
|
|
790
|
+
UGX: "USh",
|
|
791
|
+
RWF: "FRw",
|
|
792
|
+
ETB: "Br",
|
|
793
|
+
ZMW: "ZK",
|
|
794
|
+
BWP: "P",
|
|
795
|
+
MUR: "\u20A8",
|
|
796
|
+
SCR: "\u20A8",
|
|
797
|
+
NAD: "N$",
|
|
798
|
+
SZL: "E",
|
|
799
|
+
LSL: "L",
|
|
800
|
+
MWK: "MK",
|
|
801
|
+
AOA: "Kz",
|
|
802
|
+
CDF: "FC",
|
|
803
|
+
GMD: "D",
|
|
804
|
+
GNF: "FG",
|
|
805
|
+
LRD: "L$",
|
|
806
|
+
SLL: "Le",
|
|
807
|
+
MZN: "MT",
|
|
808
|
+
SDG: "SDG",
|
|
809
|
+
SSP: "SSP",
|
|
810
|
+
SOS: "Sh.So.",
|
|
811
|
+
DJF: "Fdj",
|
|
812
|
+
ERN: "Nfk",
|
|
813
|
+
CVE: "$",
|
|
814
|
+
STN: "Db",
|
|
815
|
+
KMF: "CF",
|
|
816
|
+
BIF: "FBu"
|
|
817
|
+
};
|
|
818
|
+
function getCurrencySymbol(currencyCode2) {
|
|
819
|
+
return CURRENCY_SYMBOLS[currencyCode2.toUpperCase()] || currencyCode2;
|
|
820
|
+
}
|
|
821
|
+
function formatPrice(amount, currency = "GHS", locale = "en-US") {
|
|
822
|
+
const numAmount = typeof amount === "string" ? parseFloat(amount) : amount;
|
|
823
|
+
if (isNaN(numAmount)) {
|
|
824
|
+
return `${getCurrencySymbol(currency)}0.00`;
|
|
825
|
+
}
|
|
826
|
+
try {
|
|
827
|
+
return new Intl.NumberFormat(locale, {
|
|
828
|
+
style: "currency",
|
|
829
|
+
currency: currency.toUpperCase(),
|
|
830
|
+
minimumFractionDigits: 2,
|
|
831
|
+
maximumFractionDigits: 2
|
|
832
|
+
}).format(numAmount);
|
|
833
|
+
} catch {
|
|
834
|
+
return `${getCurrencySymbol(currency)}${numAmount.toFixed(2)}`;
|
|
835
|
+
}
|
|
836
|
+
}
|
|
837
|
+
function parsePrice(value) {
|
|
838
|
+
if (value === void 0 || value === null) {
|
|
839
|
+
return 0;
|
|
840
|
+
}
|
|
841
|
+
if (typeof value === "number") {
|
|
842
|
+
return isNaN(value) ? 0 : value;
|
|
843
|
+
}
|
|
844
|
+
const cleaned = value.replace(/[^\d.-]/g, "");
|
|
845
|
+
const parsed = parseFloat(cleaned);
|
|
846
|
+
return isNaN(parsed) ? 0 : parsed;
|
|
847
|
+
}
|
|
848
|
+
|
|
745
849
|
// src/types/common.ts
|
|
746
850
|
function money(value) {
|
|
747
851
|
return value;
|
|
@@ -1353,19 +1457,6 @@ var MOBILE_MONEY_PROVIDER = {
|
|
|
1353
1457
|
AIRTEL: "airtel"
|
|
1354
1458
|
};
|
|
1355
1459
|
|
|
1356
|
-
// src/utils/price.ts
|
|
1357
|
-
function parsePrice(value) {
|
|
1358
|
-
if (value === void 0 || value === null) {
|
|
1359
|
-
return 0;
|
|
1360
|
-
}
|
|
1361
|
-
if (typeof value === "number") {
|
|
1362
|
-
return isNaN(value) ? 0 : value;
|
|
1363
|
-
}
|
|
1364
|
-
const cleaned = value.replace(/[^\d.-]/g, "");
|
|
1365
|
-
const parsed = parseFloat(cleaned);
|
|
1366
|
-
return isNaN(parsed) ? 0 : parsed;
|
|
1367
|
-
}
|
|
1368
|
-
|
|
1369
1460
|
// src/utils/payment.ts
|
|
1370
1461
|
var PAYMENT_SUCCESS_STATUSES = /* @__PURE__ */ new Set([
|
|
1371
1462
|
"success",
|
|
@@ -4314,6 +4405,8 @@ function createCimplifyClient(config = {}) {
|
|
|
4314
4405
|
return new CimplifyClient(config);
|
|
4315
4406
|
}
|
|
4316
4407
|
var LOCATION_STORAGE_KEY = "cimplify_location_id";
|
|
4408
|
+
var DISPLAY_CURRENCY_STORAGE_KEY = "cimplify_display_currency";
|
|
4409
|
+
var FX_REFRESH_INTERVAL = 12e4;
|
|
4317
4410
|
var DEFAULT_CURRENCY = "USD";
|
|
4318
4411
|
var DEFAULT_COUNTRY = "US";
|
|
4319
4412
|
function createDefaultClient() {
|
|
@@ -4342,6 +4435,27 @@ function setStoredLocationId(locationId) {
|
|
|
4342
4435
|
}
|
|
4343
4436
|
window.localStorage.setItem(LOCATION_STORAGE_KEY, locationId);
|
|
4344
4437
|
}
|
|
4438
|
+
function getStoredDisplayCurrency() {
|
|
4439
|
+
if (typeof window === "undefined" || !window.localStorage) {
|
|
4440
|
+
return null;
|
|
4441
|
+
}
|
|
4442
|
+
const value = window.localStorage.getItem(DISPLAY_CURRENCY_STORAGE_KEY);
|
|
4443
|
+
if (!value) {
|
|
4444
|
+
return null;
|
|
4445
|
+
}
|
|
4446
|
+
const normalized = value.trim().toUpperCase();
|
|
4447
|
+
return normalized.length > 0 ? normalized : null;
|
|
4448
|
+
}
|
|
4449
|
+
function setStoredDisplayCurrency(currency) {
|
|
4450
|
+
if (typeof window === "undefined" || !window.localStorage) {
|
|
4451
|
+
return;
|
|
4452
|
+
}
|
|
4453
|
+
if (!currency) {
|
|
4454
|
+
window.localStorage.removeItem(DISPLAY_CURRENCY_STORAGE_KEY);
|
|
4455
|
+
return;
|
|
4456
|
+
}
|
|
4457
|
+
window.localStorage.setItem(DISPLAY_CURRENCY_STORAGE_KEY, currency.toUpperCase());
|
|
4458
|
+
}
|
|
4345
4459
|
function resolveInitialLocation(locations) {
|
|
4346
4460
|
if (locations.length === 0) {
|
|
4347
4461
|
return null;
|
|
@@ -4371,6 +4485,54 @@ function CimplifyProvider({
|
|
|
4371
4485
|
onLocationChangeRef.current = onLocationChange;
|
|
4372
4486
|
}, [onLocationChange]);
|
|
4373
4487
|
const isDemoMode = resolvedClient.getPublicKey().trim().length === 0;
|
|
4488
|
+
const baseCurrency = business?.default_currency || DEFAULT_CURRENCY;
|
|
4489
|
+
const [displayCurrencyOverride, setDisplayCurrencyOverride] = useState(
|
|
4490
|
+
() => getStoredDisplayCurrency()
|
|
4491
|
+
);
|
|
4492
|
+
const [fxRate, setFxRate] = useState(null);
|
|
4493
|
+
const displayCurrency = displayCurrencyOverride && displayCurrencyOverride !== baseCurrency ? displayCurrencyOverride : baseCurrency;
|
|
4494
|
+
const setDisplayCurrency = useCallback(
|
|
4495
|
+
(currency) => {
|
|
4496
|
+
const normalized = currency?.trim().toUpperCase() || null;
|
|
4497
|
+
setDisplayCurrencyOverride(normalized);
|
|
4498
|
+
setStoredDisplayCurrency(normalized);
|
|
4499
|
+
if (!normalized || normalized === baseCurrency) {
|
|
4500
|
+
setFxRate(null);
|
|
4501
|
+
}
|
|
4502
|
+
},
|
|
4503
|
+
[baseCurrency]
|
|
4504
|
+
);
|
|
4505
|
+
useEffect(() => {
|
|
4506
|
+
if (displayCurrency === baseCurrency || isDemoMode) {
|
|
4507
|
+
setFxRate(null);
|
|
4508
|
+
return;
|
|
4509
|
+
}
|
|
4510
|
+
let cancelled = false;
|
|
4511
|
+
async function fetchRate() {
|
|
4512
|
+
const result = await resolvedClient.fx.getRate(
|
|
4513
|
+
baseCurrency,
|
|
4514
|
+
displayCurrency
|
|
4515
|
+
);
|
|
4516
|
+
if (!cancelled && result.ok) {
|
|
4517
|
+
setFxRate(result.value.rate);
|
|
4518
|
+
}
|
|
4519
|
+
}
|
|
4520
|
+
void fetchRate();
|
|
4521
|
+
const intervalId = setInterval(() => void fetchRate(), FX_REFRESH_INTERVAL);
|
|
4522
|
+
return () => {
|
|
4523
|
+
cancelled = true;
|
|
4524
|
+
clearInterval(intervalId);
|
|
4525
|
+
};
|
|
4526
|
+
}, [resolvedClient, baseCurrency, displayCurrency, isDemoMode]);
|
|
4527
|
+
const convertPrice = useCallback(
|
|
4528
|
+
(amount) => {
|
|
4529
|
+
const num = typeof amount === "string" ? parseFloat(amount) : amount;
|
|
4530
|
+
if (isNaN(num)) return 0;
|
|
4531
|
+
if (!fxRate || displayCurrency === baseCurrency) return num;
|
|
4532
|
+
return Math.round(num * fxRate * 100) / 100;
|
|
4533
|
+
},
|
|
4534
|
+
[fxRate, displayCurrency, baseCurrency]
|
|
4535
|
+
);
|
|
4374
4536
|
const setCurrentLocation = useCallback(
|
|
4375
4537
|
(location) => {
|
|
4376
4538
|
setCurrentLocationState(location);
|
|
@@ -4440,22 +4602,32 @@ function CimplifyProvider({
|
|
|
4440
4602
|
() => ({
|
|
4441
4603
|
client: resolvedClient,
|
|
4442
4604
|
business,
|
|
4443
|
-
currency:
|
|
4605
|
+
currency: baseCurrency,
|
|
4444
4606
|
country: business?.country_code || DEFAULT_COUNTRY,
|
|
4445
4607
|
locations,
|
|
4446
4608
|
currentLocation,
|
|
4447
4609
|
setCurrentLocation,
|
|
4448
4610
|
isReady,
|
|
4449
|
-
isDemoMode
|
|
4611
|
+
isDemoMode,
|
|
4612
|
+
baseCurrency,
|
|
4613
|
+
displayCurrency,
|
|
4614
|
+
setDisplayCurrency,
|
|
4615
|
+
convertPrice,
|
|
4616
|
+
fxRate
|
|
4450
4617
|
}),
|
|
4451
4618
|
[
|
|
4452
4619
|
resolvedClient,
|
|
4453
4620
|
business,
|
|
4621
|
+
baseCurrency,
|
|
4454
4622
|
locations,
|
|
4455
4623
|
currentLocation,
|
|
4456
4624
|
setCurrentLocation,
|
|
4457
4625
|
isReady,
|
|
4458
|
-
isDemoMode
|
|
4626
|
+
isDemoMode,
|
|
4627
|
+
displayCurrency,
|
|
4628
|
+
setDisplayCurrency,
|
|
4629
|
+
convertPrice,
|
|
4630
|
+
fxRate
|
|
4459
4631
|
]
|
|
4460
4632
|
);
|
|
4461
4633
|
return /* @__PURE__ */ jsx(CimplifyContext.Provider, { value: contextValue, children });
|
|
@@ -4470,6 +4642,13 @@ function useCimplify() {
|
|
|
4470
4642
|
function useOptionalCimplify() {
|
|
4471
4643
|
return useContext(CimplifyContext);
|
|
4472
4644
|
}
|
|
4645
|
+
function Price({ amount, className, prefix }) {
|
|
4646
|
+
const { displayCurrency, convertPrice } = useCimplify();
|
|
4647
|
+
return /* @__PURE__ */ jsxs("span", { className, children: [
|
|
4648
|
+
prefix,
|
|
4649
|
+
formatPrice(convertPrice(amount), displayCurrency)
|
|
4650
|
+
] });
|
|
4651
|
+
}
|
|
4473
4652
|
var productsCache = /* @__PURE__ */ new Map();
|
|
4474
4653
|
var productsInflight = /* @__PURE__ */ new Map();
|
|
4475
4654
|
function buildProductsCacheKey(client, locationId, options) {
|
|
@@ -6499,4 +6678,4 @@ function useCheckout() {
|
|
|
6499
6678
|
return { submit, process, isLoading };
|
|
6500
6679
|
}
|
|
6501
6680
|
|
|
6502
|
-
export { Ad, AdProvider, AddressElement, AuthElement, CimplifyCheckout, CimplifyProvider, ElementsProvider, PaymentElement, useAds, useBundle, useCart, useCategories, useCheckout, useCimplify, useCollection, useCollections, useComposite, useElements, useElementsReady, useLocations, useOptionalCimplify, useOrder, useProduct, useProducts, useQuote, useSearch };
|
|
6681
|
+
export { Ad, AdProvider, AddressElement, AuthElement, CimplifyCheckout, CimplifyProvider, ElementsProvider, PaymentElement, Price, useAds, useBundle, useCart, useCategories, useCheckout, useCimplify, useCollection, useCollections, useComposite, useElements, useElementsReady, useLocations, useOptionalCimplify, useOrder, useProduct, useProducts, useQuote, useSearch };
|