@cimplify/sdk 0.110.2 → 0.111.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. package/CHANGELOG.md +54 -0
  2. package/README.md +18 -0
  3. package/dist/advanced.d.mts +4 -4
  4. package/dist/advanced.d.ts +4 -4
  5. package/dist/advanced.js +22 -22
  6. package/dist/advanced.mjs +3 -3
  7. package/dist/{catalogue-OTuS5zp-.d.ts → catalogue-1QcoGDO6.d.ts} +2 -2
  8. package/dist/{catalogue-CPTMyBUz.d.mts → catalogue-FdFQiWrU.d.mts} +2 -2
  9. package/dist/{chunk-SYEO2WV4.mjs → chunk-42JTCWIE.mjs} +3 -3
  10. package/dist/{chunk-OMTVH334.js → chunk-6QANXRUM.js} +203 -186
  11. package/dist/{chunk-6ETDAU62.mjs → chunk-B45X3HPO.mjs} +98 -39
  12. package/dist/{chunk-MKIJQL5Q.js → chunk-CJVEJPIG.js} +69 -69
  13. package/dist/{chunk-Q2Y3VMKH.js → chunk-ETZDIISN.js} +151 -151
  14. package/dist/{chunk-GCKWKLZF.mjs → chunk-FT6GFYJL.mjs} +17 -3
  15. package/dist/{chunk-A36JRXXH.mjs → chunk-KWZHIPRN.mjs} +26 -9
  16. package/dist/{chunk-SNNEOS5Z.js → chunk-MHDUUSG6.js} +75 -75
  17. package/dist/{chunk-UCR5HRYM.js → chunk-NFXCKTE2.js} +17 -3
  18. package/dist/{chunk-DFZWHNRG.js → chunk-QOCHWR4V.js} +105 -42
  19. package/dist/{chunk-IZDWAL53.mjs → chunk-UJDQQTBS.mjs} +8 -8
  20. package/dist/{chunk-BTUSVHIE.mjs → chunk-WLSU5QJT.mjs} +2 -2
  21. package/dist/{client-dqOhP9Nc.d.ts → client-CChON4-x.d.ts} +2 -2
  22. package/dist/{client-CX_WR0-J.d.mts → client-EeuGm5gj.d.mts} +2 -2
  23. package/dist/{elements-DdsRig-2.d.mts → elements-ss9xZgRg.d.mts} +27 -1
  24. package/dist/{elements-DdsRig-2.d.ts → elements-ss9xZgRg.d.ts} +27 -1
  25. package/dist/index-BB2gjVvA.d.mts +153 -0
  26. package/dist/index-BEfmBDAH.d.ts +153 -0
  27. package/dist/{index-B98Xac8e.d.ts → index-DQK8sTfu.d.ts} +2 -2
  28. package/dist/{index-DbAN_VQE.d.mts → index-DSVkhRmW.d.mts} +2 -2
  29. package/dist/index.d.mts +8 -8
  30. package/dist/index.d.ts +8 -8
  31. package/dist/index.js +189 -177
  32. package/dist/index.mjs +8 -8
  33. package/dist/mock/cli.mjs +25 -10
  34. package/dist/mock/library.js +25 -10
  35. package/dist/mock/library.mjs +25 -10
  36. package/dist/mock/msw.js +25 -10
  37. package/dist/mock/msw.mjs +25 -10
  38. package/dist/{price-BOzexBww.d.mts → price-B-w4PwHm.d.mts} +1 -1
  39. package/dist/{price-C1h9sPxE.d.ts → price-BEvQFNJv.d.ts} +1 -1
  40. package/dist/react.d.mts +23 -15
  41. package/dist/react.d.ts +23 -15
  42. package/dist/react.js +254 -237
  43. package/dist/react.mjs +128 -111
  44. package/dist/{scheduling-D2ajXpMC.d.ts → scheduling-D9WwOxbo.d.ts} +1 -1
  45. package/dist/{scheduling-DSRbbaZb.d.mts → scheduling-DDmrYCr-.d.mts} +1 -1
  46. package/dist/{server-D29IIuDV.d.ts → server-BiKwxvnf.d.ts} +2 -2
  47. package/dist/{server-DQMWPnc8.d.mts → server-DPdtl2dd.d.mts} +2 -2
  48. package/dist/server.d.mts +4 -4
  49. package/dist/server.d.ts +4 -4
  50. package/dist/server.js +10 -10
  51. package/dist/server.mjs +4 -4
  52. package/dist/styles.css +1 -1
  53. package/dist/testing/msw.d.mts +3 -3
  54. package/dist/testing/msw.d.ts +3 -3
  55. package/dist/testing/msw.js +3 -3
  56. package/dist/testing/msw.mjs +2 -2
  57. package/dist/testing/suite.d.mts +6 -6
  58. package/dist/testing/suite.d.ts +6 -6
  59. package/dist/testing/suite.js +25 -25
  60. package/dist/testing/suite.mjs +6 -6
  61. package/dist/testing.d.mts +5 -5
  62. package/dist/testing.d.ts +5 -5
  63. package/dist/testing.js +117 -117
  64. package/dist/testing.mjs +7 -7
  65. package/dist/utils.d.mts +3 -3
  66. package/dist/utils.d.ts +3 -3
  67. package/dist/utils.js +44 -32
  68. package/dist/utils.mjs +2 -2
  69. package/package.json +5 -3
  70. package/registry/cart-summary.json +1 -1
  71. package/registry/chat-widget.json +1 -1
  72. package/registry/price.json +1 -1
  73. package/registry/product-customizer.json +1 -1
  74. package/registry/search-input.json +1 -1
  75. package/dist/index-6gkHMGAq.d.mts +0 -86
  76. package/dist/index-B_ByTtIT.d.ts +0 -86
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var chunkUCR5HRYM_js = require('./chunk-UCR5HRYM.js');
3
+ var chunkNFXCKTE2_js = require('./chunk-NFXCKTE2.js');
4
4
 
5
5
  // src/utils/price.ts
