@solvapay/react 2.0.1 → 2.0.2-preview-55843c4d7bb67bbe89bfcdabbbe0e3a679eb2805

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.
@@ -2225,7 +2225,305 @@ function interpolate(template, vars) {
2225
2225
  }
2226
2226
 
2227
2227
  // src/primitives/CheckoutSummary.tsx
2228
- import { createContext as createContext5, forwardRef as forwardRef2, useContext as useContext6, useMemo as useMemo4 } from "react";
2228
+ import { createContext as createContext5, forwardRef as forwardRef3, useContext as useContext6, useMemo as useMemo4 } from "react";
2229
+
2230
+ // src/components/businessCheckoutParts.tsx
2231
+ import { forwardRef as forwardRef2 } from "react";
2232
+ import {
2233
+ BUSINESS_COUNTRY_OPTIONS,
2234
+ SUPPORTED_BUSINESS_COUNTRIES,
2235
+ validateBusinessDetails,
2236
+ getTaxIdFieldLabel,
2237
+ getTaxIdExample,
2238
+ getTaxIdHelperText
2239
+ } from "@solvapay/core";
2240
+ import { Fragment as Fragment3, jsx as jsx7, jsxs as jsxs2 } from "react/jsx-runtime";
2241
+ function mapBusinessFieldErrors(input) {
2242
+ const result = validateBusinessDetails(input);
2243
+ if (result.success) return {};
2244
+ const errors = {};
2245
+ for (const issue of result.error.issues) {
2246
+ const key = issue.path[0];
2247
+ if (typeof key === "string" && isBusinessDetailsKey(key) && !errors[key]) {
2248
+ errors[key] = issue.message;
2249
+ }
2250
+ }
2251
+ return errors;
2252
+ }
2253
+ function isBusinessDetailsKey(key) {
2254
+ return key === "isBusiness" || key === "businessName" || key === "country" || key === "customerCountry" || key === "customerName" || key === "taxId" || key === "taxIdType";
2255
+ }
2256
+ function attr(prefix, suffix) {
2257
+ return `data-solvapay-${prefix}-${suffix}`;
2258
+ }
2259
+ var SUPPORTED_BUSINESS_COUNTRIES_SET = new Set(SUPPORTED_BUSINESS_COUNTRIES);
2260
+ function isSupportedBusinessCountry(value) {
2261
+ return SUPPORTED_BUSINESS_COUNTRIES_SET.has(value);
2262
+ }
2263
+ function resolveTaxIdLabel(country) {
2264
+ if (country && isSupportedBusinessCountry(country)) {
2265
+ return getTaxIdFieldLabel(country);
2266
+ }
2267
+ return "Tax ID";
2268
+ }
2269
+ function resolveTaxIdPlaceholder(country) {
2270
+ if (country && isSupportedBusinessCountry(country)) {
2271
+ return getTaxIdExample(country);
2272
+ }
2273
+ return "Enter tax ID";
2274
+ }
2275
+ function resolveTaxIdHelperText(country) {
2276
+ if (country && isSupportedBusinessCountry(country)) {
2277
+ return getTaxIdHelperText(country);
2278
+ }
2279
+ return "";
2280
+ }
2281
+ var REVERSE_CHARGE_NOTE = "VAT reverse charge applies \u2014 you are responsible for reporting VAT in your jurisdiction.";
2282
+ var TAX_NOT_COLLECTED_NOTE = "Tax is not collected on this purchase.";
2283
+ function formatVatSummaryLabel(breakdown) {
2284
+ if (breakdown.treatment === "reverse_charge") {
2285
+ return "VAT (reverse charge)";
2286
+ }
2287
+ if (breakdown.taxRate > 0) {
2288
+ const ratePercent = breakdown.taxRate <= 1 ? Math.round(breakdown.taxRate * 100) : breakdown.taxRate;
2289
+ return `VAT (${ratePercent}%)`;
2290
+ }
2291
+ return "VAT";
2292
+ }
2293
+ function shouldShowTaxRow(treatment) {
2294
+ return treatment !== "not_collecting" && treatment !== "not_supported";
2295
+ }
2296
+ function formatSubtotalLabel(treatment) {
2297
+ return shouldShowTaxRow(treatment) ? "Subtotal (excl. VAT)" : "Subtotal";
2298
+ }
2299
+ function createBusinessDetailsParts(useCtx, prefix) {
2300
+ const Root8 = forwardRef2(function BusinessDetailsRoot({ asChild, children, ...rest }, forwardedRef) {
2301
+ useCtx("BusinessDetails");
2302
+ const Comp = asChild ? Slot : "section";
2303
+ return /* @__PURE__ */ jsx7(Comp, { ref: forwardedRef, ...{ [attr(prefix, "business-details")]: "" }, ...rest, children });
2304
+ });
2305
+ const Toggle = forwardRef2(function BusinessDetailsToggle({ asChild, onChange, ...rest }, forwardedRef) {
2306
+ const ctx = useCtx("BusinessDetails.Toggle");
2307
+ const commonProps = {
2308
+ [attr(prefix, "business-details-toggle")]: "",
2309
+ type: "checkbox",
2310
+ checked: ctx.businessDetails.isBusiness,
2311
+ onChange: composeEventHandlers(onChange, (e) => {
2312
+ ctx.setBusinessDetails({ isBusiness: e.target.checked });
2313
+ }),
2314
+ ...rest
2315
+ };
2316
+ if (asChild) {
2317
+ return /* @__PURE__ */ jsx7(Slot, { ref: forwardedRef, ...commonProps });
2318
+ }
2319
+ return /* @__PURE__ */ jsx7("input", { ref: forwardedRef, ...commonProps });
2320
+ });
2321
+ const BusinessName = forwardRef2(
2322
+ function BusinessDetailsBusinessName({ asChild, onChange, ...rest }, forwardedRef) {
2323
+ const ctx = useCtx("BusinessDetails.BusinessName");
2324
+ if (!ctx.businessDetails.isBusiness) return null;
2325
+ const commonProps = {
2326
+ [attr(prefix, "business-details-name")]: "",
2327
+ type: "text",
2328
+ value: ctx.businessDetails.businessName ?? "",
2329
+ "aria-invalid": ctx.fieldErrors.businessName ? true : void 0,
2330
+ onChange: composeEventHandlers(onChange, (e) => {
2331
+ ctx.setBusinessDetails({ businessName: e.target.value });
2332
+ }),
2333
+ ...rest
2334
+ };
2335
+ if (asChild) {
2336
+ return /* @__PURE__ */ jsx7(Slot, { ref: forwardedRef, ...commonProps });
2337
+ }
2338
+ return /* @__PURE__ */ jsx7("input", { ref: forwardedRef, ...commonProps });
2339
+ }
2340
+ );
2341
+ const Country = forwardRef2(function BusinessDetailsCountry({ asChild, onChange, children, ...rest }, forwardedRef) {
2342
+ const ctx = useCtx("BusinessDetails.Country");
2343
+ if (!ctx.businessDetails.isBusiness) return null;
2344
+ const commonProps = {
2345
+ [attr(prefix, "business-details-country")]: "",
2346
+ value: ctx.businessDetails.country ?? "",
2347
+ "aria-invalid": ctx.fieldErrors.country ? true : void 0,
2348
+ onChange: composeEventHandlers(onChange, (e) => {
2349
+ ctx.setBusinessDetails({ country: e.target.value });
2350
+ }),
2351
+ ...rest
2352
+ };
2353
+ const defaultOptions = /* @__PURE__ */ jsxs2(Fragment3, { children: [
2354
+ /* @__PURE__ */ jsx7("option", { value: "", children: "Select country" }),
2355
+ BUSINESS_COUNTRY_OPTIONS.map(({ value, label }) => /* @__PURE__ */ jsx7("option", { value, children: label }, value))
2356
+ ] });
2357
+ if (asChild) {
2358
+ return /* @__PURE__ */ jsx7(Slot, { ref: forwardedRef, ...commonProps, children: children ?? defaultOptions });
2359
+ }
2360
+ return /* @__PURE__ */ jsx7("select", { ref: forwardedRef, ...commonProps, children: children ?? defaultOptions });
2361
+ });
2362
+ const TaxId = forwardRef2(function BusinessDetailsTaxId({ asChild, onChange, ...rest }, forwardedRef) {
2363
+ const ctx = useCtx("BusinessDetails.TaxId");
2364
+ if (!ctx.businessDetails.isBusiness) return null;
2365
+ const commonProps = {
2366
+ [attr(prefix, "business-details-tax-id")]: "",
2367
+ type: "text",
2368
+ value: ctx.businessDetails.taxId ?? "",
2369
+ "aria-invalid": ctx.fieldErrors.taxId ? true : void 0,
2370
+ onChange: composeEventHandlers(onChange, (e) => {
2371
+ ctx.setBusinessDetails({ taxId: e.target.value });
2372
+ }),
2373
+ ...rest
2374
+ };
2375
+ if (asChild) {
2376
+ return /* @__PURE__ */ jsx7(Slot, { ref: forwardedRef, ...commonProps });
2377
+ }
2378
+ return /* @__PURE__ */ jsx7("input", { ref: forwardedRef, ...commonProps });
2379
+ });
2380
+ const Fields = forwardRef2(function BusinessDetailsFields({ asChild, children, ...rest }, forwardedRef) {
2381
+ const ctx = useCtx("BusinessDetails.Fields");
2382
+ const country = ctx.businessDetails.country ?? "";
2383
+ const taxIdLabel = resolveTaxIdLabel(country);
2384
+ const taxIdPlaceholder = resolveTaxIdPlaceholder(country);
2385
+ const taxIdHelperText = resolveTaxIdHelperText(country);
2386
+ const content = /* @__PURE__ */ jsxs2(Fragment3, { children: [
2387
+ /* @__PURE__ */ jsxs2("label", { className: "solvapay-checkout-business-toggle", children: [
2388
+ /* @__PURE__ */ jsx7(Toggle, {}),
2389
+ "I'm purchasing as a business"
2390
+ ] }),
2391
+ ctx.businessDetails.isBusiness ? /* @__PURE__ */ jsxs2("fieldset", { className: "solvapay-business-fields", children: [
2392
+ /* @__PURE__ */ jsxs2("label", { className: "solvapay-business-field", children: [
2393
+ /* @__PURE__ */ jsx7("span", { className: "solvapay-business-field-label", children: "Business name" }),
2394
+ /* @__PURE__ */ jsx7(BusinessName, { placeholder: "Acme GmbH" })
2395
+ ] }),
2396
+ /* @__PURE__ */ jsxs2("label", { className: "solvapay-business-field", children: [
2397
+ /* @__PURE__ */ jsx7("span", { className: "solvapay-business-field-label", children: "Country" }),
2398
+ /* @__PURE__ */ jsx7(Country, {})
2399
+ ] }),
2400
+ /* @__PURE__ */ jsxs2("label", { className: "solvapay-business-field", children: [
2401
+ /* @__PURE__ */ jsx7("span", { className: "solvapay-business-field-label", children: taxIdLabel }),
2402
+ /* @__PURE__ */ jsx7(TaxId, { placeholder: taxIdPlaceholder }),
2403
+ taxIdHelperText ? /* @__PURE__ */ jsx7("p", { className: "solvapay-business-field-hint", children: taxIdHelperText }) : null
2404
+ ] })
2405
+ ] }) : null,
2406
+ children
2407
+ ] });
2408
+ if (asChild) {
2409
+ return /* @__PURE__ */ jsx7(Slot, { ref: forwardedRef, ...rest, children: content });
2410
+ }
2411
+ return /* @__PURE__ */ jsx7("section", { ref: forwardedRef, ...{ [attr(prefix, "business-details-fields")]: "" }, ...rest, children: content });
2412
+ });
2413
+ return {
2414
+ Root: Root8,
2415
+ Toggle,
2416
+ BusinessName,
2417
+ Country,
2418
+ TaxId,
2419
+ Fields
2420
+ };
2421
+ }
2422
+ function useSummaryAmounts(useCtx, part) {
2423
+ const ctx = useCtx(part);
2424
+ const locale = useLocale();
2425
+ const currency = (ctx.taxBreakdown?.currency ?? ctx.currency ?? "usd").toLowerCase();
2426
+ const subtotalMinor = ctx.taxBreakdown?.subtotal ?? ctx.baseAmountMinor;
2427
+ const taxMinor = ctx.taxBreakdown?.taxAmount ?? 0;
2428
+ const totalMinor = ctx.taxBreakdown?.total ?? ctx.baseAmountMinor;
2429
+ return {
2430
+ // `free: ''` — a summary line is an amount, not a price. Without it
2431
+ // formatPrice turns any zero (VAT, and a zero subtotal or total) into
2432
+ // the word "Free". DEV-723.
2433
+ subtotalFormatted: formatPrice(subtotalMinor, currency, { locale, free: "" }),
2434
+ taxFormatted: formatPrice(taxMinor, currency, { locale, free: "" }),
2435
+ totalFormatted: formatPrice(totalMinor, currency, { locale, free: "" }),
2436
+ taxRate: ctx.taxBreakdown?.taxRate ?? 0,
2437
+ treatment: ctx.taxBreakdown?.treatment ?? null,
2438
+ attaching: ctx.businessDetailsAttaching
2439
+ };
2440
+ }
2441
+ function createTaxSummaryParts(useCtx, prefix) {
2442
+ const Root8 = forwardRef2(function TaxSummaryRoot({ asChild, children, ...rest }, forwardedRef) {
2443
+ const ctx = useCtx("Summary");
2444
+ if (!ctx.isBusiness) return null;
2445
+ const Comp = asChild ? Slot : "section";
2446
+ return /* @__PURE__ */ jsx7(Comp, { ref: forwardedRef, ...{ [attr(prefix, "summary")]: "" }, ...rest, children });
2447
+ });
2448
+ const Subtotal = forwardRef2(function TaxSummarySubtotal({ asChild, children, ...rest }, forwardedRef) {
2449
+ const ctx = useCtx("Summary.Subtotal");
2450
+ const { subtotalFormatted } = useSummaryAmounts(useCtx, "Summary.Subtotal");
2451
+ if (!ctx.isBusiness) return null;
2452
+ const Comp = asChild ? Slot : "span";
2453
+ return /* @__PURE__ */ jsx7(Comp, { ref: forwardedRef, ...{ [attr(prefix, "summary-subtotal")]: "" }, ...rest, children: children ?? subtotalFormatted });
2454
+ });
2455
+ const Tax = forwardRef2(function TaxSummaryTax({ asChild, children, ...rest }, forwardedRef) {
2456
+ const ctx = useCtx("Summary.Tax");
2457
+ const { taxFormatted, taxRate, treatment } = useSummaryAmounts(useCtx, "Summary.Tax");
2458
+ if (!ctx.isBusiness) return null;
2459
+ if (!shouldShowTaxRow(treatment)) return null;
2460
+ const Comp = asChild ? Slot : "span";
2461
+ const defaultLabel = formatVatSummaryLabel({
2462
+ treatment: treatment ?? "standard",
2463
+ taxRate
2464
+ });
2465
+ return /* @__PURE__ */ jsx7(Comp, { ref: forwardedRef, ...{ [attr(prefix, "summary-tax")]: "" }, ...rest, children: children ?? /* @__PURE__ */ jsxs2(Fragment3, { children: [
2466
+ /* @__PURE__ */ jsx7("span", { children: defaultLabel }),
2467
+ " ",
2468
+ /* @__PURE__ */ jsx7("span", { ...{ [attr(prefix, "summary-tax-amount")]: "" }, children: taxFormatted })
2469
+ ] }) });
2470
+ });
2471
+ const Total = forwardRef2(function TaxSummaryTotal({ asChild, children, ...rest }, forwardedRef) {
2472
+ const ctx = useCtx("Summary.Total");
2473
+ const { totalFormatted } = useSummaryAmounts(useCtx, "Summary.Total");
2474
+ if (!ctx.isBusiness) return null;
2475
+ const Comp = asChild ? Slot : "span";
2476
+ return /* @__PURE__ */ jsx7(Comp, { ref: forwardedRef, ...{ [attr(prefix, "summary-total")]: "" }, ...rest, children: children ?? totalFormatted });
2477
+ });
2478
+ const TaxNote = forwardRef2(function TaxSummaryTaxNote({ asChild, children, ...rest }, forwardedRef) {
2479
+ const ctx = useCtx("Summary.TaxNote");
2480
+ const { treatment } = useSummaryAmounts(useCtx, "Summary.TaxNote");
2481
+ if (!ctx.isBusiness) return null;
2482
+ if (!treatment || treatment === "standard") return null;
2483
+ const Comp = asChild ? Slot : "p";
2484
+ const defaultNote = treatment === "reverse_charge" ? REVERSE_CHARGE_NOTE : treatment === "not_collecting" || treatment === "not_supported" ? TAX_NOT_COLLECTED_NOTE : null;
2485
+ if (!defaultNote && !children) return null;
2486
+ return /* @__PURE__ */ jsx7(Comp, { ref: forwardedRef, ...{ [attr(prefix, "summary-tax-note")]: "" }, ...rest, children: children ?? defaultNote });
2487
+ });
2488
+ const Rows = forwardRef2(function TaxSummaryRows({ asChild, children, ...rest }, forwardedRef) {
2489
+ const ctx = useCtx("Summary.Rows");
2490
+ const { taxRate, treatment, taxFormatted } = useSummaryAmounts(useCtx, "Summary.Rows");
2491
+ if (!ctx.isBusiness) return null;
2492
+ const showTaxRow = shouldShowTaxRow(treatment);
2493
+ const vatLabel = formatVatSummaryLabel({
2494
+ treatment: treatment ?? "standard",
2495
+ taxRate
2496
+ });
2497
+ const content = /* @__PURE__ */ jsxs2("dl", { className: "solvapay-tax-summary-rows", children: [
2498
+ /* @__PURE__ */ jsxs2("div", { className: "solvapay-tax-summary-row", children: [
2499
+ /* @__PURE__ */ jsx7("dt", { children: formatSubtotalLabel(treatment) }),
2500
+ /* @__PURE__ */ jsx7("dd", { children: /* @__PURE__ */ jsx7(Subtotal, {}) })
2501
+ ] }),
2502
+ showTaxRow ? /* @__PURE__ */ jsxs2("div", { className: "solvapay-tax-summary-row", children: [
2503
+ /* @__PURE__ */ jsx7("dt", { children: vatLabel }),
2504
+ /* @__PURE__ */ jsx7("dd", { children: /* @__PURE__ */ jsx7("span", { ...{ [attr(prefix, "summary-tax-amount")]: "" }, children: taxFormatted }) })
2505
+ ] }) : null,
2506
+ /* @__PURE__ */ jsxs2("div", { className: "solvapay-tax-summary-row solvapay-tax-summary-row--total", children: [
2507
+ /* @__PURE__ */ jsx7("dt", { children: "Total" }),
2508
+ /* @__PURE__ */ jsx7("dd", { children: /* @__PURE__ */ jsx7(Total, {}) })
2509
+ ] }),
2510
+ /* @__PURE__ */ jsx7(TaxNote, {}),
2511
+ children
2512
+ ] });
2513
+ if (asChild) {
2514
+ return /* @__PURE__ */ jsx7(Slot, { ref: forwardedRef, ...rest, children: content });
2515
+ }
2516
+ return /* @__PURE__ */ jsx7("section", { ref: forwardedRef, ...{ [attr(prefix, "summary-rows")]: "" }, ...rest, children: content });
2517
+ });
2518
+ return {
2519
+ Root: Root8,
2520
+ Subtotal,
2521
+ Tax,
2522
+ Total,
2523
+ TaxNote,
2524
+ Rows
2525
+ };
2526
+ }
2229
2527
 
