@cimplify/sdk 0.8.6 → 0.8.8

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.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import React2, { createContext, useContext, useState, useEffect, useRef, useMemo, useCallback, useSyncExternalStore } from 'react';
1
+ import React3, { createContext, useContext, useState, useEffect, useRef, useMemo, useCallback, useSyncExternalStore } from 'react';
2
2
  import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
3
3
 
4
4
  // src/react/index.tsx
@@ -362,12 +362,13 @@ function getSelections(item) {
362
362
  }
363
363
  return void 0;
364
364
  }
365
- function mapItem(item) {
365
+ function mapItem(item, fx) {
366
+ const amt = (value) => fx ? String(fx.convertPrice(value)) : String(value);
366
367
  const result = {
367
368
  name: item.name,
368
369
  quantity: item.quantity,
369
- unit_price: String(item.base_price),
370
- total_price: String(item.total_price),
370
+ unit_price: amt(item.base_price),
371
+ total_price: amt(item.total_price),
371
372
  line_type: item.line_type
372
373
  };
373
374
  if (item.image_url) result.image_url = item.image_url;
@@ -380,7 +381,7 @@ function mapItem(item) {
380
381
  if (item.add_on_options?.length) {
381
382
  result.add_ons = item.add_on_options.map((opt) => ({
382
383
  name: opt.name,
383
- price: String(opt.price ?? "0")
384
+ price: amt(opt.price ?? "0")
384
385
  }));
385
386
  }
386
387
  if (item.special_instructions) {
@@ -388,359 +389,18 @@ function mapItem(item) {
388
389
  }
389
390
  return result;
390
391
  }
391
- function transformToCheckoutCart(cart) {
392
+ function transformToCheckoutCart(cart, fx) {
393
+ const amt = (value) => fx ? String(fx.convertPrice(value)) : String(value);
392
394
  return {
393
- items: cart.items.map(mapItem),
394
- subtotal: String(cart.pricing.subtotal),
395
- tax_amount: String(cart.pricing.tax_amount),
396
- total_discounts: String(cart.pricing.total_discounts),
397
- service_charge: String(cart.pricing.service_charge),
398
- total: String(cart.pricing.total_price),
399
- currency: cart.pricing.currency
395
+ items: cart.items.map((item) => mapItem(item, fx)),
396
+ subtotal: amt(cart.pricing.subtotal),
397
+ tax_amount: amt(cart.pricing.tax_amount),
398
+ total_discounts: amt(cart.pricing.total_discounts),
399
+ service_charge: amt(cart.pricing.service_charge),
400
+ total: amt(cart.pricing.total_price),
401
+ currency: fx?.displayCurrency ?? cart.pricing.currency
400
402
  };
401
403
  }
402
- var SPACE = { sm: 8};
403
- function shellColors(isDark, primaryColor) {
404
- return {
405
- text: isDark ? "#f4f4f5" : "#1a1a1a",
406
- textSecondary: isDark ? "#a1a1aa" : "#52525b",
407
- textMuted: isDark ? "#71717a" : "#a1a1aa",
408
- border: isDark ? "#27272a" : "#e4e4e7",
409
- surface: isDark ? "#18181b" : "#fafafa",
410
- error: "#dc2626",
411
- primary: primaryColor
412
- };
413
- }
414
- function statusToLabel(status) {
415
- if (!status) {
416
- return "";
417
- }
418
- if (status === "preparing") {
419
- return "Preparing checkout";
420
- }
421
- if (status === "recovering") {
422
- return "Resuming payment";
423
- }
424
- if (status === "processing") {
425
- return "Processing payment";
426
- }
427
- if (status === "awaiting_authorization") {
428
- return "Waiting for authorization";
429
- }
430
- if (status === "polling") {
431
- return "Confirming payment";
432
- }
433
- if (status === "finalizing") {
434
- return "Finalizing order";
435
- }
436
- if (status === "success") {
437
- return "Payment complete";
438
- }
439
- return "Payment failed";
440
- }
441
- function CimplifyCheckout({
442
- client,
443
- businessId,
444
- cartId,
445
- locationId,
446
- linkUrl,
447
- orderTypes,
448
- enrollInLink = true,
449
- onComplete,
450
- onError,
451
- onStatusChange,
452
- appearance,
453
- demoMode,
454
- className
455
- }) {
456
- const resolvedOrderTypes = useMemo(
457
- () => orderTypes && orderTypes.length > 0 ? orderTypes : ["pickup", "delivery"],
458
- [orderTypes]
459
- );
460
- const [orderType, setOrderType] = useState(resolvedOrderTypes[0] || "pickup");
461
- const [status, setStatus] = useState(null);
462
- const [statusText, setStatusText] = useState("");
463
- const [isSubmitting, setIsSubmitting] = useState(false);
464
- const [isInitializing, setIsInitializing] = useState(false);
465
- const [errorMessage, setErrorMessage] = useState(null);
466
- const [resolvedBusinessId, setResolvedBusinessId] = useState(businessId ?? null);
467
- const [resolvedCartId, setResolvedCartId] = useState(cartId ?? null);
468
- const [resolvedCart, setResolvedCart] = useState(null);
469
- const checkoutMountRef = useRef(null);
470
- const elementsRef = useRef(null);
471
- const activeCheckoutRef = useRef(null);
472
- const initialAppearanceRef = useRef(appearance);
473
- const hasWarnedInlineAppearanceRef = useRef(false);
474
- const isMountedRef = useRef(true);
475
- const demoRunRef = useRef(0);
476
- const isDemoCheckout = demoMode ?? client.getPublicKey().trim().length === 0;
477
- const isTestMode = client.isTestMode();
478
- const primaryColor = appearance?.variables?.primaryColor || "#0a2540";
479
- const isDark = appearance?.theme === "dark";
480
- const emitStatus = React2.useEffectEvent(
481
- (nextStatus, context = {}) => {
482
- setStatus(nextStatus);
483
- setStatusText(context.display_text || "");
484
- onStatusChange?.(nextStatus, context);
485
- }
486
- );
487
- const fireError = React2.useEffectEvent(
488
- (error) => {
489
- onError?.(error);
490
- }
491
- );
492
- useEffect(() => {
493
- if (!resolvedOrderTypes.includes(orderType)) {
494
- setOrderType(resolvedOrderTypes[0] || "pickup");
495
- }
496
- }, [resolvedOrderTypes, orderType]);
497
- useEffect(() => {
498
- if (appearance && appearance !== initialAppearanceRef.current && !hasWarnedInlineAppearanceRef.current) {
499
- hasWarnedInlineAppearanceRef.current = true;
500
- console.warn(
501
- "[Cimplify] `appearance` prop reference changed after mount. Elements keep the initial appearance to avoid iframe remount. Memoize appearance with useMemo() to remove this warning."
502
- );
503
- }
504
- }, [appearance]);
505
- useEffect(() => {
506
- let cancelled = false;
507
- async function bootstrap() {
508
- if (isDemoCheckout) {
509
- if (!cancelled) {
510
- setResolvedBusinessId(businessId ?? null);
511
- setResolvedCartId(cartId ?? "cart_demo");
512
- setIsInitializing(false);
513
- setErrorMessage(null);
514
- }
515
- return;
516
- }
517
- const needsBusinessResolve = !businessId;
518
- const needsCartResolve = !cartId;
519
- if (!needsBusinessResolve && !needsCartResolve) {
520
- if (!cancelled) {
521
- setResolvedBusinessId(businessId || null);
522
- setResolvedCartId(cartId || null);
523
- setIsInitializing(false);
524
- setErrorMessage(null);
525
- }
526
- client.cart.get().then((cartResult) => {
527
- if (!cancelled && cartResult.ok && cartResult.value) {
528
- setResolvedCart(cartResult.value);
529
- }
530
- }).catch(() => {
531
- });
532
- return;
533
- }
534
- if (!cancelled) {
535
- setIsInitializing(true);
536
- setErrorMessage(null);
537
- }
538
- let nextBusinessId = businessId ?? null;
539
- if (!nextBusinessId) {
540
- try {
541
- nextBusinessId = await client.resolveBusinessId();
542
- } catch {
543
- if (!cancelled) {
544
- const message = "Unable to initialize checkout business context.";
545
- setResolvedBusinessId(null);
546
- setResolvedCartId(null);
547
- setErrorMessage(message);
548
- setIsInitializing(false);
549
- fireError({ code: "BUSINESS_ID_REQUIRED", message });
550
- }
551
- return;
552
- }
553
- }
554
- let nextCartId = cartId ?? null;
555
- if (!nextCartId) {
556
- const cartResult = await client.cart.get();
557
- if (!cartResult.ok || !cartResult.value?.id || cartResult.value.items.length === 0) {
558
- if (!cancelled) {
559
- const message = "Your cart is empty. Add items before checkout.";
560
- setResolvedBusinessId(nextBusinessId);
561
- setResolvedCartId(null);
562
- setErrorMessage(message);
563
- setIsInitializing(false);
564
- fireError({ code: "CART_EMPTY", message });
565
- }
566
- return;
567
- }
568
- nextCartId = cartResult.value.id;
569
- if (!cancelled) {
570
- setResolvedCart(cartResult.value);
571
- }
572
- }
573
- if (!cancelled) {
574
- setResolvedBusinessId(nextBusinessId);
575
- setResolvedCartId(nextCartId);
576
- setIsInitializing(false);
577
- setErrorMessage(null);
578
- }
579
- }
580
- void bootstrap();
581
- return () => {
582
- cancelled = true;
583
- };
584
- }, [businessId, cartId, client, isDemoCheckout]);
585
- useEffect(() => {
586
- return () => {
587
- isMountedRef.current = false;
588
- demoRunRef.current += 1;
589
- activeCheckoutRef.current?.abort();
590
- activeCheckoutRef.current = null;
591
- };
592
- }, []);
593
- const handleSubmit = React2.useEffectEvent(async () => {
594
- if (isSubmitting || isInitializing || !resolvedCartId) {
595
- if (!resolvedCartId && !isInitializing) {
596
- const message = "Your cart is empty. Add items before checkout.";
597
- setErrorMessage(message);
598
- fireError({ code: "CART_EMPTY", message });
599
- }
600
- return;
601
- }
602
- setErrorMessage(null);
603
- setIsSubmitting(true);
604
- emitStatus("preparing", { display_text: statusToLabel("preparing") });
605
- if (isDemoCheckout) {
606
- const runId = demoRunRef.current + 1;
607
- demoRunRef.current = runId;
608
- const wait = async (ms) => {
609
- await new Promise((resolve) => setTimeout(resolve, ms));
610
- return isMountedRef.current && runId === demoRunRef.current;
611
- };
612
- try {
613
- if (!await wait(400)) return;
614
- emitStatus("processing", { display_text: statusToLabel("processing") });
615
- if (!await wait(900)) return;
616
- emitStatus("polling", { display_text: statusToLabel("polling") });
617
- if (!await wait(1200)) return;
618
- const result = {
619
- success: true,
620
- order: {
621
- id: `ord_demo_${Date.now()}`,
622
- order_number: `DEMO-${Math.random().toString(36).slice(2, 8).toUpperCase()}`,
623
- status: "confirmed",
624
- total: "0.00",
625
- currency: "USD"
626
- }
627
- };
628
- emitStatus("success", {
629
- order_id: result.order?.id,
630
- order_number: result.order?.order_number,
631
- display_text: statusToLabel("success")
632
- });
633
- onComplete(result);
634
- } finally {
635
- if (isMountedRef.current && runId === demoRunRef.current) {
636
- setIsSubmitting(false);
637
- }
638
- }
639
- return;
640
- }
641
- if (!elementsRef.current) {
642
- const message = "Checkout is still initializing. Please try again.";
643
- setErrorMessage(message);
644
- fireError({ code: "CHECKOUT_NOT_READY", message });
645
- setIsSubmitting(false);
646
- return;
647
- }
648
- const checkout = elementsRef.current.processCheckout({
649
- cart_id: resolvedCartId,
650
- location_id: locationId ?? client.getLocationId() ?? void 0,
651
- order_type: orderType,
652
- enroll_in_link: enrollInLink,
653
- on_status_change: emitStatus
654
- });
655
- activeCheckoutRef.current = checkout;
656
- try {
657
- const result = await checkout;
658
- if (result.success) {
659
- onComplete(result);
660
- return;
661
- }
662
- const code = result.error?.code || "CHECKOUT_FAILED";
663
- const message = result.error?.message || "Payment failed.";
664
- setErrorMessage(message);
665
- fireError({ code, message });
666
- } finally {
667
- if (isMountedRef.current) {
668
- activeCheckoutRef.current = null;
669
- setIsSubmitting(false);
670
- }
671
- }
672
- });
673
- useEffect(() => {
674
- if (isDemoCheckout || !resolvedBusinessId) {
675
- elementsRef.current = null;
676
- return;
677
- }
678
- const elements = client.elements(resolvedBusinessId, {
679
- appearance: initialAppearanceRef.current,
680
- linkUrl
681
- });
682
- elementsRef.current = elements;
683
- const checkout = elements.create("checkout", {
684
- orderTypes: resolvedOrderTypes,
685
- defaultOrderType: resolvedOrderTypes[0]
686
- });
687
- if (checkoutMountRef.current) {
688
- checkout.mount(checkoutMountRef.current);
689
- }
690
- checkout.on("ready", () => {
691
- if (resolvedCart) {
692
- checkout.setCart(transformToCheckoutCart(resolvedCart));
693
- }
694
- });
695
- checkout.on("order_type_changed", (data) => {
696
- const typed = data;
697
- if (typed.orderType) {
698
- setOrderType(typed.orderType);
699
- }
700
- });
701
- checkout.on("request_submit", () => {
702
- void handleSubmit();
703
- });
704
- return () => {
705
- activeCheckoutRef.current?.abort();
706
- activeCheckoutRef.current = null;
707
- elements.destroy();
708
- elementsRef.current = null;
709
- };
710
- }, [client, resolvedBusinessId, isDemoCheckout]);
711
- useEffect(() => {
712
- if (!resolvedCart || !elementsRef.current) return;
713
- const checkoutElement = elementsRef.current.getElement("checkout");
714
- if (checkoutElement) {
715
- checkoutElement.setCart(transformToCheckoutCart(resolvedCart));
716
- }
717
- }, [resolvedCart]);
718
- const colors = shellColors(isDark ?? false, primaryColor);
719
- if (isInitializing) {
720
- return /* @__PURE__ */ jsx("div", { className, "data-cimplify-checkout": "", children: /* @__PURE__ */ jsx("p", { "data-cimplify-status": "", style: { fontSize: 13, color: colors.textSecondary }, children: "Preparing checkout..." }) });
721
- }
722
- if (!isDemoCheckout && (!resolvedBusinessId || !resolvedCartId)) {
723
- return /* @__PURE__ */ jsx("div", { className, "data-cimplify-checkout": "", children: /* @__PURE__ */ jsx("p", { "data-cimplify-error": "", style: { fontSize: 13, color: colors.error }, children: errorMessage || "Unable to initialize checkout. Please refresh and try again." }) });
724
- }
725
- return /* @__PURE__ */ jsxs("div", { className, "data-cimplify-checkout": "", children: [
726
- isTestMode && !isDemoCheckout && /* @__PURE__ */ jsx(
727
- "p",
728
- {
729
- "data-cimplify-test-mode": "",
730
- style: {
731
- marginBottom: "10px",
732
- fontSize: "12px",
733
- fontWeight: 600,
734
- color: "#92400e"
735
- },
736
- children: "Test mode - no real charges"
737
- }
738
- ),
739
- /* @__PURE__ */ jsx("div", { "data-cimplify-section": "checkout", children: /* @__PURE__ */ jsx("div", { ref: isDemoCheckout ? void 0 : checkoutMountRef }) }),
740
- status && /* @__PURE__ */ jsx("p", { "data-cimplify-status": "", style: { marginTop: SPACE.sm, fontSize: 13, color: colors.textSecondary }, children: statusText || statusToLabel(status) }),
741
- errorMessage && /* @__PURE__ */ jsx("p", { "data-cimplify-error": "", style: { marginTop: SPACE.sm, fontSize: 13, color: colors.error }, children: errorMessage })
742
- ] });
743
- }
744
404
 
745
405
  // src/types/common.ts
746
406
  function money(value) {
@@ -749,6 +409,59 @@ function money(value) {
749
409
  function moneyFromNumber(value) {
750
410
  return value.toFixed(2);
751
411
  }
412
+ var SUPPORTED_CURRENCY_CODES = /* @__PURE__ */ new Set([
413
+ "USD",
414
+ "EUR",
415
+ "GBP",
416
+ "JPY",
417
+ "CNY",
418
+ "CHF",
419
+ "CAD",
420
+ "AUD",
421
+ "GHS",
422
+ "NGN",
423
+ "KES",
424
+ "ZAR",
425
+ "XOF",
426
+ "XAF",
427
+ "EGP",
428
+ "TZS",
429
+ "UGX",
430
+ "RWF",
431
+ "ETB",
432
+ "ZMW",
433
+ "BWP",
434
+ "MUR",
435
+ "NAD",
436
+ "MWK",
437
+ "AOA",
438
+ "CDF",
439
+ "GMD",
440
+ "GNF",
441
+ "LRD",
442
+ "SLL",
443
+ "MZN",
444
+ "BIF",
445
+ "INR",
446
+ "BRL",
447
+ "MXN",
448
+ "KRW",
449
+ "TRY",
450
+ "THB",
451
+ "MYR",
452
+ "PHP",
453
+ "IDR",
454
+ "VND",
455
+ "SGD",
456
+ "HKD",
457
+ "TWD",
458
+ "AED",
459
+ "SAR",
460
+ "ILS"
461
+ ]);
462
+ function isSupportedCurrency(code) {
463
+ return SUPPORTED_CURRENCY_CODES.has(code);
464
+ }
752
465
  function currencyCode(value) {
753
466
  return value;
754
467
  }
@@ -1354,6 +1067,97 @@ var MOBILE_MONEY_PROVIDER = {
1354
1067
  };
1355
1068
 
1356
1069
  // src/utils/price.ts
1070
+ var CURRENCY_SYMBOLS = {
1071
+ // Major world currencies
1072
+ USD: "$",
1073
+ EUR: "\u20AC",
1074
+ GBP: "\xA3",
1075
+ JPY: "\xA5",
1076
+ CNY: "\xA5",
1077
+ CHF: "CHF",
1078
+ CAD: "C$",
1079
+ AUD: "A$",
1080
+ NZD: "NZ$",
1081
+ HKD: "HK$",
1082
+ SGD: "S$",
1083
+ INR: "\u20B9",
1084
+ BRL: "R$",
1085
+ MXN: "MX$",
1086
+ KRW: "\u20A9",
1087
+ RUB: "\u20BD",
1088
+ TRY: "\u20BA",
1089
+ THB: "\u0E3F",
1090
+ PLN: "z\u0142",
1091
+ SEK: "kr",
1092
+ NOK: "kr",
1093
+ DKK: "kr",
1094
+ CZK: "K\u010D",
1095
+ HUF: "Ft",
1096
+ ILS: "\u20AA",
1097
+ AED: "\u062F.\u0625",
1098
+ SAR: "\uFDFC",
1099
+ MYR: "RM",
1100
+ PHP: "\u20B1",
1101
+ IDR: "Rp",
1102
+ VND: "\u20AB",
1103
+ TWD: "NT$",
1104
+ // African currencies
1105
+ GHS: "GH\u20B5",
1106
+ NGN: "\u20A6",
1107
+ KES: "KSh",
1108
+ ZAR: "R",
1109
+ XOF: "CFA",
1110
+ XAF: "FCFA",
1111
+ EGP: "E\xA3",
1112
+ MAD: "MAD",
1113
+ TZS: "TSh",
1114
+ UGX: "USh",
1115
+ RWF: "FRw",
1116
+ ETB: "Br",
1117
+ ZMW: "ZK",
1118
+ BWP: "P",
1119
+ MUR: "\u20A8",
1120
+ SCR: "\u20A8",
1121
+ NAD: "N$",
1122
+ SZL: "E",
1123
+ LSL: "L",
1124
+ MWK: "MK",
1125
+ AOA: "Kz",
1126
+ CDF: "FC",
1127
+ GMD: "D",
1128
+ GNF: "FG",
1129
+ LRD: "L$",
1130
+ SLL: "Le",
1131
+ MZN: "MT",
1132
+ SDG: "SDG",
1133
+ SSP: "SSP",
1134
+ SOS: "Sh.So.",
1135
+ DJF: "Fdj",
1136
+ ERN: "Nfk",
1137
+ CVE: "$",
1138
+ STN: "Db",
1139
+ KMF: "CF",
1140
+ BIF: "FBu"
1141
+ };
1142
+ function getCurrencySymbol(currencyCode2) {
1143
+ return CURRENCY_SYMBOLS[currencyCode2.toUpperCase()] || currencyCode2;
1144
+ }
1145
+ function formatPrice(amount, currency = "GHS", locale = "en-US") {
1146
+ const numAmount = typeof amount === "string" ? parseFloat(amount) : amount;
1147
+ if (isNaN(numAmount)) {
1148
+ return `${getCurrencySymbol(currency)}0.00`;
1149
+ }
1150
+ try {
1151
+ return new Intl.NumberFormat(locale, {
1152
+ style: "currency",
1153
+ currency: currency.toUpperCase(),
1154
+ minimumFractionDigits: 2,
1155
+ maximumFractionDigits: 2
1156
+ }).format(numAmount);
1157
+ } catch {
1158
+ return `${getCurrencySymbol(currency)}${numAmount.toFixed(2)}`;
1159
+ }
1160
+ }
1357
1161
  function parsePrice(value) {
1358
1162
  if (value === void 0 || value === null) {
1359
1163
  return 0;
@@ -4314,6 +4118,8 @@ function createCimplifyClient(config = {}) {
4314
4118
  return new CimplifyClient(config);
4315
4119
  }
4316
4120
  var LOCATION_STORAGE_KEY = "cimplify_location_id";
4121
+ var DISPLAY_CURRENCY_STORAGE_KEY = "cimplify_display_currency";
4122
+ var FX_REFRESH_INTERVAL = 12e4;
4317
4123
  var DEFAULT_CURRENCY = "USD";
4318
4124
  var DEFAULT_COUNTRY = "US";
4319
4125
  function createDefaultClient() {
@@ -4342,6 +4148,27 @@ function setStoredLocationId(locationId) {
4342
4148
  }
4343
4149
  window.localStorage.setItem(LOCATION_STORAGE_KEY, locationId);
4344
4150
  }
4151
+ function getStoredDisplayCurrency() {
4152
+ if (typeof window === "undefined" || !window.localStorage) {
4153
+ return null;
4154
+ }
4155
+ const value = window.localStorage.getItem(DISPLAY_CURRENCY_STORAGE_KEY);
4156
+ if (!value) {
4157
+ return null;
4158
+ }
4159
+ const normalized = value.trim().toUpperCase();
4160
+ return normalized.length > 0 ? normalized : null;
4161
+ }
4162
+ function setStoredDisplayCurrency(currency) {
4163
+ if (typeof window === "undefined" || !window.localStorage) {
4164
+ return;
4165
+ }
4166
+ if (!currency) {
4167
+ window.localStorage.removeItem(DISPLAY_CURRENCY_STORAGE_KEY);
4168
+ return;
4169
+ }
4170
+ window.localStorage.setItem(DISPLAY_CURRENCY_STORAGE_KEY, currency.toUpperCase());
4171
+ }
4345
4172
  function resolveInitialLocation(locations) {
4346
4173
  if (locations.length === 0) {
4347
4174
  return null;
@@ -4371,6 +4198,60 @@ function CimplifyProvider({
4371
4198
  onLocationChangeRef.current = onLocationChange;
4372
4199
  }, [onLocationChange]);
4373
4200
  const isDemoMode = resolvedClient.getPublicKey().trim().length === 0;
4201
+ const baseCurrency = business?.default_currency || DEFAULT_CURRENCY;
4202
+ const [displayCurrencyOverride, setDisplayCurrencyOverride] = useState(
4203
+ () => getStoredDisplayCurrency()
4204
+ );
4205
+ const [fxRate, setFxRate] = useState(null);
4206
+ const displayCurrency = displayCurrencyOverride && displayCurrencyOverride !== baseCurrency ? displayCurrencyOverride : baseCurrency;
4207
+ const setDisplayCurrency = useCallback(
4208
+ (currency) => {
4209
+ const normalized = currency?.trim().toUpperCase() || null;
4210
+ if (normalized && !isSupportedCurrency(normalized)) {
4211
+ return;
4212
+ }
4213
+ setDisplayCurrencyOverride(normalized);
4214
+ setStoredDisplayCurrency(normalized);
4215
+ if (!normalized || normalized === baseCurrency) {
4216
+ setFxRate(null);
4217
+ }
4218
+ },
4219
+ [baseCurrency]
4220
+ );
4221
+ useEffect(() => {
4222
+ if (displayCurrency === baseCurrency || isDemoMode) {
4223
+ setFxRate(null);
4224
+ return;
4225
+ }
4226
+ let cancelled = false;
4227
+ async function fetchRate() {
4228
+ const result = await resolvedClient.fx.getRate(
4229
+ baseCurrency,
4230
+ displayCurrency
4231
+ );
4232
+ if (cancelled) return;
4233
+ if (result.ok) {
4234
+ setFxRate(result.value.rate);
4235
+ } else {
4236
+ setFxRate(null);
4237
+ }
4238
+ }
4239
+ void fetchRate();
4240
+ const intervalId = setInterval(() => void fetchRate(), FX_REFRESH_INTERVAL);
4241
+ return () => {
4242
+ cancelled = true;
4243
+ clearInterval(intervalId);
4244
+ };
4245
+ }, [resolvedClient, baseCurrency, displayCurrency, isDemoMode]);
4246
+ const convertPrice = useCallback(
4247
+ (amount) => {
4248
+ const num = typeof amount === "string" ? parseFloat(amount) : amount;
4249
+ if (isNaN(num)) return 0;
4250
+ if (!fxRate || displayCurrency === baseCurrency) return num;
4251
+ return Math.round(num * fxRate * 100) / 100;
4252
+ },
4253
+ [fxRate, displayCurrency, baseCurrency]
4254
+ );
4374
4255
  const setCurrentLocation = useCallback(
4375
4256
  (location) => {
4376
4257
  setCurrentLocationState(location);
@@ -4386,89 +4267,463 @@ function CimplifyProvider({
4386
4267
  setIsReady(false);
4387
4268
  if (isDemoMode) {
4388
4269
  if (!cancelled) {
4389
- setBusiness(null);
4390
- setLocations([]);
4391
- setCurrentLocationState(null);
4392
- resolvedClient.setLocationId(null);
4393
- setStoredLocationId(null);
4394
- setIsReady(true);
4270
+ setBusiness(null);
4271
+ setLocations([]);
4272
+ setCurrentLocationState(null);
4273
+ resolvedClient.setLocationId(null);
4274
+ setStoredLocationId(null);
4275
+ setIsReady(true);
4276
+ }
4277
+ return;
4278
+ }
4279
+ const [businessResult, locationsResult] = await Promise.all([
4280
+ resolvedClient.business.getInfo(),
4281
+ resolvedClient.business.getLocations()
4282
+ ]);
4283
+ if (cancelled) {
4284
+ return;
4285
+ }
4286
+ const nextBusiness = businessResult.ok ? businessResult.value : null;
4287
+ const nextLocations = locationsResult.ok && Array.isArray(locationsResult.value) ? locationsResult.value : [];
4288
+ const initialLocation = resolveInitialLocation(nextLocations);
4289
+ setBusiness(nextBusiness);
4290
+ if (nextBusiness?.id) {
4291
+ resolvedClient.setBusinessId(nextBusiness.id);
4292
+ }
4293
+ setLocations(nextLocations);
4294
+ if (initialLocation) {
4295
+ setCurrentLocationState(initialLocation);
4296
+ resolvedClient.setLocationId(initialLocation.id);
4297
+ setStoredLocationId(initialLocation.id);
4298
+ } else {
4299
+ setCurrentLocationState(null);
4300
+ resolvedClient.setLocationId(null);
4301
+ setStoredLocationId(null);
4302
+ }
4303
+ setIsReady(true);
4304
+ }
4305
+ bootstrap().catch(() => {
4306
+ if (cancelled) {
4307
+ return;
4308
+ }
4309
+ setBusiness(null);
4310
+ setLocations([]);
4311
+ setCurrentLocationState(null);
4312
+ resolvedClient.setLocationId(null);
4313
+ setStoredLocationId(null);
4314
+ setIsReady(true);
4315
+ });
4316
+ return () => {
4317
+ cancelled = true;
4318
+ };
4319
+ }, [resolvedClient, isDemoMode]);
4320
+ const contextValue = useMemo(
4321
+ () => ({
4322
+ client: resolvedClient,
4323
+ business,
4324
+ currency: baseCurrency,
4325
+ country: business?.country_code || DEFAULT_COUNTRY,
4326
+ locations,
4327
+ currentLocation,
4328
+ setCurrentLocation,
4329
+ isReady,
4330
+ isDemoMode,
4331
+ baseCurrency,
4332
+ displayCurrency,
4333
+ setDisplayCurrency,
4334
+ convertPrice,
4335
+ fxRate
4336
+ }),
4337
+ [
4338
+ resolvedClient,
4339
+ business,
4340
+ baseCurrency,
4341
+ locations,
4342
+ currentLocation,
4343
+ setCurrentLocation,
4344
+ isReady,
4345
+ isDemoMode,
4346
+ displayCurrency,
4347
+ setDisplayCurrency,
4348
+ convertPrice,
4349
+ fxRate
4350
+ ]
4351
+ );
4352
+ return /* @__PURE__ */ jsx(CimplifyContext.Provider, { value: contextValue, children });
4353
+ }
4354
+ function useCimplify() {
4355
+ const context = useContext(CimplifyContext);
4356
+ if (!context) {
4357
+ throw new Error("useCimplify must be used within CimplifyProvider");
4358
+ }
4359
+ return context;
4360
+ }
4361
+ function useOptionalCimplify() {
4362
+ return useContext(CimplifyContext);
4363
+ }
4364
+ var SPACE = { sm: 8};
4365
+ function shellColors(isDark, primaryColor) {
4366
+ return {
4367
+ text: isDark ? "#f4f4f5" : "#1a1a1a",
4368
+ textSecondary: isDark ? "#a1a1aa" : "#52525b",
4369
+ textMuted: isDark ? "#71717a" : "#a1a1aa",
4370
+ border: isDark ? "#27272a" : "#e4e4e7",
4371
+ surface: isDark ? "#18181b" : "#fafafa",
4372
+ error: "#dc2626",
4373
+ primary: primaryColor
4374
+ };
4375
+ }
4376
+ function statusToLabel(status) {
4377
+ if (!status) {
4378
+ return "";
4379
+ }
4380
+ if (status === "preparing") {
4381
+ return "Preparing checkout";
4382
+ }
4383
+ if (status === "recovering") {
4384
+ return "Resuming payment";
4385
+ }
4386
+ if (status === "processing") {
4387
+ return "Processing payment";
4388
+ }
4389
+ if (status === "awaiting_authorization") {
4390
+ return "Waiting for authorization";
4391
+ }
4392
+ if (status === "polling") {
4393
+ return "Confirming payment";
4394
+ }
4395
+ if (status === "finalizing") {
4396
+ return "Finalizing order";
4397
+ }
4398
+ if (status === "success") {
4399
+ return "Payment complete";
4400
+ }
4401
+ return "Payment failed";
4402
+ }
4403
+ function CimplifyCheckout({
4404
+ client,
4405
+ businessId,
4406
+ cartId,
4407
+ locationId,
4408
+ linkUrl,
4409
+ orderTypes,
4410
+ enrollInLink = true,
4411
+ onComplete,
4412
+ onError,
4413
+ onStatusChange,
4414
+ appearance,
4415
+ demoMode,
4416
+ className
4417
+ }) {
4418
+ const resolvedOrderTypes = useMemo(
4419
+ () => orderTypes && orderTypes.length > 0 ? orderTypes : ["pickup", "delivery"],
4420
+ [orderTypes]
4421
+ );
4422
+ const [orderType, setOrderType] = useState(resolvedOrderTypes[0] || "pickup");
4423
+ const [status, setStatus] = useState(null);
4424
+ const [statusText, setStatusText] = useState("");
4425
+ const [isSubmitting, setIsSubmitting] = useState(false);
4426
+ const [isInitializing, setIsInitializing] = useState(false);
4427
+ const [errorMessage, setErrorMessage] = useState(null);
4428
+ const [resolvedBusinessId, setResolvedBusinessId] = useState(businessId ?? null);
4429
+ const [resolvedCartId, setResolvedCartId] = useState(cartId ?? null);
4430
+ const [resolvedCart, setResolvedCart] = useState(null);
4431
+ const checkoutMountRef = useRef(null);
4432
+ const elementsRef = useRef(null);
4433
+ const activeCheckoutRef = useRef(null);
4434
+ const initialAppearanceRef = useRef(appearance);
4435
+ const hasWarnedInlineAppearanceRef = useRef(false);
4436
+ const isMountedRef = useRef(true);
4437
+ const demoRunRef = useRef(0);
4438
+ const isDemoCheckout = demoMode ?? client.getPublicKey().trim().length === 0;
4439
+ const isTestMode = client.isTestMode();
4440
+ const cimplifyCtx = useOptionalCimplify();
4441
+ const fxOptions = useMemo(() => {
4442
+ if (!cimplifyCtx?.fxRate) return void 0;
4443
+ if (cimplifyCtx.displayCurrency === cimplifyCtx.baseCurrency) return void 0;
4444
+ return {
4445
+ displayCurrency: cimplifyCtx.displayCurrency,
4446
+ convertPrice: cimplifyCtx.convertPrice
4447
+ };
4448
+ }, [cimplifyCtx?.fxRate, cimplifyCtx?.displayCurrency, cimplifyCtx?.baseCurrency, cimplifyCtx?.convertPrice]);
4449
+ const fxOptionsRef = useRef(fxOptions);
4450
+ fxOptionsRef.current = fxOptions;
4451
+ const resolvedCartRef = useRef(resolvedCart);
4452
+ resolvedCartRef.current = resolvedCart;
4453
+ const primaryColor = appearance?.variables?.primaryColor || "#0a2540";
4454
+ const isDark = appearance?.theme === "dark";
4455
+ const emitStatus = React3.useEffectEvent(
4456
+ (nextStatus, context = {}) => {
4457
+ setStatus(nextStatus);
4458
+ setStatusText(context.display_text || "");
4459
+ onStatusChange?.(nextStatus, context);
4460
+ }
4461
+ );
4462
+ const fireError = React3.useEffectEvent(
4463
+ (error) => {
4464
+ onError?.(error);
4465
+ }
4466
+ );
4467
+ useEffect(() => {
4468
+ if (!resolvedOrderTypes.includes(orderType)) {
4469
+ setOrderType(resolvedOrderTypes[0] || "pickup");
4470
+ }
4471
+ }, [resolvedOrderTypes, orderType]);
4472
+ useEffect(() => {
4473
+ if (appearance && appearance !== initialAppearanceRef.current && !hasWarnedInlineAppearanceRef.current) {
4474
+ hasWarnedInlineAppearanceRef.current = true;
4475
+ console.warn(
4476
+ "[Cimplify] `appearance` prop reference changed after mount. Elements keep the initial appearance to avoid iframe remount. Memoize appearance with useMemo() to remove this warning."
4477
+ );
4478
+ }
4479
+ }, [appearance]);
4480
+ useEffect(() => {
4481
+ let cancelled = false;
4482
+ async function bootstrap() {
4483
+ if (isDemoCheckout) {
4484
+ if (!cancelled) {
4485
+ setResolvedBusinessId(businessId ?? null);
4486
+ setResolvedCartId(cartId ?? "cart_demo");
4487
+ setIsInitializing(false);
4488
+ setErrorMessage(null);
4489
+ }
4490
+ return;
4491
+ }
4492
+ const needsBusinessResolve = !businessId;
4493
+ const needsCartResolve = !cartId;
4494
+ if (!needsBusinessResolve && !needsCartResolve) {
4495
+ if (!cancelled) {
4496
+ setResolvedBusinessId(businessId || null);
4497
+ setResolvedCartId(cartId || null);
4498
+ setIsInitializing(false);
4499
+ setErrorMessage(null);
4500
+ }
4501
+ client.cart.get().then((cartResult) => {
4502
+ if (!cancelled && cartResult.ok && cartResult.value) {
4503
+ setResolvedCart(cartResult.value);
4504
+ }
4505
+ }).catch(() => {
4506
+ });
4507
+ return;
4508
+ }
4509
+ if (!cancelled) {
4510
+ setIsInitializing(true);
4511
+ setErrorMessage(null);
4512
+ }
4513
+ let nextBusinessId = businessId ?? null;
4514
+ if (!nextBusinessId) {
4515
+ try {
4516
+ nextBusinessId = await client.resolveBusinessId();
4517
+ } catch {
4518
+ if (!cancelled) {
4519
+ const message = "Unable to initialize checkout business context.";
4520
+ setResolvedBusinessId(null);
4521
+ setResolvedCartId(null);
4522
+ setErrorMessage(message);
4523
+ setIsInitializing(false);
4524
+ fireError({ code: "BUSINESS_ID_REQUIRED", message });
4525
+ }
4526
+ return;
4527
+ }
4528
+ }
4529
+ let nextCartId = cartId ?? null;
4530
+ if (!nextCartId) {
4531
+ const cartResult = await client.cart.get();
4532
+ if (!cartResult.ok || !cartResult.value?.id || cartResult.value.items.length === 0) {
4533
+ if (!cancelled) {
4534
+ const message = "Your cart is empty. Add items before checkout.";
4535
+ setResolvedBusinessId(nextBusinessId);
4536
+ setResolvedCartId(null);
4537
+ setErrorMessage(message);
4538
+ setIsInitializing(false);
4539
+ fireError({ code: "CART_EMPTY", message });
4540
+ }
4541
+ return;
4542
+ }
4543
+ nextCartId = cartResult.value.id;
4544
+ if (!cancelled) {
4545
+ setResolvedCart(cartResult.value);
4395
4546
  }
4396
- return;
4397
4547
  }
4398
- const [businessResult, locationsResult] = await Promise.all([
4399
- resolvedClient.business.getInfo(),
4400
- resolvedClient.business.getLocations()
4401
- ]);
4402
- if (cancelled) {
4403
- return;
4548
+ if (!cancelled) {
4549
+ setResolvedBusinessId(nextBusinessId);
4550
+ setResolvedCartId(nextCartId);
4551
+ setIsInitializing(false);
4552
+ setErrorMessage(null);
4404
4553
  }
4405
- const nextBusiness = businessResult.ok ? businessResult.value : null;
4406
- const nextLocations = locationsResult.ok && Array.isArray(locationsResult.value) ? locationsResult.value : [];
4407
- const initialLocation = resolveInitialLocation(nextLocations);
4408
- setBusiness(nextBusiness);
4409
- if (nextBusiness?.id) {
4410
- resolvedClient.setBusinessId(nextBusiness.id);
4554
+ }
4555
+ void bootstrap();
4556
+ return () => {
4557
+ cancelled = true;
4558
+ };
4559
+ }, [businessId, cartId, client, isDemoCheckout]);
4560
+ useEffect(() => {
4561
+ return () => {
4562
+ isMountedRef.current = false;
4563
+ demoRunRef.current += 1;
4564
+ activeCheckoutRef.current?.abort();
4565
+ activeCheckoutRef.current = null;
4566
+ };
4567
+ }, []);
4568
+ const handleSubmit = React3.useEffectEvent(async () => {
4569
+ if (isSubmitting || isInitializing || !resolvedCartId) {
4570
+ if (!resolvedCartId && !isInitializing) {
4571
+ const message = "Your cart is empty. Add items before checkout.";
4572
+ setErrorMessage(message);
4573
+ fireError({ code: "CART_EMPTY", message });
4411
4574
  }
4412
- setLocations(nextLocations);
4413
- if (initialLocation) {
4414
- setCurrentLocationState(initialLocation);
4415
- resolvedClient.setLocationId(initialLocation.id);
4416
- setStoredLocationId(initialLocation.id);
4417
- } else {
4418
- setCurrentLocationState(null);
4419
- resolvedClient.setLocationId(null);
4420
- setStoredLocationId(null);
4575
+ return;
4576
+ }
4577
+ setErrorMessage(null);
4578
+ setIsSubmitting(true);
4579
+ emitStatus("preparing", { display_text: statusToLabel("preparing") });
4580
+ if (isDemoCheckout) {
4581
+ const runId = demoRunRef.current + 1;
4582
+ demoRunRef.current = runId;
4583
+ const wait = async (ms) => {
4584
+ await new Promise((resolve) => setTimeout(resolve, ms));
4585
+ return isMountedRef.current && runId === demoRunRef.current;
4586
+ };
4587
+ try {
4588
+ if (!await wait(400)) return;
4589
+ emitStatus("processing", { display_text: statusToLabel("processing") });
4590
+ if (!await wait(900)) return;
4591
+ emitStatus("polling", { display_text: statusToLabel("polling") });
4592
+ if (!await wait(1200)) return;
4593
+ const result = {
4594
+ success: true,
4595
+ order: {
4596
+ id: `ord_demo_${Date.now()}`,
4597
+ order_number: `DEMO-${Math.random().toString(36).slice(2, 8).toUpperCase()}`,
4598
+ status: "confirmed",
4599
+ total: "0.00",
4600
+ currency: "USD"
4601
+ }
4602
+ };
4603
+ emitStatus("success", {
4604
+ order_id: result.order?.id,
4605
+ order_number: result.order?.order_number,
4606
+ display_text: statusToLabel("success")
4607
+ });
4608
+ onComplete(result);
4609
+ } finally {
4610
+ if (isMountedRef.current && runId === demoRunRef.current) {
4611
+ setIsSubmitting(false);
4612
+ }
4421
4613
  }
4422
- setIsReady(true);
4614
+ return;
4423
4615
  }
4424
- bootstrap().catch(() => {
4425
- if (cancelled) {
4616
+ if (!elementsRef.current) {
4617
+ const message = "Checkout is still initializing. Please try again.";
4618
+ setErrorMessage(message);
4619
+ fireError({ code: "CHECKOUT_NOT_READY", message });
4620
+ setIsSubmitting(false);
4621
+ return;
4622
+ }
4623
+ const checkout = elementsRef.current.processCheckout({
4624
+ cart_id: resolvedCartId,
4625
+ location_id: locationId ?? client.getLocationId() ?? void 0,
4626
+ order_type: orderType,
4627
+ enroll_in_link: enrollInLink,
4628
+ on_status_change: emitStatus,
4629
+ pay_currency: fxOptions?.displayCurrency
4630
+ });
4631
+ activeCheckoutRef.current = checkout;
4632
+ try {
4633
+ const result = await checkout;
4634
+ if (result.success) {
4635
+ onComplete(result);
4426
4636
  return;
4427
4637
  }
4428
- setBusiness(null);
4429
- setLocations([]);
4430
- setCurrentLocationState(null);
4431
- resolvedClient.setLocationId(null);
4432
- setStoredLocationId(null);
4433
- setIsReady(true);
4638
+ const code = result.error?.code || "CHECKOUT_FAILED";
4639
+ const message = result.error?.message || "Payment failed.";
4640
+ setErrorMessage(message);
4641
+ fireError({ code, message });
4642
+ } finally {
4643
+ if (isMountedRef.current) {
4644
+ activeCheckoutRef.current = null;
4645
+ setIsSubmitting(false);
4646
+ }
4647
+ }
4648
+ });
4649
+ useEffect(() => {
4650
+ if (isDemoCheckout || !resolvedBusinessId) {
4651
+ elementsRef.current = null;
4652
+ return;
4653
+ }
4654
+ const elements = client.elements(resolvedBusinessId, {
4655
+ appearance: initialAppearanceRef.current,
4656
+ linkUrl
4657
+ });
4658
+ elementsRef.current = elements;
4659
+ const checkout = elements.create("checkout", {
4660
+ orderTypes: resolvedOrderTypes,
4661
+ defaultOrderType: resolvedOrderTypes[0]
4662
+ });
4663
+ if (checkoutMountRef.current) {
4664
+ checkout.mount(checkoutMountRef.current);
4665
+ }
4666
+ checkout.on("ready", () => {
4667
+ const cart = resolvedCartRef.current;
4668
+ if (cart) {
4669
+ checkout.setCart(transformToCheckoutCart(cart, fxOptionsRef.current));
4670
+ }
4671
+ });
4672
+ checkout.on("order_type_changed", (data) => {
4673
+ const typed = data;
4674
+ if (typed.orderType) {
4675
+ setOrderType(typed.orderType);
4676
+ }
4677
+ });
4678
+ checkout.on("request_submit", () => {
4679
+ void handleSubmit();
4434
4680
  });
4435
4681
  return () => {
4436
- cancelled = true;
4682
+ activeCheckoutRef.current?.abort();
4683
+ activeCheckoutRef.current = null;
4684
+ elements.destroy();
4685
+ elementsRef.current = null;
4437
4686
  };
4438
- }, [resolvedClient, isDemoMode]);
4439
- const contextValue = useMemo(
4440
- () => ({
4441
- client: resolvedClient,
4442
- business,
4443
- currency: business?.default_currency || DEFAULT_CURRENCY,
4444
- country: business?.country_code || DEFAULT_COUNTRY,
4445
- locations,
4446
- currentLocation,
4447
- setCurrentLocation,
4448
- isReady,
4449
- isDemoMode
4450
- }),
4451
- [
4452
- resolvedClient,
4453
- business,
4454
- locations,
4455
- currentLocation,
4456
- setCurrentLocation,
4457
- isReady,
4458
- isDemoMode
4459
- ]
4460
- );
4461
- return /* @__PURE__ */ jsx(CimplifyContext.Provider, { value: contextValue, children });
4462
- }
4463
- function useCimplify() {
4464
- const context = useContext(CimplifyContext);
4465
- if (!context) {
4466
- throw new Error("useCimplify must be used within CimplifyProvider");
4687
+ }, [client, resolvedBusinessId, isDemoCheckout]);
4688
+ useEffect(() => {
4689
+ if (!resolvedCart || !elementsRef.current) return;
4690
+ const checkoutElement = elementsRef.current.getElement("checkout");
4691
+ if (checkoutElement) {
4692
+ checkoutElement.setCart(transformToCheckoutCart(resolvedCart, fxOptions));
4693
+ }
4694
+ }, [resolvedCart, fxOptions]);
4695
+ const colors = shellColors(isDark ?? false, primaryColor);
4696
+ if (isInitializing) {
4697
+ return /* @__PURE__ */ jsx("div", { className, "data-cimplify-checkout": "", children: /* @__PURE__ */ jsx("p", { "data-cimplify-status": "", style: { fontSize: 13, color: colors.textSecondary }, children: "Preparing checkout..." }) });
4467
4698
  }
4468
- return context;
4699
+ if (!isDemoCheckout && (!resolvedBusinessId || !resolvedCartId)) {
4700
+ return /* @__PURE__ */ jsx("div", { className, "data-cimplify-checkout": "", children: /* @__PURE__ */ jsx("p", { "data-cimplify-error": "", style: { fontSize: 13, color: colors.error }, children: errorMessage || "Unable to initialize checkout. Please refresh and try again." }) });
4701
+ }
4702
+ return /* @__PURE__ */ jsxs("div", { className, "data-cimplify-checkout": "", children: [
4703
+ isTestMode && !isDemoCheckout && /* @__PURE__ */ jsx(
4704
+ "p",
4705
+ {
4706
+ "data-cimplify-test-mode": "",
4707
+ style: {
4708
+ marginBottom: "10px",
4709
+ fontSize: "12px",
4710
+ fontWeight: 600,
4711
+ color: "#92400e"
4712
+ },
4713
+ children: "Test mode - no real charges"
4714
+ }
4715
+ ),
4716
+ /* @__PURE__ */ jsx("div", { "data-cimplify-section": "checkout", children: /* @__PURE__ */ jsx("div", { ref: isDemoCheckout ? void 0 : checkoutMountRef }) }),
4717
+ status && /* @__PURE__ */ jsx("p", { "data-cimplify-status": "", style: { marginTop: SPACE.sm, fontSize: 13, color: colors.textSecondary }, children: statusText || statusToLabel(status) }),
4718
+ errorMessage && /* @__PURE__ */ jsx("p", { "data-cimplify-error": "", style: { marginTop: SPACE.sm, fontSize: 13, color: colors.error }, children: errorMessage })
4719
+ ] });
4469
4720
  }
4470
- function useOptionalCimplify() {
4471
- return useContext(CimplifyContext);
4721
+ function Price({ amount, className, prefix }) {
4722
+ const { displayCurrency, convertPrice } = useCimplify();
4723
+ return /* @__PURE__ */ jsxs("span", { className, children: [
4724
+ prefix,
4725
+ formatPrice(convertPrice(amount), displayCurrency)
4726
+ ] });
4472
4727
  }
4473
4728
  var productsCache = /* @__PURE__ */ new Map();
4474
4729
  var productsInflight = /* @__PURE__ */ new Map();
@@ -6499,4 +6754,4 @@ function useCheckout() {
6499
6754
  return { submit, process, isLoading };
6500
6755
  }
6501
6756
 
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 };
6757
+ 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 };