6
6
  var CURRENCY_SYMBOLS = {
@@ -77,39 +77,98 @@ var CURRENCY_SYMBOLS = {
77
77
  function getCurrencySymbol(currencyCode2) {
78
78
  return CURRENCY_SYMBOLS[currencyCode2.toUpperCase()] || currencyCode2;
79
79
  }
80
+ var PRICE_UNAVAILABLE_LABEL = "Price unavailable", DEFAULT_FORMAT_LOCALE = "en-US", PERCENT_SCALE = 100, ISO_CURRENCY_CODE = /^[A-Z]{3}$/, STANDARD_MINOR_UNIT_DIGITS = 2, ZERO_MINOR_UNIT_DIGITS = 0, THREE_MINOR_UNIT_DIGITS = 3, ZERO_DECIMAL_CURRENCIES = new Set(
81
+ "BIF CLP DJF GNF ISK JPY KMF KRW PYG RWF UGX VND VUV XAF XOF XPF".split(" ")
82
+ ), THREE_DECIMAL_CURRENCIES = new Set(
83
+ "BHD IQD JOD KWD LYD OMR TND".split(" ")
84
+ ), DECIMAL_BASE = 10, DECIMAL_RADIX = 10n, ROUND_UP_FROM_DIGIT = "5", PLAIN_DECIMAL_MAX_FRACTION_DIGITS = 20, DECIMAL_TEXT = /^([+-]?)(\d*)(?:\.(\d*))?$/, EXPONENT_NOTATION = /e/i, LOCALE_PROBE_VALUE = -1.5;
85
+ function currencyFractionDigits(currency) {
86
+ if (!currency) return null;
87
+ let code = currency.trim().toUpperCase();
88
+ return ISO_CURRENCY_CODE.test(code) ? ZERO_DECIMAL_CURRENCIES.has(code) ? (0) : THREE_DECIMAL_CURRENCIES.has(code) ? (3) : (2) : null;
89
+ }
90
+ function roundToCurrencyDigits(value, currency) {
91
+ let digits = currencyFractionDigits(currency);
92
+ if (digits === null) return value;
93
+ let factor = (10) ** digits;
94
+ return Math.round(value * factor) / factor;
95
+ }
96
+ function numberToDecimalText(value) {
97
+ if (!Number.isFinite(value)) return null;
98
+ let text = String(value);
99
+ return EXPONENT_NOTATION.test(text) ? value.toLocaleString(DEFAULT_FORMAT_LOCALE, {
100
+ useGrouping: false,
101
+ maximumFractionDigits: (20)
102
+ }) : text;
103
+ }
104
+ function roundDecimalText(text, digits) {
105
+ let match = DECIMAL_TEXT.exec(text.trim());
106
+ if (!match) return null;
107
+ let sign = match[1] ?? "", whole = match[2] ?? "", fraction = match[3] ?? "";
108
+ if (whole.length === 0 && fraction.length === 0) return null;
109
+ let kept = fraction.padEnd(digits, "0").slice(0, digits), scaled = BigInt(`${whole || "0"}${kept}`);
110
+ fraction.charAt(digits) >= ROUND_UP_FROM_DIGIT && (scaled += 1n);
111
+ let scale = DECIMAL_RADIX ** BigInt(digits);
112
+ return {
113
+ negative: sign === "-" && scaled !== 0n,
114
+ whole: scaled / scale,
115
+ fraction: digits === 0 ? "" : (scaled % scale).toString().padStart(digits, "0")
116
+ };
117
+ }
118
+ var symbolsByLocale = /* @__PURE__ */ new Map(), wholeFormatters = /* @__PURE__ */ new Map();
119
+ function localeNumberSymbols(locale) {
120
+ let cached = symbolsByLocale.get(locale);
121
+ if (cached) return cached;
122
+ let formatter = new Intl.NumberFormat(locale, { useGrouping: false }), parts = formatter.formatToParts((-1.5)), symbols = {
123
+ decimal: parts.find((part) => part.type === "decimal")?.value ?? ".",
124
+ minus: parts.find((part) => part.type === "minusSign")?.value ?? "-",
125
+ digits: Array.from({ length: (10) }, (_, digit) => formatter.format(digit))
126
+ };
127
+ return symbolsByLocale.set(locale, symbols), symbols;
128
+ }
129
+ function wholeFormatter(locale, grouping) {
130
+ let key = `${locale}|${grouping ? "grouped" : "plain"}`, cached = wholeFormatters.get(key);
131
+ if (cached) return cached;
132
+ let formatter = new Intl.NumberFormat(locale, { useGrouping: grouping });
133
+ return wholeFormatters.set(key, formatter), formatter;
134
+ }
135
+ function localeDecimalText(rounded, locale, grouping) {
136
+ let symbols = localeNumberSymbols(locale), wholeText = wholeFormatter(locale, grouping).format(rounded.whole), fractionText = Array.from(
137
+ rounded.fraction,
138
+ (digit) => symbols.digits[Number(digit)] ?? digit
139
+ ).join(""), body = fractionText.length > 0 ? `${wholeText}${symbols.decimal}${fractionText}` : wholeText;
140
+ return rounded.negative ? `${symbols.minus}${body}` : body;
141
+ }
142
+ function formatCurrencyAmount(amount, currency, options = {}) {
143
+ let digits = currencyFractionDigits(currency);
144
+ if (digits === null || !currency) return null;
145
+ let text = typeof amount == "number" ? numberToDecimalText(amount) : amount;
146
+ if (text === null) return null;
147
+ let rounded = roundDecimalText(text, digits);
148
+ if (!rounded) return null;
149
+ let locale = options.locale ?? DEFAULT_FORMAT_LOCALE, grouping = options.grouping ?? true;
150
+ return `${getCurrencySymbol(currency.trim().toUpperCase())}${localeDecimalText(rounded, locale, grouping)}`;
151
+ }
80
152
  function formatNumberCompact(value, decimals = 1) {
81
153
  let absValue = Math.abs(value), sign = value < 0 ? "-" : "";
82
154
  return absValue >= 1e9 ? `${sign}${(absValue / 1e9).toFixed(decimals)}B` : absValue >= 1e6 ? `${sign}${(absValue / 1e6).toFixed(decimals)}M` : absValue >= 1e3 ? `${sign}${(absValue / 1e3).toFixed(decimals)}K` : `${sign}${absValue.toFixed(decimals)}`;
83
155
  }
84
- function formatPrice(amount, currency = "GHS", locale = "en-US") {
85
- let numAmount = typeof amount == "string" ? parseFloat(amount) : amount;
86
- if (isNaN(numAmount))
87
- return `${getCurrencySymbol(currency)}0.00`;
88
- let symbol = getCurrencySymbol(currency);
89
- try {
90
- let formatted = new Intl.NumberFormat(locale, {
91
- minimumFractionDigits: 2,
92
- maximumFractionDigits: 2
93
- }).format(numAmount);
94
- return `${symbol}${formatted}`;
95
- } catch {
96
- return `${symbol}${numAmount.toFixed(2)}`;
97
- }
156
+ function formatPrice(amount, currency, locale = DEFAULT_FORMAT_LOCALE) {
157
+ return formatCurrencyAmount(amount, currency, { locale }) ?? PRICE_UNAVAILABLE_LABEL;
98
158
  }
99
- function formatPriceAdjustment(amount, currency = "GHS", locale = "en-US") {
100
- let formatted = formatPrice(Math.abs(amount), currency, locale);
101
- return amount > 0 ? `+${formatted}` : amount < 0 ? `-${formatted}` : formatted;
159
+ function formatPriceAdjustment(amount, currency, locale = DEFAULT_FORMAT_LOCALE) {
160
+ let formatted = formatCurrencyAmount(Math.abs(amount), currency, { locale });
161
+ return formatted === null ? PRICE_UNAVAILABLE_LABEL : amount > 0 ? `+${formatted}` : amount < 0 ? `-${formatted}` : formatted;
102
162
  }
103
- function formatPriceCompact(amount, currency = "GHS", decimals = 1) {
104
- let numAmount = typeof amount == "string" ? parseFloat(amount) : amount;
105
- if (isNaN(numAmount))
106
- return `${getCurrencySymbol(currency)}0`;
107
- let symbol = getCurrencySymbol(currency);
108
- return Math.abs(numAmount) < 1e3 ? `${symbol}${numAmount.toFixed(2)}` : `${symbol}${formatNumberCompact(numAmount, decimals)}`;
163
+ var COMPACT_THRESHOLD = 1e3;
164
+ function formatPriceCompact(amount, currency, decimals = 1) {
165
+ let exact = formatCurrencyAmount(amount, currency);
166
+ if (exact === null || !currency) return PRICE_UNAVAILABLE_LABEL;
167
+ let magnitude = typeof amount == "number" ? amount : Number.parseFloat(amount);
168
+ return Math.abs(magnitude) < (1e3) ? exact : `${getCurrencySymbol(currency.trim().toUpperCase())}${formatNumberCompact(magnitude, decimals)}`;
109
169
  }
110
- function formatMoney(amount, currency = "GHS") {
111
- let symbol = getCurrencySymbol(currency), numAmount = typeof amount == "string" ? parseFloat(amount) : amount;
112
- return isNaN(numAmount) ? `${symbol}0.00` : `${symbol}${numAmount.toFixed(2)}`;
170
+ function formatMoney(amount, currency) {
171
+ return formatCurrencyAmount(amount, currency, { grouping: false }) ?? PRICE_UNAVAILABLE_LABEL;
113
172
  }
114
173
  function parsePrice(value) {
115
174
  if (value == null)
@@ -137,9 +196,9 @@ function getTaxAmount(priceInfo) {
137
196
  function isTaxInclusive(priceInfo) {
138
197
  return priceInfo.tax_info?.is_inclusive === true;
139
198
  }
140
- function formatPriceWithTax(priceInfo, currency = "GHS") {
141
- let finalPrice = formatPrice(priceInfo.final_price, currency);
142
- return hasTaxInfo(priceInfo) ? isTaxInclusive(priceInfo) ? `${finalPrice} (incl. tax)` : `${finalPrice} + ${formatPrice(getTaxAmount(priceInfo), currency)} tax` : finalPrice;
199
+ function formatPriceWithTax(priceInfo, currency) {
200
+ let finalPrice = formatCurrencyAmount(priceInfo.final_price, currency);
201
+ return finalPrice === null ? PRICE_UNAVAILABLE_LABEL : hasTaxInfo(priceInfo) ? isTaxInclusive(priceInfo) ? `${finalPrice} (incl. tax)` : `${finalPrice} + ${formatPrice(getTaxAmount(priceInfo), currency)} tax` : finalPrice;
143
202
  }
144
203
  function getDisplayPrice(product) {
145
204
  return product.sale ? parsePrice(product.sale.price) : product.price_info ? parsePrice(product.price_info.final_price) : product.final_price !== void 0 && product.final_price !== null ? parsePrice(product.final_price) : product.default_price !== void 0 && product.default_price !== null ? parsePrice(product.default_price) : 0;
@@ -157,18 +216,17 @@ function getDiscountPercentage(product) {
157
216
  if (product.sale)
158
217
  return parsePrice(product.sale.percent_off);
159
218
  let basePrice = getBasePrice(product), finalPrice = getDisplayPrice(product);
160
- return basePrice > finalPrice && basePrice > 0 ? Math.round((basePrice - finalPrice) / basePrice * 100) : 0;
219
+ return basePrice > finalPrice && basePrice > 0 ? Math.round((basePrice - finalPrice) / basePrice * (100)) : 0;
161
220
  }
162
221
  function getMarkupPercentage(product) {
163
222
  let basePrice = getBasePrice(product), finalPrice = getDisplayPrice(product);
164
- return finalPrice > basePrice && basePrice > 0 ? Math.round((finalPrice - basePrice) / basePrice * 100) : 0;
223
+ return finalPrice > basePrice && basePrice > 0 ? Math.round((finalPrice - basePrice) / basePrice * (100)) : 0;
165
224
  }
166
225
  function getProductCurrency(product) {
167
- return product.price_info?.currency ? product.price_info.currency : product.currency ? product.currency : "GHS";
226
+ return product.price_info?.currency || product.currency || void 0;
168
227
  }
169
- function formatProductPrice(product, locale = "en-US") {
170
- let price = getDisplayPrice(product), currency = getProductCurrency(product);
171
- return formatPrice(price, currency, locale);
228
+ function formatProductPrice(product, locale = DEFAULT_FORMAT_LOCALE) {
229
+ return formatPrice(getDisplayPrice(product), getProductCurrency(product), locale);
172
230
  }
173
231
  function getUnitPriceAtQuantity(tiers, quantity, fallback) {
174
232
  let sorted = [...tiers].sort((a, b) => a.min_quantity - b.min_quantity), matched;
@@ -189,8 +247,9 @@ function getPriceRange(product) {
189
247
  }
190
248
  return null;
191
249
  }
192
- function formatPriceRange(min, max, currency = "GHS") {
193
- return `${formatPrice(min, currency)} \u2013 ${formatPrice(max, currency)}`;
250
+ function formatPriceRange(min, max, currency) {
251
+ let low = formatCurrencyAmount(min, currency), high = formatCurrencyAmount(max, currency);
252
+ return low === null || high === null ? PRICE_UNAVAILABLE_LABEL : `${low} \u2013 ${high}`;
194
253
  }
195
254
 
196
255
  // src/utils/payment.ts
@@ -344,7 +403,7 @@ function normalizeStatusResponse(response) {
344
403
  currency: "",
345
404
  message: "No status available"
346
405
  };
347
- let res = response, normalizedStatus = normalizePaymentStatusValue(res.status ?? void 0), normalizedAmount = typeof res.amount == "string" ? chunkUCR5HRYM_js.money(res.amount) : typeof res.amount == "number" && Number.isFinite(res.amount) ? res.amount : 0, normalizedCurrency = typeof res.currency == "string" && res.currency.trim().length > 0 ? res.currency : "", derivedPaid = res.paid === true && normalizedStatus !== "authorized" && !PAYMENT_REQUIRES_ACTION_STATUSES.has(normalizedStatus) && !PAYMENT_FAILURE_STATUSES.has(normalizedStatus) || PAYMENT_SUCCESS_STATUSES.has(normalizedStatus);
406
+ let res = response, normalizedStatus = normalizePaymentStatusValue(res.status ?? void 0), normalizedAmount = typeof res.amount == "string" ? chunkNFXCKTE2_js.money(res.amount) : typeof res.amount == "number" && Number.isFinite(res.amount) ? res.amount : 0, normalizedCurrency = typeof res.currency == "string" && res.currency.trim().length > 0 ? res.currency : "", derivedPaid = res.paid === true && normalizedStatus !== "authorized" && !PAYMENT_REQUIRES_ACTION_STATUSES.has(normalizedStatus) && !PAYMENT_FAILURE_STATUSES.has(normalizedStatus) || PAYMENT_SUCCESS_STATUSES.has(normalizedStatus);
348
407
  return {
349
408
  status: normalizedStatus,
350
409
  paid: derivedPaid,
@@ -379,9 +438,9 @@ function canonicalMobileMoneyProvider(provider) {
379
438
  return MOBILE_MONEY_PROVIDER_ALIASES[normalized] ?? null;
380
439
  }
381
440
  var PURCHASE_INTENT_NETWORK_BY_PROVIDER = {
382
- mtn: chunkUCR5HRYM_js.PURCHASE_INTENT_MOBILE_MONEY_NETWORK.MTN,
383
- telecel: chunkUCR5HRYM_js.PURCHASE_INTENT_MOBILE_MONEY_NETWORK.TELECEL,
384
- airteltigo: chunkUCR5HRYM_js.PURCHASE_INTENT_MOBILE_MONEY_NETWORK.AIRTEL
441
+ mtn: chunkNFXCKTE2_js.PURCHASE_INTENT_MOBILE_MONEY_NETWORK.MTN,
442
+ telecel: chunkNFXCKTE2_js.PURCHASE_INTENT_MOBILE_MONEY_NETWORK.TELECEL,
443
+ airteltigo: chunkNFXCKTE2_js.PURCHASE_INTENT_MOBILE_MONEY_NETWORK.AIRTEL
385
444
  };
386
445
  function purchaseIntentMobileMoneyNetwork(provider) {
387
446
  let canonical = canonicalMobileMoneyProvider(provider);
@@ -409,9 +468,12 @@ function detectMobileMoneyProvider(phoneNumber) {
409
468
  exports.CURRENCY_SYMBOLS = CURRENCY_SYMBOLS;
410
469
  exports.MOBILE_MONEY_PROVIDERS = MOBILE_MONEY_PROVIDERS;
411
470
  exports.PAYMENT_TERMINAL_FAILURE_STATUSES = PAYMENT_TERMINAL_FAILURE_STATUSES;
471
+ exports.PRICE_UNAVAILABLE_LABEL = PRICE_UNAVAILABLE_LABEL;
412
472
  exports.canonicalMobileMoneyProvider = canonicalMobileMoneyProvider;
413
473
  exports.categorizePaymentError = categorizePaymentError;
474
+ exports.currencyFractionDigits = currencyFractionDigits;
414
475
  exports.detectMobileMoneyProvider = detectMobileMoneyProvider;
476
+ exports.formatCurrencyAmount = formatCurrencyAmount;
415
477
  exports.formatMoney = formatMoney;
416
478
  exports.formatNumberCompact = formatNumberCompact;
417
479
  exports.formatPrice = formatPrice;
@@ -441,3 +503,4 @@ exports.normalizeStatusResponse = normalizeStatusResponse;
441
503
  exports.parsePrice = parsePrice;
442
504
  exports.paymentAuthorizationUrl = paymentAuthorizationUrl;
443
505
  exports.purchaseIntentMobileMoneyNetwork = purchaseIntentMobileMoneyNetwork;
506
+ exports.roundToCurrencyDigits = roundToCurrencyDigits;
@@ -1,7 +1,7 @@
1
1
  import { SHOPPER_RESCHEDULE_TYPE } from './chunk-76L2V6KD.mjs';
2
2
  import { messagePreview } from './chunk-SWX4SALA.mjs';
3
- import { AUTHORIZATION_TYPE, CHECKOUT_ORDER_RESULT_STATUS, CHECKOUT_NEXT_ACTION, PAYMENT_METHOD, DEFAULT_CURRENCY } from './chunk-E6QQKDNE.mjs';
4
- import { CHECKOUT_PROTECTION_STATUS, PURCHASE_INTENT_MOBILE_MONEY_NETWORK, ErrorCode, PURCHASE_INTENT_CONFIRM_STATUS, PURCHASE_INTENT_STATUS, PAYMENT_OPTION_STATUS, CHECKOUT_TERMS_COMPONENT, CHECKOUT_TERMS_DELTA_KIND, CHECKOUT_INVALIDATION_REASON, PURCHASE_INTENT_SOURCE_KIND, SOURCE_REFUSAL, PURCHASE_INTENT_PAYMENT_METHOD, PURCHASE_INTENT_PAYMENT_PROVIDER, currencyCode, PURCHASE_INTENT_LINE_CONFIGURATION_KIND, PURCHASE_INTENT_SELLABLE_KIND, PURCHASING_PRINCIPAL_KIND, LEGACY_CHECKOUT_PAYMENT_STATUS, CHECKOUT_COMPLIANCE_REASON, CHECKOUT_COMPLIANCE_LANE, MOBILE_MONEY_TENDER_AUTHORITY_KIND, PAYMENT_OPTION_NEXT_ACTION, PAYMENT_COLLECTION_MODE } from './chunk-GCKWKLZF.mjs';
3
+ import { AUTHORIZATION_TYPE, CHECKOUT_ORDER_RESULT_STATUS, CHECKOUT_NEXT_ACTION, PAYMENT_METHOD } from './chunk-E6QQKDNE.mjs';
4
+ import { CHECKOUT_PROTECTION_STATUS, PURCHASE_INTENT_MOBILE_MONEY_NETWORK, ErrorCode, PURCHASE_INTENT_CONFIRM_STATUS, PURCHASE_INTENT_STATUS, PAYMENT_OPTION_STATUS, CHECKOUT_TERMS_COMPONENT, CHECKOUT_TERMS_DELTA_KIND, CHECKOUT_INVALIDATION_REASON, PURCHASE_INTENT_SOURCE_KIND, SOURCE_REFUSAL, PURCHASE_INTENT_PAYMENT_METHOD, PURCHASE_INTENT_PAYMENT_PROVIDER, currencyCode, PURCHASE_INTENT_LINE_CONFIGURATION_KIND, PURCHASE_INTENT_SELLABLE_KIND, PURCHASING_PRINCIPAL_KIND, LEGACY_CHECKOUT_PAYMENT_STATUS, CHECKOUT_COMPLIANCE_REASON, CHECKOUT_COMPLIANCE_LANE, MOBILE_MONEY_TENDER_AUTHORITY_KIND, PAYMENT_OPTION_NEXT_ACTION, PAYMENT_COLLECTION_MODE } from './chunk-FT6GFYJL.mjs';
5
5
  import { __publicField, __privateAdd, __privateSet, __privateGet, __privateMethod, __privateWrapper } from './chunk-25T4JHEA.mjs';
6
6
 
7
7
  // ../node_modules/.bun/hono@4.13.2/node_modules/hono/dist/compose.js
@@ -1618,7 +1618,7 @@ function getQueryNum(c, key) {
1618
1618
  }
1619
1619
 
1620
1620
  // src/mock/routes/v1.ts
1621
- var PURCHASE_INTENT_ROUTE = {
1621
+ var MOBILE_MONEY_FIXTURE_CURRENCY = "GHS", PURCHASE_INTENT_ROUTE = {
1622
1622
  COLLECTION: "/purchase-intents",
1623
1623
  MEMBER: "/purchase-intents/:intent_id",
1624
1624
  REFRESH: "/purchase-intents/:intent_id/refresh",
@@ -1916,7 +1916,7 @@ function buildV1(deps) {
1916
1916
  let currency = c.req.query("currency")?.trim().toUpperCase();
1917
1917
  return !currency || !/^[A-Z]{3}$/.test(currency) ? fail(c, validation("currency must be a canonical three-letter code")) : tryRoute(c, () => ({
1918
1918
  presentment_currency: currency,
1919
- options: currency === DEFAULT_CURRENCY ? [
1919
+ options: currency === MOBILE_MONEY_FIXTURE_CURRENCY ? [
1920
1920
  { method: PAYMENT_METHOD.CARD, network: null },
1921
1921
  {
1922
1922
  method: PAYMENT_METHOD.MOBILE_MONEY,
@@ -7755,10 +7755,10 @@ function seedRetail(registry) {
7755
7755
  updated_at: ISO5
7756
7756
  };
7757
7757
  registry.variantAxes.put(ramAxis.id, ramAxis), registry.variantAxes.put(ssdAxis.id, ssdAxis);
7758
- let ramAdj = { 16: "0.00", 32: "2500.00" }, ssdAdj = { 512: "0.00", "1tb": "1500.00", "2tb": "3500.00" }, laptopVariantIds = [], firstLaptop = true;
7758
+ let ramAdjWhole = { 16: 0, 32: 2500 }, ssdAdjWhole = { 512: 0, "1tb": 1500, "2tb": 3500 }, laptopVariantIds = [], firstLaptop = true;
7759
7759
  for (let r of ramAxis.values)
7760
7760
  for (let s of ssdAxis.values) {
7761
- let ramKey = r.id.replace("axv_ram_", ""), ssdKey = s.id.replace("axv_ssd_", ""), id = `var_laptop_${ramKey}_${ssdKey}`, adj = (parseFloat(ramAdj[ramKey] ?? "0") + parseFloat(ssdAdj[ssdKey] ?? "0")).toFixed(2), variant = {
7761
+ let ramKey = r.id.replace("axv_ram_", ""), ssdKey = s.id.replace("axv_ssd_", ""), id = `var_laptop_${ramKey}_${ssdKey}`, adj = `${(ramAdjWhole[ramKey] ?? 0) + (ssdAdjWhole[ssdKey] ?? 0)}.00`, variant = {
7762
7762
  id,
7763
7763
  product_id: "prod_laptop-pro",
7764
7764
  business_id: businessId,
@@ -9964,7 +9964,7 @@ var SEED_ISO = "2026-01-01T00:00:00.000Z", ID_PREFIX = {
9964
9964
  collection: "col_",
9965
9965
  product: "prod_",
9966
9966
  service: "svc_"
9967
- }, DEFAULT_CURRENCY2 = "GHS";
9967
+ }, SEED_BUSINESS_CURRENCY = "GHS";
9968
9968
  function slugify(value) {
9969
9969
  return value.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
9970
9970
  }
@@ -9988,7 +9988,7 @@ function makeSeedContext(registry) {
9988
9988
  let handle = input.handle ?? slugify(input.name), id = `${ID_PREFIX.business}${slugify(handle)}`, business = {
9989
9989
  business_type: "other",
9990
9990
  email: `hello@${handle}.test`,
9991
- default_currency: DEFAULT_CURRENCY2,
9991
+ default_currency: SEED_BUSINESS_CURRENCY,
9992
9992
  default_offers_table_service: false,
9993
9993
  default_accepts_online_orders: true,
9994
9994
  status: "active",
@@ -1,6 +1,6 @@
1
1
  import { messagePreview } from './chunk-SWX4SALA.mjs';
2
- import { ok, err, safe, generateIdempotencyKey, SESSION_CLEARED, SESSION_CLAIMED, createClientEvents, createDefaultPaymentAuthorizationAdapterRegistry, AUTH_TOKEN_CHANGED, CatalogueQueries, CartOperations, CheckoutService, OrderQueries, LinkService, AuthService, BusinessService, InventoryService, SchedulingService, LiteService, FxService, createElements } from './chunk-A36JRXXH.mjs';
3
- import { ErrorCode, PURCHASE_INTENT_CONFIRM_STATUS, PURCHASE_INTENT_RESOLVE_STATUS, PURCHASE_INTENT_RESOLUTION_KIND, CimplifyError, PURCHASE_INTENT_ERROR_CODE, PURCHASE_INTENT_ACTION_DECISION, enrichError, IdempotencyMismatchError } from './chunk-GCKWKLZF.mjs';
2
+ import { ok, err, safe, generateIdempotencyKey, SESSION_CLEARED, SESSION_CLAIMED, createClientEvents, createDefaultPaymentAuthorizationAdapterRegistry, AUTH_TOKEN_CHANGED, CatalogueQueries, CartOperations, CheckoutService, OrderQueries, LinkService, AuthService, BusinessService, InventoryService, SchedulingService, LiteService, FxService, createElements } from './chunk-KWZHIPRN.mjs';
3
+ import { ErrorCode, PURCHASE_INTENT_CONFIRM_STATUS, PURCHASE_INTENT_RESOLVE_STATUS, PURCHASE_INTENT_RESOLUTION_KIND, CimplifyError, PURCHASE_INTENT_ERROR_CODE, PURCHASE_INTENT_ACTION_DECISION, enrichError, IdempotencyMismatchError } from './chunk-FT6GFYJL.mjs';
4
4
  import { sha256 } from '@noble/hashes/sha2.js';
5
5
 
6
6
  // src/types/observability.ts
@@ -1,5 +1,5 @@
1
- import { C as CimplifyClient } from './catalogue-OTuS5zp-.js';
2
- import { A as AppHandle, C as CreateAppOptions } from './server-D29IIuDV.js';
1
+ import { C as CimplifyClient } from './catalogue-1QcoGDO6.js';
2
+ import { A as AppHandle, C as CreateAppOptions } from './server-BiKwxvnf.js';
3
3
 
4
4
  /**
5
5
  * Test client + fixtures.
@@ -1,5 +1,5 @@
1
- import { C as CimplifyClient } from './catalogue-CPTMyBUz.mjs';
2
- import { A as AppHandle, C as CreateAppOptions } from './server-DQMWPnc8.mjs';
1
+ import { C as CimplifyClient } from './catalogue-FdFQiWrU.mjs';
2
+ import { A as AppHandle, C as CreateAppOptions } from './server-DPdtl2dd.mjs';
3
3
 
4
4
  /**
5
5
  * Test client + fixtures.
@@ -2,10 +2,16 @@ declare const __money: unique symbol;
2
2
  type Money = (string | number) & {
3
3
  readonly [__money]: true;
4
4
  };
5
+ /**
6
+ * @deprecated Parses a string through a float and turns unreadable text into 0.
7
+ * Keep wire money as the decimal string the API sent, and use
8
+ * `moneyFromNumber` for a value you computed.
9
+ */
5
10
  declare function money(value: string | number): Money;
6
11
  declare function moneyFromNumber(value: number): Money;
7
12
  declare const ZERO: Money;
8
- type CurrencyCode = "USD" | "EUR" | "GBP" | "JPY" | "CNY" | "CHF" | "CAD" | "AUD" | "GHS" | "NGN" | "KES" | "ZAR" | "XOF" | "XAF" | "EGP" | "TZS" | "UGX" | "RWF" | "ETB" | "ZMW" | "BWP" | "MUR" | "NAD" | "MWK" | "AOA" | "CDF" | "GMD" | "GNF" | "LRD" | "SLL" | "MZN" | "BIF" | "INR" | "BRL" | "COP" | "MXN" | "KRW" | "TRY" | "THB" | "MYR" | "PHP" | "IDR" | "VND" | "SGD" | "HKD" | "TWD" | "AED" | "SAR" | "ILS";
13
+ declare const CURRENCY_CODES: readonly ["USD", "EUR", "GBP", "JPY", "CNY", "CHF", "CAD", "AUD", "GHS", "NGN", "KES", "ZAR", "XOF", "XAF", "EGP", "TZS", "UGX", "RWF", "ETB", "ZMW", "BWP", "MUR", "NAD", "MWK", "AOA", "CDF", "GMD", "GNF", "LRD", "SLL", "MZN", "BIF", "INR", "BRL", "COP", "MXN", "KRW", "TRY", "THB", "MYR", "PHP", "IDR", "VND", "SGD", "HKD", "TWD", "AED", "SAR", "ILS", "BHD", "IQD", "JOD", "KWD", "LYD", "OMR", "TND", "CLP", "DJF", "ISK", "KMF", "PYG", "VUV", "XPF"];
14
+ type CurrencyCode = (typeof CURRENCY_CODES)[number];
9
15
  declare function isSupportedCurrency(code: string): code is CurrencyCode;
10
16
  declare function currencyCode(value: string): CurrencyCode;
11
17
  interface PaginationParams {
@@ -370,6 +376,13 @@ interface components {
370
376
  };
371
377
  /** @enum {string} */
372
378
  AgentFactKind: "shop_hours" | "public_products" | "customer_order_statuses" | "named_delivery_estimates";
379
+ /**
380
+ * @description Why an order cannot be amended, judged from the order alone. The amend
381
+ * command enforces this first, then refuses an order whose money already
382
+ * left through a refund, dispute or tax adjustment recorded elsewhere.
383
+ * @enum {string}
384
+ */
385
+ AmendmentRefusal: "draft" | "order_closed" | "return_or_credit_note_required" | "source_revision_required" | "contract_revision_required" | "deposit_balance_revision_required";
373
386
  AmountToPay: {
374
387
  customer_pays: string;
375
388
  business_receives: string;
@@ -3217,6 +3230,11 @@ interface components {
3217
3230
  user_friendly_id: string;
3218
3231
  business_id: string;
3219
3232
  order_type: string;
3233
+ /**
3234
+ * @description The currency the order was taken in, ISO 4217. Every amount on the
3235
+ * order is in it; it is the order's own, never the business default.
3236
+ */
3237
+ currency: string;
3220
3238
  origin: components["schemas"]["Origin"];
3221
3239
  status: components["schemas"]["OrderStatus"];
3222
3240
  lifecycle_phase: components["schemas"]["LifecyclePhase"];
@@ -3240,6 +3258,7 @@ interface components {
3240
3258
  * and line states so clients never re-derive the state machine.
3241
3259
  */
3242
3260
  available_dispositions?: components["schemas"]["OrderDisposition"][];
3261
+ amendment_refusal?: null | components["schemas"]["AmendmentRefusal"];
3243
3262
  bill_token?: string | null;
3244
3263
  tracking_token?: string | null;
3245
3264
  tracking_link?: string | null;
@@ -4338,6 +4357,8 @@ interface components {
4338
4357
  modified_by: string;
4339
4358
  };
4340
4359
  OrderPricingView: {
4360
+ /** @description The currency of every amount here: the order's own, ISO 4217. */
4361
+ currency: string;
4341
4362
  total_price: string;
4342
4363
  subtotal: string;
4343
4364
  total_discount: string;
@@ -8741,6 +8762,11 @@ declare const PAYMENT_MUTATION: {
8741
8762
  declare const ORDER_MUTATION: {
8742
8763
  readonly UPDATE_CUSTOMER: "order.update_order_customer";
8743
8764
  };
8765
+ /**
8766
+ * @deprecated A storefront has no default currency. Read it from the business
8767
+ * (`useCimplify().baseCurrency`, `business.default_currency`) or from the cart,
8768
+ * order or product record. The SDK no longer uses this value anywhere.
8769
+ */
8744
8770
  declare const DEFAULT_CURRENCY = "GHS";
8745
8771
  declare const DEFAULT_COUNTRY = "GHA";
8746
8772
 
@@ -2,10 +2,16 @@ declare const __money: unique symbol;
2
2
  type Money = (string | number) & {
3
3
  readonly [__money]: true;
4
4
  };
5
+ /**
6
+ * @deprecated Parses a string through a float and turns unreadable text into 0.
7
+ * Keep wire money as the decimal string the API sent, and use
8
+ * `moneyFromNumber` for a value you computed.
9
+ */
5
10
  declare function money(value: string | number): Money;
6
11
  declare function moneyFromNumber(value: number): Money;
7
12
  declare const ZERO: Money;
8
- type CurrencyCode = "USD" | "EUR" | "GBP" | "JPY" | "CNY" | "CHF" | "CAD" | "AUD" | "GHS" | "NGN" | "KES" | "ZAR" | "XOF" | "XAF" | "EGP" | "TZS" | "UGX" | "RWF" | "ETB" | "ZMW" | "BWP" | "MUR" | "NAD" | "MWK" | "AOA" | "CDF" | "GMD" | "GNF" | "LRD" | "SLL" | "MZN" | "BIF" | "INR" | "BRL" | "COP" | "MXN" | "KRW" | "TRY" | "THB" | "MYR" | "PHP" | "IDR" | "VND" | "SGD" | "HKD" | "TWD" | "AED" | "SAR" | "ILS";
13
+ declare const CURRENCY_CODES: readonly ["USD", "EUR", "GBP", "JPY", "CNY", "CHF", "CAD", "AUD", "GHS", "NGN", "KES", "ZAR", "XOF", "XAF", "EGP", "TZS", "UGX", "RWF", "ETB", "ZMW", "BWP", "MUR", "NAD", "MWK", "AOA", "CDF", "GMD", "GNF", "LRD", "SLL", "MZN", "BIF", "INR", "BRL", "COP", "MXN", "KRW", "TRY", "THB", "MYR", "PHP", "IDR", "VND", "SGD", "HKD", "TWD", "AED", "SAR", "ILS", "BHD", "IQD", "JOD", "KWD", "LYD", "OMR", "TND", "CLP", "DJF", "ISK", "KMF", "PYG", "VUV", "XPF"];
14
+ type CurrencyCode = (typeof CURRENCY_CODES)[number];
9
15
  declare function isSupportedCurrency(code: string): code is CurrencyCode;
10
16
  declare function currencyCode(value: string): CurrencyCode;
11
17
  interface PaginationParams {
@@ -370,6 +376,13 @@ interface components {
370
376
  };
371
377
  /** @enum {string} */
372
378
  AgentFactKind: "shop_hours" | "public_products" | "customer_order_statuses" | "named_delivery_estimates";
379
+ /**
380
+ * @description Why an order cannot be amended, judged from the order alone. The amend
381
+ * command enforces this first, then refuses an order whose money already
382
+ * left through a refund, dispute or tax adjustment recorded elsewhere.
383
+ * @enum {string}
384
+ */
385
+ AmendmentRefusal: "draft" | "order_closed" | "return_or_credit_note_required" | "source_revision_required" | "contract_revision_required" | "deposit_balance_revision_required";
373
386
  AmountToPay: {
374
387
  customer_pays: string;
375
388
  business_receives: string;
@@ -3217,6 +3230,11 @@ interface components {
3217
3230
  user_friendly_id: string;
3218
3231
  business_id: string;
3219
3232
  order_type: string;
3233
+ /**
3234
+ * @description The currency the order was taken in, ISO 4217. Every amount on the
3235
+ * order is in it; it is the order's own, never the business default.
3236
+ */
3237
+ currency: string;
3220
3238
  origin: components["schemas"]["Origin"];
3221
3239
  status: components["schemas"]["OrderStatus"];
3222
3240
  lifecycle_phase: components["schemas"]["LifecyclePhase"];
@@ -3240,6 +3258,7 @@ interface components {
3240
3258
  * and line states so clients never re-derive the state machine.
3241
3259
  */
3242
3260
  available_dispositions?: components["schemas"]["OrderDisposition"][];
3261
+ amendment_refusal?: null | components["schemas"]["AmendmentRefusal"];
3243
3262
  bill_token?: string | null;
3244
3263
  tracking_token?: string | null;
3245
3264
  tracking_link?: string | null;
@@ -4338,6 +4357,8 @@ interface components {
4338
4357
  modified_by: string;
4339
4358
  };
4340
4359
  OrderPricingView: {
4360
+ /** @description The currency of every amount here: the order's own, ISO 4217. */
4361
+ currency: string;
4341
4362
  total_price: string;
4342
4363
  subtotal: string;
4343
4364
  total_discount: string;
@@ -8741,6 +8762,11 @@ declare const PAYMENT_MUTATION: {
8741
8762
  declare const ORDER_MUTATION: {
8742
8763
  readonly UPDATE_CUSTOMER: "order.update_order_customer";
8743
8764
  };
8765
+ /**
8766
+ * @deprecated A storefront has no default currency. Read it from the business
8767
+ * (`useCimplify().baseCurrency`, `business.default_currency`) or from the cart,
8768
+ * order or product record. The SDK no longer uses this value anywhere.
8769
+ */
8744
8770
  declare const DEFAULT_CURRENCY = "GHS";
8745
8771
  declare const DEFAULT_COUNTRY = "GHA";
8746
8772
 
@@ -0,0 +1,153 @@
1
+ import { C as CurrencyCode, M as Money, dL as PricePathTaxInfo, P as Product, f as ProductWithDetails, el as QuantityPricingTier, cN as MobileMoneyProvider, dq as PaymentErrorDetails, dA as PaymentResponse, dC as PaymentStatusResponse, ea as PurchaseIntentMobileMoneyNetwork } from './elements-ss9xZgRg.mjs';
2
+ import { P as ProductWithPrice } from './price-B-w4PwHm.mjs';
3
+ import { CountryCode } from 'libphonenumber-js';
4
+
5
+ declare const CURRENCY_SYMBOLS: Record<string, string>;
6
+ declare function getCurrencySymbol(currencyCode: CurrencyCode | string): string;
7
+ /**
8
+ * The text every price formatter returns when it cannot know the currency or
9
+ * read the amount. The SDK never guesses a currency: render a loading or
10
+ * unavailable state instead of a price in the wrong money.
11
+ */
12
+ declare const PRICE_UNAVAILABLE_LABEL = "Price unavailable";
13
+ /**
14
+ * The number of minor-unit digits a currency uses (0 for XOF or JPY, 2 for
15
+ * USD or GHS, 3 for KWD or BHD). The table mirrors the platform money
16
+ * kernel's ISO 4217 exponents, so the storefront rounds exactly as the server
17
+ * prices. Returns null for a missing or malformed currency code.
18
+ */
19
+ declare function currencyFractionDigits(currency: string | null | undefined): number | null;
20
+ interface FormatCurrencyAmountOptions {
21
+ /** BCP 47 locale for digit grouping and the decimal mark. Default "en-US". */
22
+ locale?: string;
23
+ /** Group thousands. Default true. */
24
+ grouping?: boolean;
25
+ }
26
+ /**
27
+ * The one money formatter every SDK price path uses. It writes the currency
28
+ * symbol and the amount rounded half-up to the currency's own minor unit
29
+ * (0 digits for XOF, 2 for GHS, 3 for KWD). Decimal strings are rounded
30
+ * exactly, with no float drift. Returns null when the currency is missing or
31
+ * malformed or the amount is not a plain decimal, so callers render an
32
+ * unavailable state instead of a guess.
33
+ */
34
+ declare function formatCurrencyAmount(amount: number | string, currency: CurrencyCode | string | null | undefined, options?: FormatCurrencyAmountOptions): string | null;
35
+ declare function formatNumberCompact(value: number, decimals?: number): string;
36
+ /**
37
+ * Format an amount in its currency with the currency's own decimals and
38
+ * thousands grouping, e.g. `$1,234.50`, `CFA12,500`, `KWD1.250`.
39
+ *
40
+ * `currency` is optional only for source compatibility. The SDK never guesses
41
+ * one: without a currency, or with an amount that is not a plain number or
42
+ * decimal string, this returns {@link PRICE_UNAVAILABLE_LABEL}.
43
+ */
44
+ declare function formatPrice(amount: number | string | Money, currency?: CurrencyCode | string | null, locale?: string): string;
45
+ /**
46
+ * Format a signed price change, e.g. `+$2.00` or `-CFA500`. Returns
47
+ * {@link PRICE_UNAVAILABLE_LABEL} without a currency.
48
+ */
49
+ declare function formatPriceAdjustment(amount: number, currency?: CurrencyCode | string | null, locale?: string): string;
50
+ /**
51
+ * Format a price compactly: amounts under 1,000 keep the currency's decimals,
52
+ * larger ones use K, M and B. Returns {@link PRICE_UNAVAILABLE_LABEL} without a
53
+ * currency.
54
+ */
55
+ declare function formatPriceCompact(amount: number | string | Money, currency?: CurrencyCode | string | null, decimals?: number): string;
56
+ /**
57
+ * Format an amount in its currency without thousands grouping, e.g.
58
+ * `GH₵1234.50` or `CFA12500`. Returns {@link PRICE_UNAVAILABLE_LABEL} without a
59
+ * currency.
60
+ */
61
+ declare function formatMoney(amount: number | string | Money, currency?: CurrencyCode | string | null): string;
62
+ declare function parsePrice(value: Money | string | number | undefined | null): number;
63
+ declare function hasTaxInfo(priceInfo: {
64
+ tax_info?: PricePathTaxInfo;
65
+ }): boolean;
66
+ declare function getTaxAmount(priceInfo: {
67
+ tax_info?: PricePathTaxInfo;
68
+ }): number;
69
+ declare function isTaxInclusive(priceInfo: {
70
+ tax_info?: PricePathTaxInfo;
71
+ }): boolean;
72
+ /**
73
+ * Format a price with its tax note, e.g. `$10.50 (incl. tax)`. Returns
74
+ * {@link PRICE_UNAVAILABLE_LABEL} without a currency.
75
+ */
76
+ declare function formatPriceWithTax(priceInfo: {
77
+ final_price: Money;
78
+ tax_info?: PricePathTaxInfo;
79
+ }, currency?: CurrencyCode | string | null): string;
80
+ declare function getDisplayPrice(product: ProductWithPrice): number;
81
+ declare function getBasePrice(product: ProductWithPrice): number;
82
+ declare function isOnSale(product: ProductWithPrice): boolean;
83
+ declare function getDiscountPercentage(product: ProductWithPrice): number;
84
+ declare function getMarkupPercentage(product: ProductWithPrice): number;
85
+ /**
86
+ * The currency a product is priced in, from its price path or its own
87
+ * `currency`. Returns undefined when the payload carries neither; the SDK
88
+ * never substitutes a default.
89
+ */
90
+ declare function getProductCurrency(product: ProductWithPrice): CurrencyCode | undefined;
91
+ /**
92
+ * Format a product's display price in the product's currency. Returns
93
+ * {@link PRICE_UNAVAILABLE_LABEL} when the product carries no currency.
94
+ */
95
+ declare function formatProductPrice(product: ProductWithPrice, locale?: string): string;
96
+ declare function getUnitPriceAtQuantity(tiers: QuantityPricingTier[], quantity: number, fallback: number): number;
97
+ declare function getPriceRange(product: Product | ProductWithDetails): {
98
+ min: number;
99
+ max: number;
100
+ } | null;
101
+ /**
102
+ * Format a min to max price range in one currency. Returns
103
+ * {@link PRICE_UNAVAILABLE_LABEL} without a currency.
104
+ */
105
+ declare function formatPriceRange(min: number, max: number, currency?: CurrencyCode | string | null): string;
106
+
107
+ declare function categorizePaymentError(error: Error, errorCode?: string): PaymentErrorDetails;
108
+ declare function normalizePaymentResponse(response: unknown): PaymentResponse;
109
+ declare const PAYMENT_TERMINAL_FAILURE_STATUSES: readonly ["failed", "cancelled", "voided", "abandoned", "refunded", "refund_pending", "reversed", "disputed"];
110
+ declare function isPaymentStatusSuccess(status: string | undefined): boolean;
111
+ declare function isPaymentStatusFailure(status: string | undefined): boolean;
112
+ declare function isPaymentStatusRequiresAction(status: string | undefined): boolean;
113
+ declare function normalizeStatusResponse(response: unknown): PaymentStatusResponse;
114
+ declare const MOBILE_MONEY_PROVIDERS: {
115
+ readonly mtn: {
116
+ readonly name: "MTN Mobile Money";
117
+ readonly prefix: readonly ["024", "025", "053", "054", "055", "059"];
118
+ };
119
+ readonly vodafone: {
120
+ readonly name: "Telecel Cash";
121
+ readonly prefix: readonly ["020", "050"];
122
+ };
123
+ readonly airtel: {
124
+ readonly name: "AirtelTigo Money";
125
+ readonly prefix: readonly ["026", "027", "056", "057"];
126
+ };
127
+ };
128
+ type CanonicalMobileMoneyProvider = Extract<MobileMoneyProvider, "mtn" | "telecel" | "airteltigo" | "mpesa">;
129
+ /** Normalize route-catalog and legacy network aliases to storefront provider codes. */
130
+ declare function canonicalMobileMoneyProvider(provider: string | null | undefined): CanonicalMobileMoneyProvider | null;
131
+ /**
132
+ * Collapse storefront aliases to Checkout's closed durable network vocabulary.
133
+ * M-PESA is deliberately absent until the backend can issue a matching
134
+ * PurchaseIntent payment option.
135
+ */
136
+ declare function purchaseIntentMobileMoneyNetwork(provider: string | null | undefined): PurchaseIntentMobileMoneyNetwork | null;
137
+ /**
138
+ * Validate an external payment-authorization URL before browser navigation.
139
+ * Provider payloads are data, not executable navigation instructions: only
140
+ * HTTPS is accepted outside local development.
141
+ */
142
+ declare function paymentAuthorizationUrl(value: unknown): string | null;
143
+ declare function detectMobileMoneyProvider(phoneNumber: string): "mtn" | "vodafone" | "airtel" | null;
144
+
145
+ interface PhoneNormalizationOptions {
146
+ country?: string | null;
147
+ currency?: string | null;
148
+ }
149
+ declare function resolvePhoneCountryCode(options?: PhoneNormalizationOptions): CountryCode | undefined;
150
+ declare function normalizePhoneToE164(raw: string, options?: PhoneNormalizationOptions): string | null;
151
+ declare function isValidPhoneForContext(raw: string, options?: PhoneNormalizationOptions): boolean;
152
+
153
+ export { isPaymentStatusFailure as A, isPaymentStatusRequiresAction as B, CURRENCY_SYMBOLS as C, isPaymentStatusSuccess as D, isTaxInclusive as E, type FormatCurrencyAmountOptions as F, isValidPhoneForContext as G, normalizePaymentResponse as H, normalizePhoneToE164 as I, normalizeStatusResponse as J, parsePrice as K, paymentAuthorizationUrl as L, MOBILE_MONEY_PROVIDERS as M, purchaseIntentMobileMoneyNetwork as N, resolvePhoneCountryCode as O, PAYMENT_TERMINAL_FAILURE_STATUSES as P, type CanonicalMobileMoneyProvider as a, PRICE_UNAVAILABLE_LABEL as b, canonicalMobileMoneyProvider as c, categorizePaymentError as d, currencyFractionDigits as e, detectMobileMoneyProvider as f, formatCurrencyAmount as g, formatMoney as h, formatNumberCompact as i, formatPrice as j, formatPriceAdjustment as k, formatPriceCompact as l, formatPriceRange as m, formatPriceWithTax as n, formatProductPrice as o, getBasePrice as p, getCurrencySymbol as q, getDiscountPercentage as r, getDisplayPrice as s, getMarkupPercentage as t, getPriceRange as u, getProductCurrency as v, getTaxAmount as w, getUnitPriceAtQuantity as x, hasTaxInfo as y, isOnSale as z };