@betterstore/react 0.2.14 → 0.2.16

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/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # @betterstore/sdk
2
2
 
3
+ ## 0.2.16
4
+
5
+ ### Patch Changes
6
+
7
+ - better currency formatting
8
+
9
+ ## 0.2.15
10
+
11
+ ### Patch Changes
12
+
13
+ - fonts config added to stripe
14
+
3
15
  ## 0.2.14
4
16
 
5
17
  ### Patch Changes
@@ -1,4 +1,5 @@
1
1
  import { CheckoutSession } from "@betterstore/sdk";
2
+ import { StripeElementsOptions } from "@stripe/stripe-js";
2
3
  import React from "react";
3
4
  import { AppearanceConfig } from "./appearance";
4
5
  interface CheckoutFormProps {
@@ -10,6 +11,7 @@ interface CheckoutFormProps {
10
11
  customer?: CheckoutSession["customer"];
11
12
  currency: string;
12
13
  checkoutAppearance?: AppearanceConfig;
14
+ fonts?: StripeElementsOptions["fonts"];
13
15
  }
14
- export default function CheckoutForm({ checkoutId, onSuccess, onError, cancelUrl, clientSecret, customer, currency, checkoutAppearance, }: CheckoutFormProps): React.JSX.Element;
16
+ export default function CheckoutForm({ checkoutId, onSuccess, onError, cancelUrl, clientSecret, customer, currency, checkoutAppearance, fonts, }: CheckoutFormProps): React.JSX.Element;
15
17
  export {};
@@ -1,4 +1,5 @@
1
1
  import { Locale } from "@/i18n";
2
+ import { StripeElementsOptions } from "@stripe/stripe-js";
2
3
  import React from "react";
3
4
  import { AppearanceConfig } from "./appearance";
4
5
  interface CheckoutEmbedProps {
@@ -8,6 +9,7 @@ interface CheckoutEmbedProps {
8
9
  cancelUrl: string;
9
10
  successUrl: string;
10
11
  appearance?: AppearanceConfig;
12
+ fonts?: StripeElementsOptions["fonts"];
11
13
  locale?: Locale;
12
14
  };
13
15
  }
@@ -1,3 +1,4 @@
1
+ import { StripeElementsOptions } from "@stripe/stripe-js";
1
2
  import React from "react";
2
3
  import { AppearanceConfig } from "../../appearance";
3
4
  interface PaymentFormProps {
@@ -11,6 +12,7 @@ interface PaymentFormProps {
11
12
  shippingProvider: string;
12
13
  shippingPrice: string;
13
14
  checkoutAppearance?: AppearanceConfig;
15
+ fonts?: StripeElementsOptions["fonts"];
14
16
  }
15
- export default function PaymentForm({ paymentSecret, onSuccess, onError, onBack, onDoubleBack, contactEmail, shippingAddress, shippingProvider, shippingPrice, checkoutAppearance, }: PaymentFormProps): React.JSX.Element;
17
+ export default function PaymentForm({ paymentSecret, onSuccess, onError, onBack, onDoubleBack, contactEmail, shippingAddress, shippingProvider, shippingPrice, checkoutAppearance, fonts, }: PaymentFormProps): React.JSX.Element;
16
18
  export {};
@@ -1,8 +1,9 @@
1
- import { Appearance } from "@stripe/stripe-js";
1
+ import { Appearance, StripeElementsOptions } from "@stripe/stripe-js";
2
2
  import React from "react";
3
- declare function PaymentElement({ paymentSecret, checkoutAppearance, onSuccess, onError, children, }: {
3
+ declare function PaymentElement({ paymentSecret, checkoutAppearance, fonts, onSuccess, onError, children, }: {
4
4
  paymentSecret: string;
5
5
  checkoutAppearance?: Appearance;
6
+ fonts?: StripeElementsOptions["fonts"];
6
7
  onSuccess?: () => void;
7
8
  onError?: () => void;
8
9
  children: React.ReactNode;
package/dist/index.cjs.js CHANGED
@@ -20772,11 +20772,44 @@ var Client = class {
20772
20772
  }
20773
20773
  };
20774
20774
  var client_default = Client;
20775
+ var Helpers = class {
20776
+ constructor(proxy) {
20777
+ this.proxy = proxy;
20778
+ }
20779
+ formatPrice(priceInCents, currency, exchangeRate) {
20780
+ const amount = priceInCents / 100 * (exchangeRate != null ? exchangeRate : 1);
20781
+ const isWhole = amount % 1 === 0;
20782
+ const formattedPrice = new Intl.NumberFormat(void 0, {
20783
+ style: "currency",
20784
+ currency,
20785
+ minimumFractionDigits: isWhole ? 0 : 2,
20786
+ maximumFractionDigits: isWhole ? 0 : 2
20787
+ }).format(amount);
20788
+ return formattedPrice;
20789
+ }
20790
+ getExchangeRate(baseCurrency, targetCurrency) {
20791
+ return __async(this, null, function* () {
20792
+ const { data } = yield axios.get(
20793
+ `https://api.exchangerate-api.com/v4/latest/${baseCurrency}`
20794
+ );
20795
+ const rate = data.rates[targetCurrency];
20796
+ if (!rate) {
20797
+ throw new Error("Could not get exchange rate for target currency");
20798
+ }
20799
+ return rate;
20800
+ });
20801
+ }
20802
+ };
20803
+ var helpers_default = Helpers;
20775
20804
  function createStoreClient(config) {
20776
- return new client_default(config.proxy);
20805
+ return new client_default(config == null ? void 0 : config.proxy);
20806
+ }
20807
+ function createStoreHelpers(config) {
20808
+ return new helpers_default(void 0 );
20777
20809
  }
20778
20810
 
20779
20811
  const storeClient = createStoreClient({ proxy: "/api/betterstore" });
20812
+ const storeHelpers = createStoreHelpers();
20780
20813
 
20781
20814
  function Appearance({ appearance, }) {
20782
20815
  React.useEffect(() => {
@@ -31660,18 +31693,19 @@ var CheckoutForm$2 = React.memo(CheckoutForm$1);
31660
31693
 
31661
31694
  const publicStripeKey = "pk_test_51OjSZ2JoDmiuDQz4Vub296KIgTCy4y8NJos59h93bq3sLe3veuXnV9XVmvvWDFlt3aEWHY4pOuIXyahEjjKZwezn00qo4U5fQS";
31662
31695
  const stripePromise = stripeJs.loadStripe(publicStripeKey);
31663
- function PaymentElement({ paymentSecret, checkoutAppearance, onSuccess, onError, children, }) {
31696
+ function PaymentElement({ paymentSecret, checkoutAppearance, fonts, onSuccess, onError, children, }) {
31664
31697
  const options = {
31665
31698
  locale: "en",
31666
31699
  appearance: checkoutAppearance,
31667
31700
  clientSecret: paymentSecret,
31701
+ fonts: fonts,
31668
31702
  };
31669
31703
  return (React.createElement(reactStripeJs.Elements, { stripe: stripePromise, options: options },
31670
31704
  React.createElement(CheckoutForm$2, { onSuccess: onSuccess, onError: onError, children: children })));
31671
31705
  }
31672
31706
  var PaymentElement$1 = React.memo(PaymentElement);
31673
31707
 
31674
- function PaymentForm({ paymentSecret, onSuccess, onError, onBack, onDoubleBack, contactEmail, shippingAddress, shippingProvider, shippingPrice, checkoutAppearance, }) {
31708
+ function PaymentForm({ paymentSecret, onSuccess, onError, onBack, onDoubleBack, contactEmail, shippingAddress, shippingProvider, shippingPrice, checkoutAppearance, fonts, }) {
31675
31709
  const { t } = reactI18next.useTranslation();
31676
31710
  return (React.createElement("div", { className: "space-y-6" },
31677
31711
  React.createElement("div", null,
@@ -31699,7 +31733,7 @@ function PaymentForm({ paymentSecret, onSuccess, onError, onBack, onDoubleBack,
31699
31733
  " \u00B7 ",
31700
31734
  shippingPrice)),
31701
31735
  React.createElement(Button, { variant: "link", onClick: onBack }, t("CheckoutEmbed.Shipping.change")))),
31702
- React.createElement("div", { className: "mt-8" }, paymentSecret && (React.createElement(PaymentElement$1, { checkoutAppearance: convertCheckoutAppearanceToStripeAppearance(checkoutAppearance), paymentSecret: paymentSecret, onSuccess: onSuccess, onError: onError },
31736
+ React.createElement("div", { className: "mt-8" }, paymentSecret && (React.createElement(PaymentElement$1, { fonts: fonts, checkoutAppearance: convertCheckoutAppearanceToStripeAppearance(checkoutAppearance), paymentSecret: paymentSecret, onSuccess: onSuccess, onError: onError },
31703
31737
  React.createElement("div", { className: "flex justify-between items-center pt-8" },
31704
31738
  React.createElement(Button, { type: "button", variant: "ghost", onClick: onBack },
31705
31739
  React.createElement(lucideReact.ChevronLeft, null),
@@ -31796,7 +31830,7 @@ const motionSettings = {
31796
31830
  exit: { opacity: 0 },
31797
31831
  transition: { duration: 0.2 },
31798
31832
  };
31799
- function CheckoutForm({ checkoutId, onSuccess, onError, cancelUrl, clientSecret, customer, currency, checkoutAppearance, }) {
31833
+ function CheckoutForm({ checkoutId, onSuccess, onError, cancelUrl, clientSecret, customer, currency, checkoutAppearance, fonts, }) {
31800
31834
  const { formData, setFormData, step, setStep } = useFormStore(checkoutId)();
31801
31835
  const [paymentSecret, setPaymentSecret] = React.useState(null);
31802
31836
  const [shippingRates, setShippingRates] = React.useState([]);
@@ -31923,7 +31957,7 @@ function CheckoutForm({ checkoutId, onSuccess, onError, cancelUrl, clientSecret,
31923
31957
  step === "shipping" && formData.customer && (React.createElement(motion.div, Object.assign({ key: "shipping" }, motionSettings, { className: "absolute w-full" }),
31924
31958
  React.createElement(ShippingMethodForm, { shippingRates: shippingRates, initialData: formData.shipping, onSubmit: handleShippingSubmit, onBack: handleBack, contactEmail: formData.customer.email, shippingAddress: formatAddress(formData.customer.address) }))),
31925
31959
  step === "payment" && formData.customer && formData.shipping && (React.createElement(motion.div, Object.assign({ key: "payment" }, motionSettings, { className: "absolute w-full" }),
31926
- React.createElement(PaymentForm, { checkoutAppearance: checkoutAppearance, paymentSecret: paymentSecret, onSuccess: onSuccess, onError: onError, onBack: handleBack, onDoubleBack: handleDoubleBack, contactEmail: formData.customer.email, shippingAddress: formatAddress(formData.customer.address), shippingProvider: formData.shipping.provider, shippingPrice: formData.shipping.amount.toString() + " " + currency }))))));
31960
+ React.createElement(PaymentForm, { fonts: fonts, checkoutAppearance: checkoutAppearance, paymentSecret: paymentSecret, onSuccess: onSuccess, onError: onError, onBack: handleBack, onDoubleBack: handleDoubleBack, contactEmail: formData.customer.email, shippingAddress: formatAddress(formData.customer.address), shippingProvider: formData.shipping.provider, shippingPrice: formData.shipping.amount.toString() + " " + currency }))))));
31927
31961
  }
31928
31962
 
31929
31963
  function CheckoutFormLoading() {
@@ -31952,9 +31986,6 @@ function CheckoutSummary({ lineItems, shipping, tax, currency, cancelUrl, exchan
31952
31986
  return acc + ((_b = (_a = item.product) === null || _a === void 0 ? void 0 : _a.priceInCents) !== null && _b !== void 0 ? _b : 0) * item.quantity;
31953
31987
  }, 0);
31954
31988
  const total = subtotal + (tax !== null && tax !== void 0 ? tax : 0) + (shipping !== null && shipping !== void 0 ? shipping : 0);
31955
- const formatPrice = (cents) => {
31956
- return `${((cents / 100) * exchangeRate).toFixed(2)} ${currency}`;
31957
- };
31958
31989
  return (React.createElement("div", { className: "grid gap-5" },
31959
31990
  React.createElement("div", { className: "flex justify-between items-center" },
31960
31991
  React.createElement("h2", null, t("CheckoutEmbed.Summary.title")),
@@ -31964,18 +31995,18 @@ function CheckoutSummary({ lineItems, shipping, tax, currency, cancelUrl, exchan
31964
31995
  React.createElement("div", { className: "grid gap-3" },
31965
31996
  React.createElement("div", { className: "flex justify-between" },
31966
31997
  React.createElement("p", null, t("CheckoutEmbed.Summary.subtotal")),
31967
- React.createElement("p", null, formatPrice(subtotal))),
31998
+ React.createElement("p", null, storeHelpers.formatPrice(subtotal, currency, exchangeRate))),
31968
31999
  React.createElement("div", { className: "flex justify-between" },
31969
32000
  React.createElement("p", null, t("CheckoutEmbed.Summary.shipping")),
31970
32001
  React.createElement("p", null, !!shipping
31971
- ? formatPrice(shipping)
32002
+ ? storeHelpers.formatPrice(shipping, currency, exchangeRate)
31972
32003
  : t("CheckoutEmbed.Summary.calculatedAtNextStep"))),
31973
32004
  !!tax && (React.createElement("div", { className: "flex justify-between" },
31974
32005
  React.createElement("p", null, t("CheckoutEmbed.Summary.tax")),
31975
- React.createElement("p", null, formatPrice(tax)))),
32006
+ React.createElement("p", null, storeHelpers.formatPrice(tax, currency, exchangeRate)))),
31976
32007
  React.createElement("div", { className: "flex font-bold justify-between items-center" },
31977
32008
  React.createElement("p", null, t("CheckoutEmbed.Summary.total")),
31978
- React.createElement("p", null, formatPrice(total)))),
32009
+ React.createElement("p", null, storeHelpers.formatPrice(total, currency, exchangeRate)))),
31979
32010
  React.createElement("hr", null),
31980
32011
  lineItems.map((item, index) => {
31981
32012
  var _a, _b, _c, _d, _e;
@@ -31987,7 +32018,7 @@ function CheckoutSummary({ lineItems, shipping, tax, currency, cancelUrl, exchan
31987
32018
  React.createElement("h3", { className: "text-lg font-medium" }, (_c = item.product) === null || _c === void 0 ? void 0 : _c.title),
31988
32019
  React.createElement("p", { className: "text-muted-foreground text-sm" }, item.variantOptions.map((option) => option.name).join(" / "))),
31989
32020
  React.createElement("div", { className: "text-right" },
31990
- React.createElement("p", { className: "text-lg font-medium" }, formatPrice((_e = (_d = item.product) === null || _d === void 0 ? void 0 : _d.priceInCents) !== null && _e !== void 0 ? _e : 0)))));
32021
+ React.createElement("p", { className: "text-lg font-medium" }, storeHelpers.formatPrice((_e = (_d = item.product) === null || _d === void 0 ? void 0 : _d.priceInCents) !== null && _e !== void 0 ? _e : 0, currency, exchangeRate)))));
31991
32022
  })));
31992
32023
  }
31993
32024
 
@@ -32065,7 +32096,7 @@ function CheckoutEmbed({ checkoutId, config }) {
32065
32096
  }
32066
32097
  return (React.createElement("div", { className: "checkout-embed mx-auto max-w-[1200px] min-h-screen overflow-x-hidden py-8 md:py-12 grid md:grid-cols-7 " },
32067
32098
  React.createElement(Appearance, { appearance: appearance }),
32068
- React.createElement("div", { className: "md:col-span-4 px-4 md:px-8" }, loading ? (React.createElement(CheckoutFormLoading, null)) : (React.createElement(CheckoutForm, { checkoutAppearance: appearance, currency: (_a = checkout === null || checkout === void 0 ? void 0 : checkout.currency) !== null && _a !== void 0 ? _a : "", customer: checkout === null || checkout === void 0 ? void 0 : checkout.customer, cancelUrl: cancelUrl, checkoutId: checkoutId, clientSecret: clientSecret, onSuccess: onSuccess, onError: onError }))),
32099
+ React.createElement("div", { className: "md:col-span-4 px-4 md:px-8" }, loading ? (React.createElement(CheckoutFormLoading, null)) : (React.createElement(CheckoutForm, { fonts: config.fonts, checkoutAppearance: appearance, currency: (_a = checkout === null || checkout === void 0 ? void 0 : checkout.currency) !== null && _a !== void 0 ? _a : "", customer: checkout === null || checkout === void 0 ? void 0 : checkout.customer, cancelUrl: cancelUrl, checkoutId: checkoutId, clientSecret: clientSecret, onSuccess: onSuccess, onError: onError }))),
32069
32100
  React.createElement("div", { className: "md:col-span-3 px-4 md:px-8 order-first md:order-last" }, loading ? (React.createElement(CheckoutSummaryLoading, null)) : (React.createElement(CheckoutSummary, { currency: (_b = checkout === null || checkout === void 0 ? void 0 : checkout.currency) !== null && _b !== void 0 ? _b : "", lineItems: (_c = checkout === null || checkout === void 0 ? void 0 : checkout.lineItems) !== null && _c !== void 0 ? _c : [], shipping: checkout === null || checkout === void 0 ? void 0 : checkout.shipping, tax: checkout === null || checkout === void 0 ? void 0 : checkout.tax, cancelUrl: cancelUrl, exchangeRate: (_d = checkout === null || checkout === void 0 ? void 0 : checkout.exchangeRate) !== null && _d !== void 0 ? _d : 1 })))));
32070
32101
  }
32071
32102
  var index = React.memo(CheckoutEmbed);
package/dist/index.mjs CHANGED
@@ -20749,11 +20749,44 @@ var Client = class {
20749
20749
  }
20750
20750
  };
20751
20751
  var client_default = Client;
20752
+ var Helpers = class {
20753
+ constructor(proxy) {
20754
+ this.proxy = proxy;
20755
+ }
20756
+ formatPrice(priceInCents, currency, exchangeRate) {
20757
+ const amount = priceInCents / 100 * (exchangeRate != null ? exchangeRate : 1);
20758
+ const isWhole = amount % 1 === 0;
20759
+ const formattedPrice = new Intl.NumberFormat(void 0, {
20760
+ style: "currency",
20761
+ currency,
20762
+ minimumFractionDigits: isWhole ? 0 : 2,
20763
+ maximumFractionDigits: isWhole ? 0 : 2
20764
+ }).format(amount);
20765
+ return formattedPrice;
20766
+ }
20767
+ getExchangeRate(baseCurrency, targetCurrency) {
20768
+ return __async(this, null, function* () {
20769
+ const { data } = yield axios.get(
20770
+ `https://api.exchangerate-api.com/v4/latest/${baseCurrency}`
20771
+ );
20772
+ const rate = data.rates[targetCurrency];
20773
+ if (!rate) {
20774
+ throw new Error("Could not get exchange rate for target currency");
20775
+ }
20776
+ return rate;
20777
+ });
20778
+ }
20779
+ };
20780
+ var helpers_default = Helpers;
20752
20781
  function createStoreClient(config) {
20753
- return new client_default(config.proxy);
20782
+ return new client_default(config == null ? void 0 : config.proxy);
20783
+ }
20784
+ function createStoreHelpers(config) {
20785
+ return new helpers_default(void 0 );
20754
20786
  }
20755
20787
 
20756
20788
  const storeClient = createStoreClient({ proxy: "/api/betterstore" });
20789
+ const storeHelpers = createStoreHelpers();
20757
20790
 
20758
20791
  function Appearance({ appearance, }) {
20759
20792
  useEffect(() => {
@@ -31637,18 +31670,19 @@ var CheckoutForm$2 = memo$1(CheckoutForm$1);
31637
31670
 
31638
31671
  const publicStripeKey = "pk_test_51OjSZ2JoDmiuDQz4Vub296KIgTCy4y8NJos59h93bq3sLe3veuXnV9XVmvvWDFlt3aEWHY4pOuIXyahEjjKZwezn00qo4U5fQS";
31639
31672
  const stripePromise = loadStripe(publicStripeKey);
31640
- function PaymentElement({ paymentSecret, checkoutAppearance, onSuccess, onError, children, }) {
31673
+ function PaymentElement({ paymentSecret, checkoutAppearance, fonts, onSuccess, onError, children, }) {
31641
31674
  const options = {
31642
31675
  locale: "en",
31643
31676
  appearance: checkoutAppearance,
31644
31677
  clientSecret: paymentSecret,
31678
+ fonts: fonts,
31645
31679
  };
31646
31680
  return (React__default.createElement(Elements, { stripe: stripePromise, options: options },
31647
31681
  React__default.createElement(CheckoutForm$2, { onSuccess: onSuccess, onError: onError, children: children })));
31648
31682
  }
31649
31683
  var PaymentElement$1 = memo$1(PaymentElement);
31650
31684
 
31651
- function PaymentForm({ paymentSecret, onSuccess, onError, onBack, onDoubleBack, contactEmail, shippingAddress, shippingProvider, shippingPrice, checkoutAppearance, }) {
31685
+ function PaymentForm({ paymentSecret, onSuccess, onError, onBack, onDoubleBack, contactEmail, shippingAddress, shippingProvider, shippingPrice, checkoutAppearance, fonts, }) {
31652
31686
  const { t } = useTranslation();
31653
31687
  return (React__default.createElement("div", { className: "space-y-6" },
31654
31688
  React__default.createElement("div", null,
@@ -31676,7 +31710,7 @@ function PaymentForm({ paymentSecret, onSuccess, onError, onBack, onDoubleBack,
31676
31710
  " \u00B7 ",
31677
31711
  shippingPrice)),
31678
31712
  React__default.createElement(Button, { variant: "link", onClick: onBack }, t("CheckoutEmbed.Shipping.change")))),
31679
- React__default.createElement("div", { className: "mt-8" }, paymentSecret && (React__default.createElement(PaymentElement$1, { checkoutAppearance: convertCheckoutAppearanceToStripeAppearance(checkoutAppearance), paymentSecret: paymentSecret, onSuccess: onSuccess, onError: onError },
31713
+ React__default.createElement("div", { className: "mt-8" }, paymentSecret && (React__default.createElement(PaymentElement$1, { fonts: fonts, checkoutAppearance: convertCheckoutAppearanceToStripeAppearance(checkoutAppearance), paymentSecret: paymentSecret, onSuccess: onSuccess, onError: onError },
31680
31714
  React__default.createElement("div", { className: "flex justify-between items-center pt-8" },
31681
31715
  React__default.createElement(Button, { type: "button", variant: "ghost", onClick: onBack },
31682
31716
  React__default.createElement(ChevronLeft, null),
@@ -31773,7 +31807,7 @@ const motionSettings = {
31773
31807
  exit: { opacity: 0 },
31774
31808
  transition: { duration: 0.2 },
31775
31809
  };
31776
- function CheckoutForm({ checkoutId, onSuccess, onError, cancelUrl, clientSecret, customer, currency, checkoutAppearance, }) {
31810
+ function CheckoutForm({ checkoutId, onSuccess, onError, cancelUrl, clientSecret, customer, currency, checkoutAppearance, fonts, }) {
31777
31811
  const { formData, setFormData, step, setStep } = useFormStore(checkoutId)();
31778
31812
  const [paymentSecret, setPaymentSecret] = useState(null);
31779
31813
  const [shippingRates, setShippingRates] = useState([]);
@@ -31900,7 +31934,7 @@ function CheckoutForm({ checkoutId, onSuccess, onError, cancelUrl, clientSecret,
31900
31934
  step === "shipping" && formData.customer && (React__default.createElement(motion.div, Object.assign({ key: "shipping" }, motionSettings, { className: "absolute w-full" }),
31901
31935
  React__default.createElement(ShippingMethodForm, { shippingRates: shippingRates, initialData: formData.shipping, onSubmit: handleShippingSubmit, onBack: handleBack, contactEmail: formData.customer.email, shippingAddress: formatAddress(formData.customer.address) }))),
31902
31936
  step === "payment" && formData.customer && formData.shipping && (React__default.createElement(motion.div, Object.assign({ key: "payment" }, motionSettings, { className: "absolute w-full" }),
31903
- React__default.createElement(PaymentForm, { checkoutAppearance: checkoutAppearance, paymentSecret: paymentSecret, onSuccess: onSuccess, onError: onError, onBack: handleBack, onDoubleBack: handleDoubleBack, contactEmail: formData.customer.email, shippingAddress: formatAddress(formData.customer.address), shippingProvider: formData.shipping.provider, shippingPrice: formData.shipping.amount.toString() + " " + currency }))))));
31937
+ React__default.createElement(PaymentForm, { fonts: fonts, checkoutAppearance: checkoutAppearance, paymentSecret: paymentSecret, onSuccess: onSuccess, onError: onError, onBack: handleBack, onDoubleBack: handleDoubleBack, contactEmail: formData.customer.email, shippingAddress: formatAddress(formData.customer.address), shippingProvider: formData.shipping.provider, shippingPrice: formData.shipping.amount.toString() + " " + currency }))))));
31904
31938
  }
31905
31939
 
31906
31940
  function CheckoutFormLoading() {
@@ -31929,9 +31963,6 @@ function CheckoutSummary({ lineItems, shipping, tax, currency, cancelUrl, exchan
31929
31963
  return acc + ((_b = (_a = item.product) === null || _a === void 0 ? void 0 : _a.priceInCents) !== null && _b !== void 0 ? _b : 0) * item.quantity;
31930
31964
  }, 0);
31931
31965
  const total = subtotal + (tax !== null && tax !== void 0 ? tax : 0) + (shipping !== null && shipping !== void 0 ? shipping : 0);
31932
- const formatPrice = (cents) => {
31933
- return `${((cents / 100) * exchangeRate).toFixed(2)} ${currency}`;
31934
- };
31935
31966
  return (React__default.createElement("div", { className: "grid gap-5" },
31936
31967
  React__default.createElement("div", { className: "flex justify-between items-center" },
31937
31968
  React__default.createElement("h2", null, t("CheckoutEmbed.Summary.title")),
@@ -31941,18 +31972,18 @@ function CheckoutSummary({ lineItems, shipping, tax, currency, cancelUrl, exchan
31941
31972
  React__default.createElement("div", { className: "grid gap-3" },
31942
31973
  React__default.createElement("div", { className: "flex justify-between" },
31943
31974
  React__default.createElement("p", null, t("CheckoutEmbed.Summary.subtotal")),
31944
- React__default.createElement("p", null, formatPrice(subtotal))),
31975
+ React__default.createElement("p", null, storeHelpers.formatPrice(subtotal, currency, exchangeRate))),
31945
31976
  React__default.createElement("div", { className: "flex justify-between" },
31946
31977
  React__default.createElement("p", null, t("CheckoutEmbed.Summary.shipping")),
31947
31978
  React__default.createElement("p", null, !!shipping
31948
- ? formatPrice(shipping)
31979
+ ? storeHelpers.formatPrice(shipping, currency, exchangeRate)
31949
31980
  : t("CheckoutEmbed.Summary.calculatedAtNextStep"))),
31950
31981
  !!tax && (React__default.createElement("div", { className: "flex justify-between" },
31951
31982
  React__default.createElement("p", null, t("CheckoutEmbed.Summary.tax")),
31952
- React__default.createElement("p", null, formatPrice(tax)))),
31983
+ React__default.createElement("p", null, storeHelpers.formatPrice(tax, currency, exchangeRate)))),
31953
31984
  React__default.createElement("div", { className: "flex font-bold justify-between items-center" },
31954
31985
  React__default.createElement("p", null, t("CheckoutEmbed.Summary.total")),
31955
- React__default.createElement("p", null, formatPrice(total)))),
31986
+ React__default.createElement("p", null, storeHelpers.formatPrice(total, currency, exchangeRate)))),
31956
31987
  React__default.createElement("hr", null),
31957
31988
  lineItems.map((item, index) => {
31958
31989
  var _a, _b, _c, _d, _e;
@@ -31964,7 +31995,7 @@ function CheckoutSummary({ lineItems, shipping, tax, currency, cancelUrl, exchan
31964
31995
  React__default.createElement("h3", { className: "text-lg font-medium" }, (_c = item.product) === null || _c === void 0 ? void 0 : _c.title),
31965
31996
  React__default.createElement("p", { className: "text-muted-foreground text-sm" }, item.variantOptions.map((option) => option.name).join(" / "))),
31966
31997
  React__default.createElement("div", { className: "text-right" },
31967
- React__default.createElement("p", { className: "text-lg font-medium" }, formatPrice((_e = (_d = item.product) === null || _d === void 0 ? void 0 : _d.priceInCents) !== null && _e !== void 0 ? _e : 0)))));
31998
+ React__default.createElement("p", { className: "text-lg font-medium" }, storeHelpers.formatPrice((_e = (_d = item.product) === null || _d === void 0 ? void 0 : _d.priceInCents) !== null && _e !== void 0 ? _e : 0, currency, exchangeRate)))));
31968
31999
  })));
31969
32000
  }
31970
32001
 
@@ -32042,7 +32073,7 @@ function CheckoutEmbed({ checkoutId, config }) {
32042
32073
  }
32043
32074
  return (React__default.createElement("div", { className: "checkout-embed mx-auto max-w-[1200px] min-h-screen overflow-x-hidden py-8 md:py-12 grid md:grid-cols-7 " },
32044
32075
  React__default.createElement(Appearance, { appearance: appearance }),
32045
- React__default.createElement("div", { className: "md:col-span-4 px-4 md:px-8" }, loading ? (React__default.createElement(CheckoutFormLoading, null)) : (React__default.createElement(CheckoutForm, { checkoutAppearance: appearance, currency: (_a = checkout === null || checkout === void 0 ? void 0 : checkout.currency) !== null && _a !== void 0 ? _a : "", customer: checkout === null || checkout === void 0 ? void 0 : checkout.customer, cancelUrl: cancelUrl, checkoutId: checkoutId, clientSecret: clientSecret, onSuccess: onSuccess, onError: onError }))),
32076
+ React__default.createElement("div", { className: "md:col-span-4 px-4 md:px-8" }, loading ? (React__default.createElement(CheckoutFormLoading, null)) : (React__default.createElement(CheckoutForm, { fonts: config.fonts, checkoutAppearance: appearance, currency: (_a = checkout === null || checkout === void 0 ? void 0 : checkout.currency) !== null && _a !== void 0 ? _a : "", customer: checkout === null || checkout === void 0 ? void 0 : checkout.customer, cancelUrl: cancelUrl, checkoutId: checkoutId, clientSecret: clientSecret, onSuccess: onSuccess, onError: onError }))),
32046
32077
  React__default.createElement("div", { className: "md:col-span-3 px-4 md:px-8 order-first md:order-last" }, loading ? (React__default.createElement(CheckoutSummaryLoading, null)) : (React__default.createElement(CheckoutSummary, { currency: (_b = checkout === null || checkout === void 0 ? void 0 : checkout.currency) !== null && _b !== void 0 ? _b : "", lineItems: (_c = checkout === null || checkout === void 0 ? void 0 : checkout.lineItems) !== null && _c !== void 0 ? _c : [], shipping: checkout === null || checkout === void 0 ? void 0 : checkout.shipping, tax: checkout === null || checkout === void 0 ? void 0 : checkout.tax, cancelUrl: cancelUrl, exchangeRate: (_d = checkout === null || checkout === void 0 ? void 0 : checkout.exchangeRate) !== null && _d !== void 0 ? _d : 1 })))));
32047
32078
  }
32048
32079
  var index = memo$1(CheckoutEmbed);
@@ -8,3 +8,8 @@ export declare const storeClient: {
8
8
  retrieveCustomer(clientSecret: string, idOrEmail: string): Promise<import("@betterstore/sdk").Customer>;
9
9
  updateCustomer(clientSecret: string, customerId: string, params: import("@betterstore/sdk").CustomerUpdateParams): Promise<import("@betterstore/sdk").Customer>;
10
10
  };
11
+ export declare const storeHelpers: {
12
+ proxy?: string;
13
+ formatPrice(priceInCents: number, currency: string, exchangeRate?: number): string;
14
+ getExchangeRate(baseCurrency: string, targetCurrency: string): Promise<number>;
15
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@betterstore/react",
3
- "version": "0.2.14",
3
+ "version": "0.2.16",
4
4
  "description": "E-commerce for Developers",
5
5
  "private": false,
6
6
  "publishConfig": {
@@ -19,7 +19,7 @@
19
19
  "author": "Better Store",
20
20
  "license": "MIT",
21
21
  "devDependencies": {
22
- "@betterstore/sdk": "^0.3.16",
22
+ "@betterstore/sdk": "^0.3.21",
23
23
  "@changesets/cli": "^2.28.1",
24
24
  "@rollup/plugin-commonjs": "^28.0.3",
25
25
  "@rollup/plugin-json": "^6.1.0",