2230
2528
  // src/utils/errors.ts
2231
2529
  var DOCS_BASE_URL = "https://solvapay.com/docs";
@@ -2263,7 +2561,7 @@ var MissingProductRefError = class extends SolvaPayError2 {
2263
2561
  };
2264
2562
 
2265
2563
  // src/primitives/CheckoutSummary.tsx
2266
- import { Fragment as Fragment3, jsx as jsx7, jsxs as jsxs2 } from "react/jsx-runtime";
2564
+ import { Fragment as Fragment4, jsx as jsx8, jsxs as jsxs3 } from "react/jsx-runtime";
2267
2565
  var CheckoutSummaryContext = createContext5(null);
2268
2566
  function useCheckoutSummaryContext(part) {
2269
2567
  const ctx = useContext6(CheckoutSummaryContext);
@@ -2274,7 +2572,7 @@ function useCheckoutSummaryContext(part) {
2274
2572
  }
2275
2573
  return ctx;
2276
2574
  }
2277
- var Root = forwardRef2(function CheckoutSummaryRoot({ planRef, productRef, taxBreakdown = null, baseAmountMinor = 0, asChild, children, ...rest }, forwardedRef) {
2575
+ var Root = forwardRef3(function CheckoutSummaryRoot({ planRef, productRef, taxBreakdown = null, baseAmountMinor = 0, asChild, children, ...rest }, forwardedRef) {
2278
2576
  const solva = useContext6(SolvaPayContext);
2279
2577
  if (!solva) throw new MissingProviderError("CheckoutSummary");
2280
2578
  const locale = useLocale();
@@ -2307,9 +2605,9 @@ var Root = forwardRef2(function CheckoutSummaryRoot({ planRef, productRef, taxBr
2307
2605
  const subtotalMinor = taxBreakdown?.subtotal ?? baseAmountMinor;
2308
2606
  const taxMinor = taxBreakdown?.taxAmount ?? 0;
2309
2607
  const totalMinor = taxBreakdown?.total ?? baseAmountMinor;
2310
- const subtotalFormatted = formatPrice(subtotalMinor, taxCurrency, { locale });
2311
- const taxFormatted = formatPrice(taxMinor, taxCurrency, { locale });
2312
- const totalFormatted = formatPrice(totalMinor, taxCurrency, { locale });
2608
+ const subtotalFormatted = formatPrice(subtotalMinor, taxCurrency, { locale, free: "" });
2609
+ const taxFormatted = formatPrice(taxMinor, taxCurrency, { locale, free: "" });
2610
+ const totalFormatted = formatPrice(totalMinor, taxCurrency, { locale, free: "" });
2313
2611
  const ctx = useMemo4(
2314
2612
  () => ({
2315
2613
  plan,
@@ -2337,77 +2635,78 @@ var Root = forwardRef2(function CheckoutSummaryRoot({ planRef, productRef, taxBr
2337
2635
  ]
2338
2636
  );
2339
2637
  const Comp = asChild ? Slot : "section";
2340
- return /* @__PURE__ */ jsx7(Comp, { ref: forwardedRef, "data-solvapay-checkout-summary": "", ...rest, children: /* @__PURE__ */ jsx7(CheckoutSummaryContext.Provider, { value: ctx, children }) });
2638
+ return /* @__PURE__ */ jsx8(Comp, { ref: forwardedRef, "data-solvapay-checkout-summary": "", ...rest, children: /* @__PURE__ */ jsx8(CheckoutSummaryContext.Provider, { value: ctx, children }) });
2341
2639
  });
2342
- var ProductSlot = forwardRef2(function CheckoutSummaryProduct({ asChild, children, ...rest }, forwardedRef) {
2640
+ var ProductSlot = forwardRef3(function CheckoutSummaryProduct({ asChild, children, ...rest }, forwardedRef) {
2343
2641
  const ctx = useCheckoutSummaryContext("Product");
2344
2642
  const name = ctx.product?.name;
2345
2643
  if (!name) return null;
2346
2644
  const Comp = asChild ? Slot : "span";
2347
- return /* @__PURE__ */ jsx7(Comp, { ref: forwardedRef, "data-solvapay-checkout-summary-product": "", ...rest, children: children ?? name });
2645
+ return /* @__PURE__ */ jsx8(Comp, { ref: forwardedRef, "data-solvapay-checkout-summary-product": "", ...rest, children: children ?? name });
2348
2646
  });
2349
- var PlanSlot = forwardRef2(function CheckoutSummaryPlan({ asChild, children, ...rest }, forwardedRef) {
2647
+ var PlanSlot = forwardRef3(function CheckoutSummaryPlan({ asChild, children, ...rest }, forwardedRef) {
2350
2648
  const ctx = useCheckoutSummaryContext("Plan");
2351
2649
  const name = ctx.plan?.name;
2352
2650
  if (!name) return null;
2353
2651
  const Comp = asChild ? Slot : "span";
2354
- return /* @__PURE__ */ jsx7(Comp, { ref: forwardedRef, "data-solvapay-checkout-summary-plan": "", ...rest, children: children ?? name });
2652
+ return /* @__PURE__ */ jsx8(Comp, { ref: forwardedRef, "data-solvapay-checkout-summary-plan": "", ...rest, children: children ?? name });
2355
2653
  });
2356
- var TaxNoteSlot = forwardRef2(
2654
+ var TaxNoteSlot = forwardRef3(
2357
2655
  function CheckoutSummaryTaxNote({ asChild, children, ...rest }, forwardedRef) {
2358
2656
  const ctx = useCheckoutSummaryContext("TaxNote");
2359
2657
  if (ctx.taxBreakdown) return null;
2360
2658
  const Comp = asChild ? Slot : "p";
2361
- return /* @__PURE__ */ jsx7(Comp, { ref: forwardedRef, "data-solvapay-checkout-summary-tax-note": "", ...rest, children: children ?? "Taxes calculated at checkout" });
2659
+ return /* @__PURE__ */ jsx8(Comp, { ref: forwardedRef, "data-solvapay-checkout-summary-tax-note": "", ...rest, children: children ?? "Taxes calculated at checkout" });
2362
2660
  }
2363
2661
  );
2364
- var SubtotalSlot = forwardRef2(function CheckoutSummarySubtotal({ asChild, children, ...rest }, forwardedRef) {
2662
+ var SubtotalSlot = forwardRef3(function CheckoutSummarySubtotal({ asChild, children, ...rest }, forwardedRef) {
2365
2663
  const ctx = useCheckoutSummaryContext("Subtotal");
2366
2664
  if (!ctx.taxBreakdown) return null;
2367
2665
  const Comp = asChild ? Slot : "span";
2368
- return /* @__PURE__ */ jsx7(Comp, { ref: forwardedRef, "data-solvapay-checkout-summary-subtotal": "", ...rest, children: children ?? ctx.subtotalFormatted });
2666
+ return /* @__PURE__ */ jsx8(Comp, { ref: forwardedRef, "data-solvapay-checkout-summary-subtotal": "", ...rest, children: children ?? ctx.subtotalFormatted });
2369
2667
  });
2370
- var TaxSlot = forwardRef2(function CheckoutSummaryTax({ asChild, children, ...rest }, forwardedRef) {
2668
+ var TaxSlot = forwardRef3(function CheckoutSummaryTax({ asChild, children, ...rest }, forwardedRef) {
2371
2669
  const ctx = useCheckoutSummaryContext("Tax");
2372
2670
  if (!ctx.taxBreakdown) return null;
2373
- const Comp = asChild ? Slot : "span";
2374
2671
  const { taxRate, treatment } = ctx.taxBreakdown;
2375
- const defaultLabel = treatment === "reverse_charge" ? `VAT reverse charge (${ctx.taxFormatted})` : taxRate != null ? `Tax (${Math.round(taxRate * 100)}%)` : "Tax";
2376
- return /* @__PURE__ */ jsx7(Comp, { ref: forwardedRef, "data-solvapay-checkout-summary-tax": "", ...rest, children: children ?? /* @__PURE__ */ jsxs2(Fragment3, { children: [
2377
- /* @__PURE__ */ jsx7("span", { children: defaultLabel }),
2672
+ if (!shouldShowTaxRow(treatment)) return null;
2673
+ const Comp = asChild ? Slot : "span";
2674
+ const defaultLabel = formatVatSummaryLabel({ treatment, taxRate: taxRate ?? 0 });
2675
+ return /* @__PURE__ */ jsx8(Comp, { ref: forwardedRef, "data-solvapay-checkout-summary-tax": "", ...rest, children: children ?? /* @__PURE__ */ jsxs3(Fragment4, { children: [
2676
+ /* @__PURE__ */ jsx8("span", { children: defaultLabel }),
2378
2677
  " ",
2379
- /* @__PURE__ */ jsx7("span", { "data-solvapay-checkout-summary-tax-amount": "", children: ctx.taxFormatted })
2678
+ /* @__PURE__ */ jsx8("span", { "data-solvapay-checkout-summary-tax-amount": "", children: ctx.taxFormatted })
2380
2679
  ] }) });
2381
2680
  });
2382
- var TotalSlot = forwardRef2(function CheckoutSummaryTotal({ asChild, children, ...rest }, forwardedRef) {
2681
+ var TotalSlot = forwardRef3(function CheckoutSummaryTotal({ asChild, children, ...rest }, forwardedRef) {
2383
2682
  const ctx = useCheckoutSummaryContext("Total");
2384
2683
  if (!ctx.taxBreakdown) return null;
2385
2684
  const Comp = asChild ? Slot : "span";
2386
- return /* @__PURE__ */ jsx7(Comp, { ref: forwardedRef, "data-solvapay-checkout-summary-total": "", ...rest, children: children ?? ctx.totalFormatted });
2685
+ return /* @__PURE__ */ jsx8(Comp, { ref: forwardedRef, "data-solvapay-checkout-summary-total": "", ...rest, children: children ?? ctx.totalFormatted });
2387
2686
  });
2388
- var TaxTreatmentNoteSlot = forwardRef2(
2687
+ var TaxTreatmentNoteSlot = forwardRef3(
2389
2688
  function CheckoutSummaryTaxTreatmentNote({ asChild, children, ...rest }, forwardedRef) {
2390
2689
  const ctx = useCheckoutSummaryContext("TaxTreatmentNote");
2391
2690
  const treatment = ctx.taxBreakdown?.treatment;
2392
2691
  if (!treatment || treatment === "standard") return null;
2393
2692
  const Comp = asChild ? Slot : "p";
2394
- const defaultNote = treatment === "reverse_charge" ? "VAT reverse charge applies \u2014 you are responsible for reporting VAT in your jurisdiction." : treatment === "not_collecting" ? "Tax is not collected on this purchase." : null;
2693
+ const defaultNote = treatment === "reverse_charge" ? REVERSE_CHARGE_NOTE : treatment === "not_collecting" || treatment === "not_supported" ? TAX_NOT_COLLECTED_NOTE : null;
2395
2694
  if (!defaultNote && !children) return null;
2396
- return /* @__PURE__ */ jsx7(Comp, { ref: forwardedRef, "data-solvapay-checkout-summary-tax-treatment-note": "", ...rest, children: children ?? defaultNote });
2695
+ return /* @__PURE__ */ jsx8(Comp, { ref: forwardedRef, "data-solvapay-checkout-summary-tax-treatment-note": "", ...rest, children: children ?? defaultNote });
2397
2696
  }
2398
2697
  );
2399
- var PriceSlot = forwardRef2(function CheckoutSummaryPrice({ asChild, children, ...rest }, forwardedRef) {
2698
+ var PriceSlot = forwardRef3(function CheckoutSummaryPrice({ asChild, children, ...rest }, forwardedRef) {
2400
2699
  const ctx = useCheckoutSummaryContext("Price");
2401
2700
  if (ctx.taxBreakdown) return null;
2402
2701
  const Comp = asChild ? Slot : "span";
2403
- return /* @__PURE__ */ jsx7(Comp, { ref: forwardedRef, "data-solvapay-checkout-summary-price": "", ...rest, children: children ?? ctx.priceFormatted });
2702
+ return /* @__PURE__ */ jsx8(Comp, { ref: forwardedRef, "data-solvapay-checkout-summary-price": "", ...rest, children: children ?? ctx.priceFormatted });
2404
2703
  });
2405
- var TrialSlot = forwardRef2(
2704
+ var TrialSlot = forwardRef3(
2406
2705
  function CheckoutSummaryTrial({ asChild, children, ...rest }, forwardedRef) {
2407
2706
  const ctx = useCheckoutSummaryContext("Trial");
2408
2707
  if (!ctx.trialBanner || ctx.taxBreakdown) return null;
2409
2708
  const Comp = asChild ? Slot : "p";
2410
- return /* @__PURE__ */ jsx7(Comp, { ref: forwardedRef, "data-solvapay-checkout-summary-trial": "", ...rest, children: children ?? ctx.trialBanner });
2709
+ return /* @__PURE__ */ jsx8(Comp, { ref: forwardedRef, "data-solvapay-checkout-summary-trial": "", ...rest, children: children ?? ctx.trialBanner });
2411
2710
  }
2412
2711
  );
2413
2712
  var CheckoutSummaryRoot2 = Root;
@@ -2437,7 +2736,7 @@ function useCheckoutSummary() {
2437
2736
  }
2438
2737
 
2439
2738
  // src/components/CheckoutSummary.tsx
2440
- import { Fragment as Fragment4, jsx as jsx8, jsxs as jsxs3 } from "react/jsx-runtime";
2739
+ import { Fragment as Fragment5, jsx as jsx9, jsxs as jsxs4 } from "react/jsx-runtime";
2441
2740
  var CheckoutSummary2 = ({
2442
2741
  planRef,
2443
2742
  productRef,
@@ -2449,7 +2748,7 @@ var CheckoutSummary2 = ({
2449
2748
  }) => {
2450
2749
  const rootClass = ["solvapay-checkout-summary", className].filter(Boolean).join(" ");
2451
2750
  const hasTax = taxBreakdown != null;
2452
- return /* @__PURE__ */ jsxs3(
2751
+ return /* @__PURE__ */ jsxs4(
2453
2752
  CheckoutSummary.Root,
2454
2753
  {
2455
2754
  planRef,
@@ -2458,25 +2757,25 @@ var CheckoutSummary2 = ({
2458
2757
  baseAmountMinor,
2459
2758
  className: rootClass,
2460
2759
  children: [
2461
- /* @__PURE__ */ jsx8(CheckoutSummary.Product, { className: "solvapay-checkout-summary-product" }),
2462
- /* @__PURE__ */ jsxs3("div", { className: "solvapay-checkout-summary-row", children: [
2463
- /* @__PURE__ */ jsx8(CheckoutSummary.Plan, { className: "solvapay-checkout-summary-plan" }),
2464
- !hasTax && /* @__PURE__ */ jsx8(CheckoutSummary.Price, { className: "solvapay-checkout-summary-price" })
2760
+ /* @__PURE__ */ jsx9(CheckoutSummary.Product, { className: "solvapay-checkout-summary-product" }),
2761
+ /* @__PURE__ */ jsxs4("div", { className: "solvapay-checkout-summary-row", children: [
2762
+ /* @__PURE__ */ jsx9(CheckoutSummary.Plan, { className: "solvapay-checkout-summary-plan" }),
2763
+ !hasTax && /* @__PURE__ */ jsx9(CheckoutSummary.Price, { className: "solvapay-checkout-summary-price" })
2465
2764
  ] }),
2466
- hasTax ? /* @__PURE__ */ jsxs3(Fragment4, { children: [
2467
- /* @__PURE__ */ jsxs3("div", { className: "solvapay-checkout-summary-row", children: [
2468
- /* @__PURE__ */ jsx8("span", { children: "Subtotal" }),
2469
- /* @__PURE__ */ jsx8(CheckoutSummary.Subtotal, { className: "solvapay-checkout-summary-subtotal" })
2765
+ hasTax ? /* @__PURE__ */ jsxs4(Fragment5, { children: [
2766
+ /* @__PURE__ */ jsxs4("div", { className: "solvapay-checkout-summary-row", children: [
2767
+ /* @__PURE__ */ jsx9("span", { children: "Subtotal" }),
2768
+ /* @__PURE__ */ jsx9(CheckoutSummary.Subtotal, { className: "solvapay-checkout-summary-subtotal" })
2470
2769
  ] }),
2471
- /* @__PURE__ */ jsx8("div", { className: "solvapay-checkout-summary-row", children: /* @__PURE__ */ jsx8(CheckoutSummary.Tax, { className: "solvapay-checkout-summary-tax" }) }),
2472
- /* @__PURE__ */ jsxs3("div", { className: "solvapay-checkout-summary-row", children: [
2473
- /* @__PURE__ */ jsx8("span", { children: "Total" }),
2474
- /* @__PURE__ */ jsx8(CheckoutSummary.Total, { className: "solvapay-checkout-summary-total" })
2770
+ /* @__PURE__ */ jsx9("div", { className: "solvapay-checkout-summary-row", children: /* @__PURE__ */ jsx9(CheckoutSummary.Tax, { className: "solvapay-checkout-summary-tax" }) }),
2771
+ /* @__PURE__ */ jsxs4("div", { className: "solvapay-checkout-summary-row", children: [
2772
+ /* @__PURE__ */ jsx9("span", { children: "Total" }),
2773
+ /* @__PURE__ */ jsx9(CheckoutSummary.Total, { className: "solvapay-checkout-summary-total" })
2475
2774
  ] }),
2476
- /* @__PURE__ */ jsx8(CheckoutSummary.TaxTreatmentNote, { className: "solvapay-checkout-summary-tax-treatment-note" })
2477
- ] }) : /* @__PURE__ */ jsxs3(Fragment4, { children: [
2478
- showTrial && /* @__PURE__ */ jsx8(CheckoutSummary.Trial, { className: "solvapay-checkout-summary-trial" }),
2479
- showTaxNote && /* @__PURE__ */ jsx8(CheckoutSummary.TaxNote, { className: "solvapay-checkout-summary-tax-note" })
2775
+ /* @__PURE__ */ jsx9(CheckoutSummary.TaxTreatmentNote, { className: "solvapay-checkout-summary-tax-treatment-note" })
2776
+ ] }) : /* @__PURE__ */ jsxs4(Fragment5, { children: [
2777
+ showTrial && /* @__PURE__ */ jsx9(CheckoutSummary.Trial, { className: "solvapay-checkout-summary-trial" }),
2778
+ showTaxNote && /* @__PURE__ */ jsx9(CheckoutSummary.TaxNote, { className: "solvapay-checkout-summary-tax-note" })
2480
2779
  ] })
2481
2780
  ]
2482
2781
  }
@@ -2589,9 +2888,9 @@ function deriveVariant(plan, mode) {
2589
2888
  }
2590
2889
 
2591
2890
  // src/primitives/MandateText.tsx
2592
- import { forwardRef as forwardRef3, useContext as useContext7, useMemo as useMemo5 } from "react";
2593
- import { jsx as jsx9 } from "react/jsx-runtime";
2594
- var MandateText = forwardRef3(
2891
+ import { forwardRef as forwardRef4, useContext as useContext7, useMemo as useMemo5 } from "react";
2892
+ import { jsx as jsx10 } from "react/jsx-runtime";
2893
+ var MandateText = forwardRef4(
2595
2894
  function MandateText2({
2596
2895
  planRef,
2597
2896
  productRef,
@@ -2647,7 +2946,7 @@ var MandateText = forwardRef3(
2647
2946
  const text = typeof template === "function" ? template(ctx) : template;
2648
2947
  if (!text) return null;
2649
2948
  const Comp = asChild ? Slot : "p";
2650
- return /* @__PURE__ */ jsx9(
2949
+ return /* @__PURE__ */ jsx10(
2651
2950
  Comp,
2652
2951
  {
2653
2952
  ref: forwardedRef,
@@ -2669,7 +2968,7 @@ function linkifyMandateText(text, merchant, copy) {
2669
2968
  return text.split(pattern).map((part, i) => {
2670
2969
  const match = entries.find((e) => e.url === part);
2671
2970
  if (!match) return part;
2672
- return /* @__PURE__ */ jsx9(
2971
+ return /* @__PURE__ */ jsx10(
2673
2972
  "a",
2674
2973
  {
2675
2974
  href: match.url,
@@ -2687,11 +2986,11 @@ function escapeRegExp(value) {
2687
2986
  }
2688
2987
 
2689
2988
  // src/components/Spinner.tsx
2690
- import { jsx as jsx10, jsxs as jsxs4 } from "react/jsx-runtime";
2989
+ import { jsx as jsx11, jsxs as jsxs5 } from "react/jsx-runtime";
2691
2990
  var SIZE_PX = { sm: 16, md: 20, lg: 24 };
2692
2991
  var Spinner = ({ className, size = "md" }) => {
2693
2992
  const px = SIZE_PX[size];
2694
- return /* @__PURE__ */ jsxs4(
2993
+ return /* @__PURE__ */ jsxs5(
2695
2994
  "svg",
2696
2995
  {
2697
2996
  "data-solvapay-spinner": "",
@@ -2702,7 +3001,7 @@ var Spinner = ({ className, size = "md" }) => {
2702
3001
  fill: "none",
2703
3002
  "aria-hidden": "true",
2704
3003
  children: [
2705
- /* @__PURE__ */ jsx10(
3004
+ /* @__PURE__ */ jsx11(
2706
3005
  "circle",
2707
3006
  {
2708
3007
  cx: "12",
@@ -2713,7 +3012,7 @@ var Spinner = ({ className, size = "md" }) => {
2713
3012
  strokeOpacity: "0.25"
2714
3013
  }
2715
3014
  ),
2716
- /* @__PURE__ */ jsx10(
3015
+ /* @__PURE__ */ jsx11(
2717
3016
  "path",
2718
3017
  {
2719
3018
  fill: "currentColor",
@@ -3021,302 +3320,6 @@ import { useCallback as useCallback8, useEffect as useEffect6, useRef as useRef4
3021
3320
  import {
3022
3321
  validateBusinessDetails as validateBusinessDetails2
3023
3322
  } from "@solvapay/core";
3024
-
3025
- // src/components/businessCheckoutParts.tsx
3026
- import { forwardRef as forwardRef4 } from "react";
3027
- import {
3028
- BUSINESS_COUNTRY_OPTIONS,
3029
- SUPPORTED_BUSINESS_COUNTRIES,
3030
- validateBusinessDetails,
3031
- getTaxIdFieldLabel,
3032
- getTaxIdExample,
3033
- getTaxIdHelperText
3034
- } from "@solvapay/core";
3035
- import { Fragment as Fragment5, jsx as jsx11, jsxs as jsxs5 } from "react/jsx-runtime";
3036
- function mapBusinessFieldErrors(input) {
3037
- const result = validateBusinessDetails(input);
3038
- if (result.success) return {};
3039
- const errors = {};
3040
- for (const issue of result.error.issues) {
3041
- const key = issue.path[0];
3042
- if (typeof key === "string" && isBusinessDetailsKey(key) && !errors[key]) {
3043
- errors[key] = issue.message;
3044
- }
3045
- }
3046
- return errors;
3047
- }
3048
- function isBusinessDetailsKey(key) {
3049
- return key === "isBusiness" || key === "businessName" || key === "country" || key === "customerCountry" || key === "customerName" || key === "taxId" || key === "taxIdType";
3050
- }
3051
- function attr(prefix, suffix) {
3052
- return `data-solvapay-${prefix}-${suffix}`;
3053
- }
3054
- var SUPPORTED_BUSINESS_COUNTRIES_SET = new Set(SUPPORTED_BUSINESS_COUNTRIES);
3055
- function isSupportedBusinessCountry(value) {
3056
- return SUPPORTED_BUSINESS_COUNTRIES_SET.has(value);
3057
- }
3058
- function resolveTaxIdLabel(country) {
3059
- if (country && isSupportedBusinessCountry(country)) {
3060
- return getTaxIdFieldLabel(country);
3061
- }
3062
- return "Tax ID";
3063
- }
3064
- function resolveTaxIdPlaceholder(country) {
3065
- if (country && isSupportedBusinessCountry(country)) {
3066
- return getTaxIdExample(country);
3067
- }
3068
- return "Enter tax ID";
3069
- }
3070
- function resolveTaxIdHelperText(country) {
3071
- if (country && isSupportedBusinessCountry(country)) {
3072
- return getTaxIdHelperText(country);
3073
- }
3074
- return "";
3075
- }
3076
- function formatVatSummaryLabel(breakdown) {
3077
- if (breakdown.treatment === "reverse_charge") {
3078
- return "VAT (reverse charge)";
3079
- }
3080
- if (breakdown.taxRate > 0) {
3081
- const ratePercent = breakdown.taxRate <= 1 ? Math.round(breakdown.taxRate * 100) : breakdown.taxRate;
3082
- return breakdown.inclusive ? `VAT (${ratePercent}%, incl.)` : `VAT (${ratePercent}%)`;
3083
- }
3084
- return "VAT";
3085
- }
3086
- function shouldShowTaxRow(treatment, taxRate) {
3087
- if (treatment === "not_collecting") return false;
3088
- if (treatment === "reverse_charge") return true;
3089
- return taxRate > 0;
3090
- }
3091
- function createBusinessDetailsParts(useCtx, prefix) {
3092
- const Root8 = forwardRef4(function BusinessDetailsRoot({ asChild, children, ...rest }, forwardedRef) {
3093
- useCtx("BusinessDetails");
3094
- const Comp = asChild ? Slot : "section";
3095
- return /* @__PURE__ */ jsx11(Comp, { ref: forwardedRef, ...{ [attr(prefix, "business-details")]: "" }, ...rest, children });
3096
- });
3097
- const Toggle = forwardRef4(function BusinessDetailsToggle({ asChild, onChange, ...rest }, forwardedRef) {
3098
- const ctx = useCtx("BusinessDetails.Toggle");
3099
- const commonProps = {
3100
- [attr(prefix, "business-details-toggle")]: "",
3101
- type: "checkbox",
3102
- checked: ctx.businessDetails.isBusiness,
3103
- onChange: composeEventHandlers(onChange, (e) => {
3104
- ctx.setBusinessDetails({ isBusiness: e.target.checked });
3105
- }),
3106
- ...rest
3107
- };
3108
- if (asChild) {
3109
- return /* @__PURE__ */ jsx11(Slot, { ref: forwardedRef, ...commonProps });
3110
- }
3111
- return /* @__PURE__ */ jsx11("input", { ref: forwardedRef, ...commonProps });
3112
- });
3113
- const BusinessName = forwardRef4(
3114
- function BusinessDetailsBusinessName({ asChild, onChange, ...rest }, forwardedRef) {
3115
- const ctx = useCtx("BusinessDetails.BusinessName");
3116
- if (!ctx.businessDetails.isBusiness) return null;
3117
- const commonProps = {
3118
- [attr(prefix, "business-details-name")]: "",
3119
- type: "text",
3120
- value: ctx.businessDetails.businessName ?? "",
3121
- "aria-invalid": ctx.fieldErrors.businessName ? true : void 0,
3122
- onChange: composeEventHandlers(onChange, (e) => {
3123
- ctx.setBusinessDetails({ businessName: e.target.value });
3124
- }),
3125
- ...rest
3126
- };
3127
- if (asChild) {
3128
- return /* @__PURE__ */ jsx11(Slot, { ref: forwardedRef, ...commonProps });
3129
- }
3130
- return /* @__PURE__ */ jsx11("input", { ref: forwardedRef, ...commonProps });
3131
- }
3132
- );
3133
- const Country = forwardRef4(function BusinessDetailsCountry({ asChild, onChange, children, ...rest }, forwardedRef) {
3134
- const ctx = useCtx("BusinessDetails.Country");
3135
- if (!ctx.businessDetails.isBusiness) return null;
3136
- const commonProps = {
3137
- [attr(prefix, "business-details-country")]: "",
3138
- value: ctx.businessDetails.country ?? "",
3139
- "aria-invalid": ctx.fieldErrors.country ? true : void 0,
3140
- onChange: composeEventHandlers(onChange, (e) => {
3141
- ctx.setBusinessDetails({ country: e.target.value });
3142
- }),
3143
- ...rest
3144
- };
3145
- const defaultOptions = /* @__PURE__ */ jsxs5(Fragment5, { children: [
3146
- /* @__PURE__ */ jsx11("option", { value: "", children: "Select country" }),
3147
- BUSINESS_COUNTRY_OPTIONS.map(({ value, label }) => /* @__PURE__ */ jsx11("option", { value, children: label }, value))
3148
- ] });
3149
- if (asChild) {
3150
- return /* @__PURE__ */ jsx11(Slot, { ref: forwardedRef, ...commonProps, children: children ?? defaultOptions });
3151
- }
3152
- return /* @__PURE__ */ jsx11("select", { ref: forwardedRef, ...commonProps, children: children ?? defaultOptions });
3153
- });
3154
- const TaxId = forwardRef4(function BusinessDetailsTaxId({ asChild, onChange, ...rest }, forwardedRef) {
3155
- const ctx = useCtx("BusinessDetails.TaxId");
3156
- if (!ctx.businessDetails.isBusiness) return null;
3157
- const commonProps = {
3158
- [attr(prefix, "business-details-tax-id")]: "",
3159
- type: "text",
3160
- value: ctx.businessDetails.taxId ?? "",
3161
- "aria-invalid": ctx.fieldErrors.taxId ? true : void 0,
3162
- onChange: composeEventHandlers(onChange, (e) => {
3163
- ctx.setBusinessDetails({ taxId: e.target.value });
3164
- }),
3165
- ...rest
3166
- };
3167
- if (asChild) {
3168
- return /* @__PURE__ */ jsx11(Slot, { ref: forwardedRef, ...commonProps });
3169
- }
3170
- return /* @__PURE__ */ jsx11("input", { ref: forwardedRef, ...commonProps });
3171
- });
3172
- const Fields = forwardRef4(function BusinessDetailsFields({ asChild, children, ...rest }, forwardedRef) {
3173
- const ctx = useCtx("BusinessDetails.Fields");
3174
- const country = ctx.businessDetails.country ?? "";
3175
- const taxIdLabel = resolveTaxIdLabel(country);
3176
- const taxIdPlaceholder = resolveTaxIdPlaceholder(country);
3177
- const taxIdHelperText = resolveTaxIdHelperText(country);
3178
- const content = /* @__PURE__ */ jsxs5(Fragment5, { children: [
3179
- /* @__PURE__ */ jsxs5("label", { className: "solvapay-checkout-business-toggle", children: [
3180
- /* @__PURE__ */ jsx11(Toggle, {}),
3181
- "I'm purchasing as a business"
3182
- ] }),
3183
- ctx.businessDetails.isBusiness ? /* @__PURE__ */ jsxs5("fieldset", { className: "solvapay-business-fields", children: [
3184
- /* @__PURE__ */ jsxs5("label", { className: "solvapay-business-field", children: [
3185
- /* @__PURE__ */ jsx11("span", { className: "solvapay-business-field-label", children: "Business name" }),
3186
- /* @__PURE__ */ jsx11(BusinessName, { placeholder: "Acme GmbH" })
3187
- ] }),
3188
- /* @__PURE__ */ jsxs5("label", { className: "solvapay-business-field", children: [
3189
- /* @__PURE__ */ jsx11("span", { className: "solvapay-business-field-label", children: "Country" }),
3190
- /* @__PURE__ */ jsx11(Country, {})
3191
- ] }),
3192
- /* @__PURE__ */ jsxs5("label", { className: "solvapay-business-field", children: [
3193
- /* @__PURE__ */ jsx11("span", { className: "solvapay-business-field-label", children: taxIdLabel }),
3194
- /* @__PURE__ */ jsx11(TaxId, { placeholder: taxIdPlaceholder }),
3195
- taxIdHelperText ? /* @__PURE__ */ jsx11("p", { className: "solvapay-business-field-hint", children: taxIdHelperText }) : null
3196
- ] })
3197
- ] }) : null,
3198
- children
3199
- ] });
3200
- if (asChild) {
3201
- return /* @__PURE__ */ jsx11(Slot, { ref: forwardedRef, ...rest, children: content });
3202
- }
3203
- return /* @__PURE__ */ jsx11("section", { ref: forwardedRef, ...{ [attr(prefix, "business-details-fields")]: "" }, ...rest, children: content });
3204
- });
3205
- return {
3206
- Root: Root8,
3207
- Toggle,
3208
- BusinessName,
3209
- Country,
3210
- TaxId,
3211
- Fields
3212
- };
3213
- }
3214
- function useSummaryAmounts(useCtx, part) {
3215
- const ctx = useCtx(part);
3216
- const locale = useLocale();
3217
- const currency = (ctx.taxBreakdown?.currency ?? ctx.currency ?? "usd").toLowerCase();
3218
- const subtotalMinor = ctx.taxBreakdown?.subtotal ?? ctx.baseAmountMinor;
3219
- const taxMinor = ctx.taxBreakdown?.taxAmount ?? 0;
3220
- const totalMinor = ctx.taxBreakdown?.total ?? ctx.baseAmountMinor;
3221
- return {
3222
- subtotalFormatted: formatPrice(subtotalMinor, currency, { locale }),
3223
- taxFormatted: formatPrice(taxMinor, currency, { locale }),
3224
- totalFormatted: formatPrice(totalMinor, currency, { locale }),
3225
- taxRate: ctx.taxBreakdown?.taxRate ?? 0,
3226
- treatment: ctx.taxBreakdown?.treatment ?? null,
3227
- inclusive: ctx.taxBreakdown?.inclusive ?? false,
3228
- attaching: ctx.businessDetailsAttaching
3229
- };
3230
- }
3231
- function createTaxSummaryParts(useCtx, prefix) {
3232
- const Root8 = forwardRef4(function TaxSummaryRoot({ asChild, children, ...rest }, forwardedRef) {
3233
- const ctx = useCtx("Summary");
3234
- if (!ctx.isBusiness) return null;
3235
- const Comp = asChild ? Slot : "section";
3236
- return /* @__PURE__ */ jsx11(Comp, { ref: forwardedRef, ...{ [attr(prefix, "summary")]: "" }, ...rest, children });
3237
- });
3238
- const Subtotal = forwardRef4(function TaxSummarySubtotal({ asChild, children, ...rest }, forwardedRef) {
3239
- const ctx = useCtx("Summary.Subtotal");
3240
- const { subtotalFormatted } = useSummaryAmounts(useCtx, "Summary.Subtotal");
3241
- if (!ctx.isBusiness) return null;
3242
- const Comp = asChild ? Slot : "span";
3243
- return /* @__PURE__ */ jsx11(Comp, { ref: forwardedRef, ...{ [attr(prefix, "summary-subtotal")]: "" }, ...rest, children: children ?? subtotalFormatted });
3244
- });
3245
- const Tax = forwardRef4(function TaxSummaryTax({ asChild, children, ...rest }, forwardedRef) {
3246
- const ctx = useCtx("Summary.Tax");
3247
- const { taxFormatted, taxRate, treatment, inclusive } = useSummaryAmounts(useCtx, "Summary.Tax");
3248
- if (!ctx.isBusiness) return null;
3249
- const Comp = asChild ? Slot : "span";
3250
- const defaultLabel = formatVatSummaryLabel({
3251
- treatment: treatment ?? "standard",
3252
- taxRate,
3253
- inclusive
3254
- });
3255
- return /* @__PURE__ */ jsx11(Comp, { ref: forwardedRef, ...{ [attr(prefix, "summary-tax")]: "" }, ...rest, children: children ?? /* @__PURE__ */ jsxs5(Fragment5, { children: [
3256
- /* @__PURE__ */ jsx11("span", { children: defaultLabel }),
3257
- " ",
3258
- /* @__PURE__ */ jsx11("span", { ...{ [attr(prefix, "summary-tax-amount")]: "" }, children: taxFormatted })
3259
- ] }) });
3260
- });
3261
- const Total = forwardRef4(function TaxSummaryTotal({ asChild, children, ...rest }, forwardedRef) {
3262
- const ctx = useCtx("Summary.Total");
3263
- const { totalFormatted } = useSummaryAmounts(useCtx, "Summary.Total");
3264
- if (!ctx.isBusiness) return null;
3265
- const Comp = asChild ? Slot : "span";
3266
- return /* @__PURE__ */ jsx11(Comp, { ref: forwardedRef, ...{ [attr(prefix, "summary-total")]: "" }, ...rest, children: children ?? totalFormatted });
3267
- });
3268
- const TaxNote = forwardRef4(function TaxSummaryTaxNote({ asChild, children, ...rest }, forwardedRef) {
3269
- const ctx = useCtx("Summary.TaxNote");
3270
- const { treatment } = useSummaryAmounts(useCtx, "Summary.TaxNote");
3271
- if (!ctx.isBusiness) return null;
3272
- if (!treatment || treatment === "standard") return null;
3273
- const Comp = asChild ? Slot : "p";
3274
- const defaultNote = treatment === "reverse_charge" ? "VAT reverse charge applies \u2014 you are responsible for reporting VAT in your jurisdiction." : treatment === "not_collecting" ? "Tax is not collected on this purchase." : null;
3275
- if (!defaultNote && !children) return null;
3276
- return /* @__PURE__ */ jsx11(Comp, { ref: forwardedRef, ...{ [attr(prefix, "summary-tax-note")]: "" }, ...rest, children: children ?? defaultNote });
3277
- });
3278
- const Rows = forwardRef4(function TaxSummaryRows({ asChild, children, ...rest }, forwardedRef) {
3279
- const ctx = useCtx("Summary.Rows");
3280
- const { taxRate, treatment, inclusive, taxFormatted } = useSummaryAmounts(useCtx, "Summary.Rows");
3281
- if (!ctx.isBusiness) return null;
3282
- const showTaxRow = shouldShowTaxRow(treatment, taxRate);
3283
- const vatLabel = formatVatSummaryLabel({
3284
- treatment: treatment ?? "standard",
3285
- taxRate,
3286
- inclusive
3287
- });
3288
- const content = /* @__PURE__ */ jsxs5("dl", { className: "solvapay-tax-summary-rows", children: [
3289
- /* @__PURE__ */ jsxs5("p", { className: "solvapay-tax-summary-row", children: [
3290
- /* @__PURE__ */ jsx11("dt", { children: "Subtotal" }),
3291
- /* @__PURE__ */ jsx11("dd", { children: /* @__PURE__ */ jsx11(Subtotal, {}) })
3292
- ] }),
3293
- showTaxRow ? /* @__PURE__ */ jsxs5("p", { className: "solvapay-tax-summary-row", children: [
3294
- /* @__PURE__ */ jsx11("dt", { children: vatLabel }),
3295
- /* @__PURE__ */ jsx11("dd", { children: /* @__PURE__ */ jsx11("span", { ...{ [attr(prefix, "summary-tax-amount")]: "" }, children: taxFormatted }) })
3296
- ] }) : null,
3297
- /* @__PURE__ */ jsxs5("p", { className: "solvapay-tax-summary-row solvapay-tax-summary-row--total", children: [
3298
- /* @__PURE__ */ jsx11("dt", { children: "Total" }),
3299
- /* @__PURE__ */ jsx11("dd", { children: /* @__PURE__ */ jsx11(Total, {}) })
3300
- ] }),
3301
- /* @__PURE__ */ jsx11(TaxNote, {}),
3302
- children
3303
- ] });
3304
- if (asChild) {
3305
- return /* @__PURE__ */ jsx11(Slot, { ref: forwardedRef, ...rest, children: content });
3306
- }
3307
- return /* @__PURE__ */ jsx11("section", { ref: forwardedRef, ...{ [attr(prefix, "summary-rows")]: "" }, ...rest, children: content });
3308
- });
3309
- return {
3310
- Root: Root8,
3311
- Subtotal,
3312
- Tax,
3313
- Total,
3314
- TaxNote,
3315
- Rows
3316
- };
3317
- }
3318
-
3319
- // src/hooks/useBusinessDetailsAttach.ts
3320
3323
  var defaultBusinessDetails = { isBusiness: false };
3321
3324
  function useBusinessDetailsAttach(options) {
3322
3325
  const {
@@ -6553,7 +6556,7 @@ import {
6553
6556
  creditsPerUnitFromBalance,
6554
6557
  includedUnits,
6555
6558
  meterName,
6556
- perUnitCharge
6559
+ usageRate
6557
6560
  } from "@solvapay/core";
6558
6561
  function isPayg(plan) {
6559
6562
  return isPaygPlan(plan ?? null);
@@ -6598,15 +6601,14 @@ function planBillingInterval(plan) {
6598
6601
  return readBillingCycle(plan)?.interval ?? null;
6599
6602
  }
6600
6603
  function formatPaygRate(plan, locale, balance) {
6604
+ const rate = usageRate(plan);
6605
+ if (!rate || !(rate.amountMinor > 0)) return null;
6606
+ const prefix = rate.tiered ? "from " : "";
6601
6607
  const credits = creditsPerUnitFromBalance(plan, balance);
6602
6608
  if (credits != null) {
6603
- return `${credits.toLocaleString(locale)} ${credits === 1 ? "credit" : "credits"} / call`;
6604
- }
6605
- const charge = perUnitCharge(plan);
6606
- if (charge && charge.amountMinor > 0) {
6607
- return `${formatPrice(charge.amountMinor, charge.currency.toUpperCase(), { locale })} / call`;
6609
+ return `${prefix}${credits.toLocaleString(locale)} ${credits === 1 ? "credit" : "credits"} / call`;
6608
6610
  }
6609
- return null;
6611
+ return `${prefix}${formatPrice(rate.amountMinor, rate.currency.toUpperCase(), { locale })} / call`;
6610
6612
  }
6611
6613
  function inferIncludedUnits(plan) {
6612
6614
  const cap = includedUnits(plan);