@amboras-dev/money 0.2.0 → 0.4.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 (78) hide show
  1. package/README.md +22 -11
  2. package/dist/ai.cjs +12 -13
  3. package/dist/ai.d.cts +5 -9
  4. package/dist/ai.d.ts +5 -9
  5. package/dist/ai.js +12 -13
  6. package/dist/{allocate-CZRg4TOP.cjs → allocate-AusholrC.cjs} +3 -4
  7. package/dist/{allocate-X7_jAtOj.js → allocate-BBRfdaSC.js} +3 -4
  8. package/dist/{amount-BV0O-aN8.cjs → amount-Bzxw9aD4.cjs} +32 -14
  9. package/dist/{amount-BoYBMgK9.js → amount-off8IMBJ.js} +32 -14
  10. package/dist/{arithmetic-BhNwisjb.js → arithmetic-C97-YafD.js} +4 -5
  11. package/dist/{arithmetic-DjT4Kzgt.cjs → arithmetic-D8A6IeZ0.cjs} +4 -5
  12. package/dist/billing.cjs +5 -8
  13. package/dist/billing.d.cts +1 -9
  14. package/dist/billing.d.ts +1 -9
  15. package/dist/billing.js +5 -8
  16. package/dist/commerce.cjs +15 -23
  17. package/dist/commerce.d.cts +2 -16
  18. package/dist/commerce.d.ts +2 -16
  19. package/dist/commerce.js +15 -23
  20. package/dist/{format-DLhno7eX.cjs → format-92fzvTXY.cjs} +9 -9
  21. package/dist/{format-BdPnijvn.js → format-BJC513u4.js} +9 -9
  22. package/dist/fx.cjs +12 -18
  23. package/dist/fx.d.cts +5 -15
  24. package/dist/fx.d.ts +5 -15
  25. package/dist/fx.js +12 -18
  26. package/dist/index.cjs +10 -12
  27. package/dist/index.d.cts +17 -23
  28. package/dist/index.d.ts +17 -23
  29. package/dist/index.js +10 -12
  30. package/dist/input.cjs +7 -10
  31. package/dist/input.d.cts +16 -22
  32. package/dist/input.d.ts +16 -22
  33. package/dist/input.js +7 -10
  34. package/dist/{iso-minor-wSwJN57T.cjs → iso-minor-DyNjT9A1.cjs} +2 -3
  35. package/dist/{iso-minor-CqkWDxHS.js → iso-minor-odkY-e6I.js} +2 -3
  36. package/dist/{medusa-lRY9xlsf.cjs → medusa-CzVK0bth.cjs} +3 -4
  37. package/dist/{medusa-DBXJXXvF.d.ts → medusa-DofdvIgQ.d.cts} +1 -3
  38. package/dist/{medusa-4K8N1pUc.d.cts → medusa-DrbYmD2Y.d.ts} +1 -3
  39. package/dist/{medusa-DqJY1qpj.js → medusa-pKGlImn9.js} +3 -4
  40. package/dist/{money-B-3aFjNJ.d.cts → money-BkMeYDEW.d.cts} +0 -6
  41. package/dist/{money-B-3aFjNJ.d.ts → money-BkMeYDEW.d.ts} +0 -6
  42. package/dist/{money-WhnGiI00.js → money-BxbAw7BP.js} +7 -15
  43. package/dist/{money-B3wH_Z4S.cjs → money-DWBjuuEK.cjs} +7 -15
  44. package/dist/{number-text-DE-q4jO5.js → number-text-Bj-gZXiF.js} +3 -4
  45. package/dist/{number-text-BWu67jUq.cjs → number-text-CWuVwrlg.cjs} +3 -4
  46. package/dist/{own-oP9DXFWv.cjs → own-C5imDkyB.cjs} +1 -2
  47. package/dist/{own-D7544D3k.js → own-DHxqIYqL.js} +1 -2
  48. package/dist/{percent-D1VB9xXG.js → percent-CB3Ixjc_.js} +2 -3
  49. package/dist/{percent-C0InC2t2.cjs → percent-DABHiSBs.cjs} +2 -3
  50. package/dist/{rate-DBPiYgT1.d.ts → rate-BvvZUdSu.d.ts} +1 -3
  51. package/dist/{rate-tqK8ijG0.d.cts → rate-CEakW3ia.d.cts} +1 -3
  52. package/dist/{rate-CVeMii4a.cjs → rate-CEjWTATc.cjs} +3 -4
  53. package/dist/{rate-DicStBue.js → rate-D6S2_wgZ.js} +3 -4
  54. package/dist/{reporting-tpGJbqYp.d.ts → reporting-DFNyDBdi.d.cts} +2 -4
  55. package/dist/{reporting-CG-ai2sM.d.cts → reporting-jIBILvnr.d.ts} +2 -4
  56. package/dist/{retail-DRUTTQoJ.d.ts → retail-B04CjW3b.d.ts} +1 -3
  57. package/dist/{retail-Cml8YSKg.cjs → retail-CYGPU4ea.cjs} +4 -5
  58. package/dist/{retail-C_BPLvMj.d.cts → retail-CmEyJQOH.d.cts} +1 -3
  59. package/dist/{retail-1mu888J1.js → retail-DXgs11ov.js} +4 -5
  60. package/dist/{rounding-DHBtNCHG.cjs → rounding-4QKTRbMQ.cjs} +2 -3
  61. package/dist/{rounding-g9rvye0k.js → rounding-CA1PVP3b.js} +2 -3
  62. package/dist/sql.cjs +9 -15
  63. package/dist/sql.d.cts +2 -12
  64. package/dist/sql.d.ts +2 -12
  65. package/dist/sql.js +9 -15
  66. package/dist/testing.cjs +39198 -12
  67. package/dist/testing.d.cts +20 -13
  68. package/dist/testing.d.ts +20 -13
  69. package/dist/testing.js +39198 -13
  70. package/dist/{wire-sW0yzqth.js → wire-B4QU8O3W.js} +350 -93
  71. package/dist/{wire-CaUN9Vf_.d.ts → wire-CVNicirK.d.ts} +165 -46
  72. package/dist/{wire-xjYXv4go.d.cts → wire-CtNJmWVP.d.cts} +165 -46
  73. package/dist/{wire-Bhuut8cW.cjs → wire-u2tmHY0Y.cjs} +403 -92
  74. package/dist/wire.cjs +10 -1
  75. package/dist/wire.d.cts +2 -2
  76. package/dist/wire.d.ts +2 -2
  77. package/dist/wire.js +1 -2
  78. package/package.json +4 -3
@@ -1,32 +1,9 @@
1
- import { $ as describeValue, C as medusaCurrencyCode, Q as MoneyError, X as mulDiv, c as toMajorDecimal, ct as normalizeDecimal, dt as roundToScale, ft as strictNumberDecimal, it as formatDecimal, k as storageExponent, lt as parseDecimal, mt as unitsWithin, n as fromMajor, o as readStored, pt as toDecimalText, rt as divRound, s as storedDecimal, t as boundedMoney, ut as pow10, y as findCurrency } from "./money-WhnGiI00.js";
2
- import { n as allocateUnits } from "./allocate-X7_jAtOj.js";
3
- import { t as hasOwnKey } from "./own-D7544D3k.js";
4
- import { n as isoMinorFactor } from "./iso-minor-CqkWDxHS.js";
5
- import { n as readNumberText } from "./number-text-DE-q4jO5.js";
6
- //#region src/wire/anet.ts
7
- const escapeRegExp = (text) => text.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
8
- /**
9
- * The first `"<field>": <decimal>` (quoted or not) in a raw JSON body, verbatim: `JSON.parse`
10
- * would turn the gateway's `43.00` into `43`. The value is the whole JSON token, held to
11
- * `parseDecimal`'s `'plain'` grammar (`1e3` or `"43.10abc"` is not a decimal literal).
12
- * Undefined when absent; there is no lossy fallback.
13
- */
14
- function jsonDecimalLiteral(rawBody, field) {
15
- if (typeof rawBody !== "string" || typeof field !== "string") return void 0;
16
- const tokens = rawBody.matchAll(new RegExp(`"${escapeRegExp(field)}"\\s*:\\s*("?)([^"\\s,}\\]]+)\\1`, "g"));
17
- for (const [, , token] of tokens) if (parseDecimal(token, "plain")) return token;
18
- }
19
- const isPositiveLiteral = (text) => {
20
- const value = parseDecimal(text.trim());
21
- return value !== null && value.units > 0n;
22
- };
23
- function authorizeNetReversibleAmount(details) {
24
- const settle = details.settleAmount ?? void 0;
25
- if (settle !== void 0 && isPositiveLiteral(settle)) return settle;
26
- return details.authAmount ?? settle;
27
- }
28
- //#endregion
29
- //#region src/data/psp.ts
1
+ import { $ as describeValue, C as medusaCurrencyCode, Q as MoneyError, X as mulDiv, c as toMajorDecimal, ct as normalizeDecimal, dt as roundToScale, et as addDecimal, ft as strictNumberDecimal, it as formatDecimal, k as storageExponent, lt as parseDecimal, mt as unitsWithin, n as fromMajor, o as readStored, pt as toDecimalText, rt as divRound, s as storedDecimal, t as boundedMoney, tt as compareDecimal, ut as pow10, y as findCurrency } from "./money-BxbAw7BP.js";
2
+ import { n as allocateUnits } from "./allocate-BBRfdaSC.js";
3
+ import { t as hasOwnKey } from "./own-DHxqIYqL.js";
4
+ import { n as isoMinorFactor } from "./iso-minor-odkY-e6I.js";
5
+ import { n as readNumberText } from "./number-text-Bj-gZXiF.js";
6
+ // src/data/psp.ts
30
7
  /** developer.paypal.com/reference/currency-codes ("Last updated: August 17, 2026"). */
31
8
  const PAYPAL_CURRENCY_DIGITS = {
32
9
  0: [
@@ -519,15 +496,17 @@ const RAZORPAY_CURRENCY_EXPONENTS = {
519
496
  "TND"
520
497
  ]
521
498
  };
522
- /** Paystack: "If we notice a fractional part during processing, we ignore the fractional part." */
523
- const PAYSTACK_CURRENCY_DIGITS = { 2: [
499
+ /** paystack.com/docs/api/#supported-currency (retrieved 2026-10-07): every currency a Paystack account can charge. */
500
+ const PAYSTACK_CURRENCIES = [
524
501
  "GHS",
525
502
  "KES",
526
503
  "NGN",
527
504
  "USD",
528
505
  "XOF",
529
506
  "ZAR"
530
- ] };
507
+ ];
508
+ /** Paystack: "If we notice a fractional part during processing, we ignore the fractional part." */
509
+ const PAYSTACK_CURRENCY_DIGITS = { 2: PAYSTACK_CURRENCIES };
531
510
  /** Factor-1 overrides: ISO zero-decimal codes the PSP wants at two decimals (storage and wire agree). */
532
511
  const STRIPE_SENT_AS_TWO_DECIMAL = ["ISK", "UGX"];
533
512
  const ADYEN_SENT_AS_TWO_DECIMAL = ["ISK", "CLP"];
@@ -1000,6 +979,101 @@ const AUTHORIZE_NET_CURRENCIES = [
1000
979
  "PLN"
1001
980
  ];
1002
981
  const VND_ONLY = ["VND"];
982
+ /**
983
+ * The account countries a PSP onboards, for PSPs whose accounts each charge a per-country list.
984
+ * Paystack: support.paystack.com/en/articles/2130690 "Enabling international payments for your
985
+ * business" (retrieved 2026-10-26): "Côte d'Ivoire XOF", "Ghana GHS", "Kenya KES, USD", "Nigeria
986
+ * NGN, USD", "South Africa ZAR", and "At the moment, only Kenya and Nigeria-based businesses have
987
+ * the ability to accept payments for their business in USD and be paid out in USD". USD has to be
988
+ * enabled on the account first (the article is how to enable it), and no Paystack API reports
989
+ * whether it is, so USD is `optIn`, never in `currencies`.
990
+ */
991
+ const PSP_ACCOUNT_COUNTRIES = { paystack: {
992
+ CI: { currencies: ["XOF"] },
993
+ GH: { currencies: ["GHS"] },
994
+ KE: {
995
+ currencies: ["KES"],
996
+ optIn: ["USD"]
997
+ },
998
+ NG: {
999
+ currencies: ["NGN"],
1000
+ optIn: ["USD"]
1001
+ },
1002
+ ZA: { currencies: ["ZAR"] }
1003
+ } };
1004
+ /**
1005
+ * The currency every account of a multi-currency PSP charges without enabling anything; any other
1006
+ * needs the account's international or multi-currency add-on. The single-currency PSPs (MoMo,
1007
+ * VNPay, Payoo: `VND_ONLY`) are not restated here: their home currency is their one currency.
1008
+ * Razorpay: razorpay.com/docs/payments/international-payments (retrieved 2026-10-26) says "The final
1009
+ * settlement is done in the bank accounts of Indian businesses in INR", with international
1010
+ * payments activated under Account & Settings, and razorpay.com/docs/sg/payments/international-payments/faqs
1011
+ * (retrieved 2026-10-27): "The Settlement currency is INR (Indian rupees) for all transactions made
1012
+ * using Razorpay". This is the settlement currency only; it says nothing about where the account is
1013
+ * registered (Razorpay has no entry in `PSP_HOME_COUNTRY`). iyzico help centre (quoted in Medusa
1014
+ * `capabilities/iyzico.ts`, 2026-10-07; re-read 2026-10-26): "payments you take in foreign
1015
+ * currencies are exchanged into Turkish Liras", taking them needs the paid Multi Currency add-on.
1016
+ */
1017
+ const PSP_HOME_CURRENCY = {
1018
+ razorpay: "INR",
1019
+ iyzico: "TRY"
1020
+ };
1021
+ /**
1022
+ * The one country every account of a PSP is registered in, for PSPs whose accounts are all
1023
+ * registered in a single country. Razorpay is left out: the same FAQ lists it as available in India,
1024
+ * Malaysia (Curlec), Singapore and the United States, so its accounts are not all registered in one
1025
+ * country, and a Singapore or US account must not read as IN. iyzico: consistent with orch `account-facts.ts`
1026
+ * `PROVIDER_CONSTANT_FACTS` (2026-10-26), which records TR, and with its Turkish-lira settlement
1027
+ * above. MoMo, VNPay, Payoo: domestic Vietnamese rails that take VND only (`VND_ONLY`), carried over
1028
+ * from the same `PROVIDER_CONSTANT_FACTS`.
1029
+ */
1030
+ const PSP_HOME_COUNTRY = {
1031
+ iyzico: "TR",
1032
+ momo: "VN",
1033
+ vnpay: "VN",
1034
+ payoo: "VN"
1035
+ };
1036
+ /**
1037
+ * The currency of a saved-method verification charge when the caller has none, where the PSP
1038
+ * documents one. `only`: the PSP verifies in that currency alone, so any other is refused.
1039
+ * Razorpay: recurring payment orders take a currency where "currently, only INR is allowed"
1040
+ * (razorpay.com/docs/api/payments/recurring-payments/emandate/create-subsequent-payments, retrieved
1041
+ * 2026-10-26), so its verification is INR only. Mollie: docs.mollie.com/docs/multicurrency
1042
+ * (retrieved 2026-10-27) lists EUR as supported by "All payment methods except BACS, Blik, Swish
1043
+ * and Twint", so every card method takes EUR and a card verification can fall back to it. Adyen
1044
+ * and Paystack publish no such currency: Adyen's zero-amount verification takes whatever the
1045
+ * merchant account processes, and a Paystack account charges its own country's currency, so their
1046
+ * callers must pass one.
1047
+ */
1048
+ const VERIFICATION_CURRENCY = {
1049
+ razorpay: {
1050
+ code: "INR",
1051
+ only: true
1052
+ },
1053
+ mollie: {
1054
+ code: "EUR",
1055
+ only: false
1056
+ }
1057
+ };
1058
+ /**
1059
+ * The PSPs whose wire amount Medusa computed in floating point before it adopted 0.2.0: major
1060
+ * units as `(stored / storageScale).toFixed(wireDigits)` on a double (Airwallex and Payoo then
1061
+ * `Number(...)` of that text). Source: Medusa `src/common/money/codec.ts` `majorStringCodec` /
1062
+ * `majorNumberCodec` and `psp-codecs.ts` (staging 785bd0420, 2026-10-27), and the same expression
1063
+ * in each provider's `amount.ts` before that codec existed (`03989fd4e^`). The stored amount was
1064
+ * `Number()` of Medusa's amount, unrounded. At an exact tie the double can sit just below it, so
1065
+ * USD 1072.5 went as `'10.72'` where 0.2.0 sends `'10.73'`; `sameWireAmount`'s
1066
+ * `acceptLegacyFloatRounding` reads that spelling. Payoo is listed because it used the same codec,
1067
+ * but its whole-dong rule leaves it no tie, so its float spelling is always the exact one.
1068
+ */
1069
+ const PSP_LEGACY_FLOAT_TO_FIXED = [
1070
+ "paypal",
1071
+ "mollie",
1072
+ "airwallex",
1073
+ "iyzico",
1074
+ "authorize-net",
1075
+ "payoo"
1076
+ ];
1003
1077
  /** orch `MINIMUM_AMOUNT_BY_CURRENCY`, majors. */
1004
1078
  const PSP_MINIMUM_MAJOR = { paystack: { USD: "2.00" } };
1005
1079
  /** RBI e-mandate AFA-free cap: INR 15,000 (razorpay-vault `15_000_00` paise, seam `1_500_000`). */
@@ -1014,8 +1088,29 @@ const PROVIDER_ONLY_CURRENCIES = { CNH: {
1014
1088
  name: "Chinese Yuan (offshore)",
1015
1089
  psps: ["adyen"]
1016
1090
  } };
1017
- //#endregion
1018
- //#region src/wire/currency.ts
1091
+ // src/wire/anet.ts
1092
+ const escapeRegExp = (text) => text.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
1093
+ /**
1094
+ * The first `"<field>": <decimal>` (quoted or not) in a raw JSON body, verbatim: `JSON.parse`
1095
+ * would turn the gateway's `43.00` into `43`. The value is the whole JSON token, held to
1096
+ * `parseDecimal`'s `'plain'` grammar (`1e3` or `"43.10abc"` is not a decimal literal).
1097
+ * Undefined when absent; there is no lossy fallback.
1098
+ */
1099
+ function jsonDecimalLiteral(rawBody, field) {
1100
+ if (typeof rawBody !== "string" || typeof field !== "string") return void 0;
1101
+ const tokens = rawBody.matchAll(new RegExp(`"${escapeRegExp(field)}"\\s*:\\s*("?)([^"\\s,}\\]]+)\\1`, "g"));
1102
+ for (const [, , token] of tokens) if (parseDecimal(token, "plain")) return token;
1103
+ }
1104
+ const isPositiveLiteral = (text) => {
1105
+ const value = parseDecimal(text.trim());
1106
+ return value !== null && value.units > 0n;
1107
+ };
1108
+ function authorizeNetReversibleAmount(details) {
1109
+ const settle = details.settleAmount ?? void 0;
1110
+ if (settle !== void 0 && isPositiveLiteral(settle)) return settle;
1111
+ return details.authAmount ?? settle;
1112
+ }
1113
+ // src/wire/currency.ts
1019
1114
  /** The registry entry (any case, historic included) for `input`, else null. Never throws. */
1020
1115
  function wireCurrency(input) {
1021
1116
  return findCurrency(input, { allowHistoric: true });
@@ -1070,8 +1165,17 @@ function wireStoredDecimal(m) {
1070
1165
  stored: normalizeDecimal(parsed)
1071
1166
  };
1072
1167
  }
1073
- //#endregion
1074
- //#region src/wire/descriptors.ts
1168
+ // src/wire/descriptors.ts
1169
+ function accountCountries(id) {
1170
+ const table = PSP_ACCOUNT_COUNTRIES[id] ?? {};
1171
+ return new Map(Object.keys(table).map((country) => {
1172
+ const entry = {
1173
+ currencies: new Set(table[country].currencies),
1174
+ optIn: new Set(table[country].optIn ?? [])
1175
+ };
1176
+ return [country, Object.freeze(entry)];
1177
+ }));
1178
+ }
1075
1179
  function digitTable(groups) {
1076
1180
  const table = /* @__PURE__ */ new Map();
1077
1181
  for (const digits of [
@@ -1113,7 +1217,12 @@ function describe(id, input) {
1113
1217
  singleCurrency: input.singleCurrency ?? null,
1114
1218
  unsupported: input.unsupported ?? genericUnsupported(input.tag),
1115
1219
  facadeAccepts: input.facadeAccepts ?? scalesAnyCurrency,
1116
- inboundWholePositive: input.inboundWholePositive ?? false
1220
+ inboundWholePositive: input.inboundWholePositive ?? false,
1221
+ homeCurrency: PSP_HOME_CURRENCY[id] ?? input.singleCurrency ?? null,
1222
+ homeCountry: PSP_HOME_COUNTRY[id] ?? null,
1223
+ accountCountries: accountCountries(id),
1224
+ verificationCurrency: VERIFICATION_CURRENCY[id] ?? null,
1225
+ legacyFloatToFixed: PSP_LEGACY_FLOAT_TO_FIXED.includes(id)
1117
1226
  });
1118
1227
  }
1119
1228
  const notTwoDecimalAtStripe = new Set(STRIPE_NOT_TWO_DECIMAL);
@@ -1266,8 +1375,7 @@ function pspDescriptor(psp) {
1266
1375
  if (typeof psp === "string" && hasOwnKey(PSP_DESCRIPTORS, psp)) return PSP_DESCRIPTORS[psp];
1267
1376
  throw new MoneyError("wire_unsupported", `Unknown payment provider: ${describeValue(psp)}`);
1268
1377
  }
1269
- //#endregion
1270
- //#region src/wire/marker.ts
1378
+ // src/wire/marker.ts
1271
1379
  const WIRE_SCALE_KEY = "amboras_wire_scale";
1272
1380
  const WIRE_SCALE_ISO_MINOR_V2 = "iso-minor-v2";
1273
1381
  const WIRE_SCALE_MARKER = Object.freeze({ [WIRE_SCALE_KEY]: WIRE_SCALE_ISO_MINOR_V2 });
@@ -1286,8 +1394,19 @@ function conventionKind(value) {
1286
1394
  const kind = typeof value === "object" && value !== null ? value.kind : void 0;
1287
1395
  return kind === "iso-minor-v2" || kind === "pre-cutover" ? kind : null;
1288
1396
  }
1289
- //#endregion
1290
- //#region src/wire/codec.ts
1397
+ const WIRE_ROUNDING_KEY = "amboras_wire_rounding";
1398
+ const WIRE_ROUNDING_EXACT = "exact";
1399
+ const WIRE_ROUNDING_MARKER = Object.freeze({ [WIRE_ROUNDING_KEY]: WIRE_ROUNDING_EXACT });
1400
+ /**
1401
+ * Whether a payment may be held at the PSP in Medusa's pre-0.2.0 float spelling: no record is a
1402
+ * non-null object whose `amboras_wire_rounding` is strictly `'exact'`. Pass the result as
1403
+ * `sameWireAmount`'s `acceptLegacyFloatRounding`, so only sessions created before the deploy get
1404
+ * the legacy spelling. Reads already fetched records only.
1405
+ */
1406
+ function mayHoldLegacyFloatRounding(...records) {
1407
+ return !records.some((r) => typeof r === "object" && r !== null && r["amboras_wire_rounding"] === "exact");
1408
+ }
1409
+ // src/wire/codec.ts
1291
1410
  const isBlank = (value) => value === null || value === void 0 || typeof value === "string" && value.trim() === "";
1292
1411
  const shownCode = (currency) => typeof currency === "string" ? currency.trim().toUpperCase() : describeValue(currency);
1293
1412
  function missingCurrency(d) {
@@ -1318,7 +1437,8 @@ function pspCurrencies(psp) {
1318
1437
  /**
1319
1438
  * `currency` as a CurrencyCode `psp` takes. Empty throws `currency_missing` (`[<Tag>] Cannot
1320
1439
  * scale an amount without a currency code; ...`); anything the PSP does not take throws
1321
- * `wire_unsupported` with the provider's own message.
1440
+ * `wire_unsupported` with the provider's own message. Typed as the PSP's literal union where it
1441
+ * has a short fixed list (`assertPspCurrency('authorize-net', c)` is an `AuthorizeNetCurrency`).
1322
1442
  */
1323
1443
  function assertPspCurrency(psp, currency) {
1324
1444
  const d = pspDescriptor(psp);
@@ -1349,6 +1469,28 @@ function pspDefaultCurrency(psp) {
1349
1469
  const single = pspDescriptor(psp).singleCurrency;
1350
1470
  return single === null ? null : single;
1351
1471
  }
1472
+ /**
1473
+ * The currency every account of `psp` charges without enabling anything (any other needs the
1474
+ * account's international or multi-currency add-on, or is never taken): Razorpay INR, iyzico TRY,
1475
+ * and for the single-currency PSPs their one currency (MoMo, VNPay and Payoo VND). Null for PSPs
1476
+ * whose accounts have no single home currency (Stripe, Adyen, PayPal, Mollie, Airwallex, Authorize.Net, and Paystack, whose home currency is the
1477
+ * account country's: `pspPresentment('paystack').accountCountries`). Unlike `pspDefaultCurrency`,
1478
+ * which is non-null only for the single-currency PSPs, a home currency does not mean the PSP takes
1479
+ * nothing else.
1480
+ */
1481
+ function pspHomeCurrency(psp) {
1482
+ const home = pspDescriptor(psp).homeCurrency;
1483
+ return home === null ? null : home;
1484
+ }
1485
+ /**
1486
+ * The one country (ISO 3166 alpha-2) every account of `psp` is registered in, for PSPs whose
1487
+ * accounts are all registered in a single country: iyzico `'TR'`, MoMo, VNPay and Payoo `'VN'`. Null
1488
+ * for PSPs available in several countries: Razorpay (India, Malaysia, Singapore, the United States)
1489
+ * and Paystack (its country follows the account: `pspAccountCountryForCurrency`).
1490
+ */
1491
+ function pspHomeCountry(psp) {
1492
+ return pspDescriptor(psp).homeCountry;
1493
+ }
1352
1494
  function factorOf(d, info) {
1353
1495
  if (d.sentAsTwoDecimal.has(info.code)) return 1n;
1354
1496
  if (d.sentAsZeroDecimal.has(info.code)) return 100n;
@@ -1480,8 +1622,18 @@ function decodeChecked(d, wire, currency, convention, allowNegative, exact = fal
1480
1622
  if (w.units < 0n && !allowNegative) throw new MoneyError("amount_invalid", `[${d.tag}] Negative wire amount: ${describeValue(wire)}`);
1481
1623
  return decodeWith(d, w, info, kind, exact);
1482
1624
  }
1483
- function decodeWire(psp, wire, currency, convention) {
1484
- return decodeChecked(pspDescriptor(psp), wire, currency, convention, true);
1625
+ function decodeOptions(d, options, extra) {
1626
+ const notAnOptionsObject = options !== void 0 && (typeof options !== "object" || options === null || hasOwnKey(options, "kind"));
1627
+ if (extra.length > 0 || notAnOptionsObject) {
1628
+ const message = `[${d.tag}] decodeWire takes one options object ({ convention, allowNegative }) as its fourth argument.`;
1629
+ throw new MoneyError("wire_refused", message);
1630
+ }
1631
+ return options ?? {};
1632
+ }
1633
+ function decodeWire(psp, wire, currency, options, ...extra) {
1634
+ const d = pspDescriptor(psp);
1635
+ const { convention, allowNegative } = decodeOptions(d, options, extra);
1636
+ return decodeChecked(d, wire, currency, convention, allowNegative === true);
1485
1637
  }
1486
1638
  /**
1487
1639
  * `decodeWire` that never throws: undefined wherever it would throw (null, undefined, `''`,
@@ -1516,6 +1668,20 @@ function legacyIsoMajor(m) {
1516
1668
  };
1517
1669
  return formatDecimal(roundToScale(major, info.displayDigits, "half-up"));
1518
1670
  }
1671
+ /**
1672
+ * Internal: `m` as Medusa's pre-0.2.0 float codec spelled it for a `legacyFloatToFixed` PSP, at
1673
+ * the PSP's wire digits, or with `isoDigits` at the display digits (the pre-PSP-table spelling):
1674
+ * `(Number(amount) / storageScale).toFixed(digits)`, computed on a double on purpose, because
1675
+ * that is what the PSP holds for a payment created before 0.2.0 (USD 1072.5 is `'10.72'`).
1676
+ * Null for a PSP that never encoded in floating point.
1677
+ */
1678
+ function legacyFloatMajor(psp, m, isoDigits) {
1679
+ const d = pspDescriptor(psp);
1680
+ if (!d.legacyFloatToFixed) return null;
1681
+ const { info } = wireStoredDecimal(m);
1682
+ const digits = isoDigits ? info.displayDigits : wireDigitsOf(d, info);
1683
+ return (Number(m.amount) / info.storageScale).toFixed(digits);
1684
+ }
1519
1685
  /** Internal: one unit of the PSP's last wire digit as Money. */
1520
1686
  function wireUnit(psp, currency, convention) {
1521
1687
  const d = pspDescriptor(psp);
@@ -1526,8 +1692,7 @@ function wireUnit(psp, currency, convention) {
1526
1692
  }, info, d.gated ? requireConvention(d, convention) : null);
1527
1693
  return boundedMoney(isoMinorFactor(info, wireDigitsOf(d, info)), info);
1528
1694
  }
1529
- //#endregion
1530
- //#region src/wire/breakdown.ts
1695
+ // src/wire/breakdown.ts
1531
1696
  /**
1532
1697
  * `total` and its `parts` (same currency, non-negative, adding up to `total`) as integer wire
1533
1698
  * amounts whose sum is exactly `encodeWire(psp, total)`: the wire total split by largest
@@ -1558,8 +1723,7 @@ function wireBreakdown(psp, total, parts, convention) {
1558
1723
  parts: out
1559
1724
  };
1560
1725
  }
1561
- //#endregion
1562
- //#region src/wire/compare.ts
1726
+ // src/wire/compare.ts
1563
1727
  /**
1564
1728
  * Whether a PSP-reported amount is `expected`, a Money or a FractionalMoney (Medusa's unrounded
1565
1729
  * session total). The expected wire is `encodeWire(psp, expected, { convention, allowZero: true })`
@@ -1574,7 +1738,10 @@ function sameWireAmount(psp, reported, expected, options = {}) {
1574
1738
  const reportedInfo = wireCurrency(options.reportedCurrency);
1575
1739
  if (reportedInfo === null || reportedInfo !== wireCurrency(expected.currency)) return false;
1576
1740
  }
1577
- const targets = expectedTargets(psp, expected, convention, options.acceptLegacyIsoDigits === true);
1741
+ const targets = expectedTargets(psp, expected, convention, {
1742
+ isoDigits: options.acceptLegacyIsoDigits === true,
1743
+ floatRounding: options.acceptLegacyFloatRounding === true
1744
+ });
1578
1745
  if (targets === null) return false;
1579
1746
  const { target, legacy } = targets;
1580
1747
  const decode = (value) => options.textOnly && typeof value !== "string" ? void 0 : tryDecodeWireExactly(psp, value, expected.currency, convention);
@@ -1586,10 +1753,14 @@ function sameWireAmount(psp, reported, expected, options = {}) {
1586
1753
  }
1587
1754
  const got = decode(reported);
1588
1755
  if (got === void 0) return false;
1589
- return got.amount === target.amount || got.amount === legacy?.amount;
1756
+ return got.amount === target.amount || legacy.some((m) => m.amount === got.amount);
1590
1757
  }
1591
- /** What `expected` decodes to once sent (and in its legacy ISO-digit spelling), or null when it cannot be sent. */
1592
- function expectedTargets(psp, expected, convention, acceptLegacy) {
1758
+ /**
1759
+ * What `expected` decodes to once sent, and to in each accepted legacy spelling (the exact
1760
+ * ISO-digit one; the pre-0.2.0 float one at the wire digits, and at the ISO digits too when both
1761
+ * are accepted), or null when it cannot be sent.
1762
+ */
1763
+ function expectedTargets(psp, expected, convention, accept) {
1593
1764
  try {
1594
1765
  const d = pspDescriptor(psp);
1595
1766
  const wire = encodeWire(psp, expected, {
@@ -1597,21 +1768,22 @@ function expectedTargets(psp, expected, convention, acceptLegacy) {
1597
1768
  allowZero: true
1598
1769
  });
1599
1770
  const target = decodeAt(psp, wire, expected, convention);
1600
- if (!acceptLegacy || d.family === "iso-minor") return {
1601
- target,
1602
- legacy: void 0
1603
- };
1604
- const spelling = legacyIsoMajor(expected);
1771
+ const spellings = [];
1772
+ if (accept.isoDigits && d.family !== "iso-minor") spellings.push(legacyIsoMajor(expected));
1773
+ if (accept.floatRounding) spellings.push(legacyFloatMajor(psp, expected, false));
1774
+ if (accept.floatRounding && accept.isoDigits) spellings.push(legacyFloatMajor(psp, expected, true));
1775
+ const legacy = [];
1776
+ for (const spelling of spellings) if (spelling !== null && spelling !== String(wire)) legacy.push(decodeAt(psp, spelling, expected, convention));
1605
1777
  return {
1606
1778
  target,
1607
- legacy: spelling === String(wire) ? void 0 : decodeAt(psp, spelling, expected, convention)
1779
+ legacy
1608
1780
  };
1609
1781
  } catch {
1610
1782
  return null;
1611
1783
  }
1612
1784
  }
1613
1785
  function decodeAt(psp, wire, expected, convention) {
1614
- return decodeWire(psp, wire, expected.currency, convention);
1786
+ return decodeWire(psp, wire, expected.currency, { convention });
1615
1787
  }
1616
1788
  /**
1617
1789
  * One unit of the PSP's last wire digit, as Money: for ISO-minor PSPs `decodeWire(psp, 1)` (the
@@ -1625,8 +1797,7 @@ function oneWireUnit(psp, currency, convention) {
1625
1797
  function wireKeyPart(wire) {
1626
1798
  return String(wire);
1627
1799
  }
1628
- //#endregion
1629
- //#region src/data/destinations.ts
1800
+ // src/data/destinations.ts
1630
1801
  const pixel = (currencyCase, unit = "major-number") => ({
1631
1802
  unit,
1632
1803
  currencyCase,
@@ -1689,8 +1860,7 @@ const DESTINATIONS = {
1689
1860
  verified: true
1690
1861
  }
1691
1862
  };
1692
- //#endregion
1693
- //#region src/wire/destinations.ts
1863
+ // src/wire/destinations.ts
1694
1864
  function descriptorOf(dest) {
1695
1865
  if (typeof dest === "string" && hasOwnKey(DESTINATIONS, dest)) return DESTINATIONS[dest];
1696
1866
  throw new MoneyError("wire_unsupported", `Unknown destination: ${describeValue(dest)}`);
@@ -1737,8 +1907,52 @@ function eventMoney(m) {
1737
1907
  currency: medusaCurrencyCode(info.code)
1738
1908
  };
1739
1909
  }
1740
- //#endregion
1741
- //#region src/wire/presentment.ts
1910
+ // src/wire/legacy-refund.ts
1911
+ const minus = (a, b) => addDecimal(a, {
1912
+ units: -b.units,
1913
+ scale: b.scale
1914
+ });
1915
+ /**
1916
+ * The PSP's remaining amount, to refund instead of `refund`, when the PSP holds the capture only
1917
+ * in Medusa's pre-0.2.0 float spelling (`legacyFloatToFixed` PSPs: USD 1072.5 captured as
1918
+ * `'10.72'`, where today's spelling is `'10.73'`) and `refund` is Medusa's whole remaining amount
1919
+ * (`captured - refunded`, exactly). Medusa's remaining then encodes one wire unit above what the
1920
+ * PSP still holds (after a `'0.72'` refund, Medusa's 1000.5 is `'10.01'` against the PSP's
1921
+ * `'10.00'`), and the PSP refuses it (NOT_ALLOWED), so the refund could never complete.
1922
+ * Returns `{ wire, money }` for the PSP's remaining (`'10.00'`, USD 1000), never more than it and
1923
+ * never more than one legacy rounding below what `refund` encodes to. Null (send `refund` as
1924
+ * is) for every other case: a PSP that never encoded in floating point, a capture that matches
1925
+ * today's spelling or no spelling, a partial refund, a refund that already fits, mixed
1926
+ * currencies, and any amount or PSP fact that cannot be read. Never throws.
1927
+ */
1928
+ function legacyFloatRefundClamp(psp, input) {
1929
+ try {
1930
+ if (!pspDescriptor(psp).legacyFloatToFixed) return null;
1931
+ const { captured, refunded, refund } = input;
1932
+ const info = wireCurrency(captured.currency);
1933
+ if (info === null || wireCurrency(refunded.currency) !== info || wireCurrency(refund.currency) !== info) return null;
1934
+ const pspCaptured = tryDecodeWireExactly(psp, input.capturedWire, info.code, void 0);
1935
+ const pspRefunded = tryDecodeWireExactly(psp, input.refundedWire, info.code, void 0);
1936
+ if (pspCaptured === void 0 || pspRefunded === void 0) return null;
1937
+ if (!(!sameWireAmount(psp, input.capturedWire, captured) && sameWireAmount(psp, input.capturedWire, captured, { acceptLegacyFloatRounding: true }))) return null;
1938
+ const medusaRemaining = minus(wireStoredDecimal(captured).stored, wireStoredDecimal(refunded).stored);
1939
+ if (compareDecimal(wireStoredDecimal(refund).stored, medusaRemaining) !== 0) return null;
1940
+ const encode = encodeWire;
1941
+ const decode = decodeWire;
1942
+ const sent = decode(psp, encode(psp, refund, { label: "refund amount" }), info.code).amount;
1943
+ const pspRemaining = pspCaptured.amount - pspRefunded.amount;
1944
+ const legacyGap = decode(psp, encode(psp, captured), info.code).amount - pspCaptured.amount;
1945
+ if (pspRemaining <= 0 || sent <= pspRemaining || sent - pspRemaining > legacyGap) return null;
1946
+ const money = boundedMoney(BigInt(pspRemaining), info);
1947
+ return {
1948
+ wire: encode(psp, money, { label: "refund amount" }),
1949
+ money
1950
+ };
1951
+ } catch {
1952
+ return null;
1953
+ }
1954
+ }
1955
+ // src/wire/presentment.ts
1742
1956
  /** Registry codes only, sorted: a provider-only code (Adyen CNH) or one the registry does not know is left out. */
1743
1957
  function knownCodes(codes) {
1744
1958
  const known = [];
@@ -1759,33 +1973,75 @@ function pspPresentment(psp) {
1759
1973
  const d = pspDescriptor(psp);
1760
1974
  const requires = PRESENTMENT_REQUIRES_ACCOUNT_COUNTRY[d.id] ?? {};
1761
1975
  const allowsOnly = PRESENTMENT_ACCOUNT_COUNTRY_ALLOWS_ONLY[d.id] ?? {};
1976
+ const countries = new Map([...d.accountCountries].map(([country, entry]) => {
1977
+ const lists = {
1978
+ currencies: new Set(knownCodes(entry.currencies)),
1979
+ optIn: new Set(knownCodes(entry.optIn))
1980
+ };
1981
+ return [country, Object.freeze(lists)];
1982
+ }));
1762
1983
  return Object.freeze({
1763
1984
  currencies: new Set(knownCodes(d.presentmentCurrencies)),
1764
1985
  currencyRequiresAccountCountry: new Map(knownCodes(Object.keys(requires)).map((code) => [code, new Set(requires[code])])),
1765
- accountCountryAllowsOnly: new Map(Object.keys(allowsOnly).map((country) => [country, new Set(knownCodes(allowsOnly[country]))]))
1986
+ accountCountryAllowsOnly: new Map(Object.keys(allowsOnly).map((country) => [country, new Set(knownCodes(allowsOnly[country]))])),
1987
+ accountCountries: countries,
1988
+ optInCompanions: optInCompanionsOf(countries)
1766
1989
  });
1767
1990
  }
1768
1991
  /**
1992
+ * Internal: per currency that names one account country, that country's opt-in currencies. A
1993
+ * currency two countries share names neither, so it gets no companion (no Paystack currency is
1994
+ * shared today; the tests hold the rule with a fixture).
1995
+ */
1996
+ function optInCompanionsOf(countries) {
1997
+ const companions = /* @__PURE__ */ new Map();
1998
+ for (const entry of countries.values()) {
1999
+ if (entry.optIn.size === 0) continue;
2000
+ for (const code of entry.currencies) if (impliedCountry(countries, code) !== null) companions.set(code, new Set(entry.optIn));
2001
+ }
2002
+ return companions;
2003
+ }
2004
+ /** The one account country whose list (always or opt-in) holds `code`, else null. */
2005
+ function impliedCountry(countries, code) {
2006
+ const holders = [...countries].filter(([, entry]) => entry.currencies.has(code) || entry.optIn.has(code));
2007
+ return holders.length === 1 ? holders[0][0] : null;
2008
+ }
2009
+ /**
2010
+ * The account country a currency names for `psp`: the one country whose accounts present it
2011
+ * (Paystack NGN: `'NG'`, XOF: `'CI'`, the only XOF country Paystack onboards). Null when several
2012
+ * countries' accounts can present it (Paystack USD, on NG and KE accounts), when the PSP has no
2013
+ * per-country lists, or for an unknown code. Never throws for a bad code; an unknown PSP throws
2014
+ * `wire_unsupported`.
2015
+ */
2016
+ function pspAccountCountryForCurrency(psp, currency) {
2017
+ const d = pspDescriptor(psp);
2018
+ const info = wireCurrency(currency);
2019
+ return info === null ? null : impliedCountry(d.accountCountries, info.code);
2020
+ }
2021
+ /**
1769
2022
  * The currencies `psp` lets an account present (charge buyers in). Without `accountCountry`, the
1770
- * union over every account country; with it (ISO 3166 alpha-2, any case), only what an account
1771
- * registered there can charge: Stripe's three-decimal five need a UAE account, PayPal's BRL, CNY
1772
- * and MYR an in-country one, Airwallex cards on a US account take its documented 76 and on an MX
1773
- * account MXN only. Not `pspCurrencies`, which is what the codec scales and the facade lets
1774
- * through (Stripe's adds every two-decimal ISO code it accepts on the wire).
2023
+ * union over every account country, opt-in currencies included; with it (ISO 3166 alpha-2, any
2024
+ * case), only what an account registered there can charge: Stripe's three-decimal five need a UAE
2025
+ * account, PayPal's BRL, CNY and MYR an in-country one, Airwallex cards on a US account take its
2026
+ * documented 76 and on an MX account MXN only, a Paystack account its country's currency (plus USD
2027
+ * on NG and KE with `includeOptIn`, and nothing for a country Paystack does not onboard). Not
2028
+ * `pspCurrencies`, which is what the codec scales and the facade lets through (Stripe's adds every
2029
+ * two-decimal ISO code it accepts on the wire).
1775
2030
  */
1776
2031
  function pspPresentmentCurrencies(psp, options = {}) {
1777
2032
  const rules = pspPresentment(psp);
1778
2033
  if (options.accountCountry === void 0) return rules.currencies;
1779
2034
  const country = options.accountCountry.trim().toUpperCase();
1780
2035
  const only = rules.accountCountryAllowsOnly.get(country);
2036
+ const listed = rules.accountCountries.get(country);
1781
2037
  const codes = [...rules.currencies].filter((code) => {
1782
2038
  const required = rules.currencyRequiresAccountCountry.get(code);
1783
- return (required === void 0 || required.has(country)) && (only === void 0 || only.has(code));
2039
+ const inCountryList = rules.accountCountries.size === 0 || listed !== void 0 && (listed.currencies.has(code) || options.includeOptIn === true && listed.optIn.has(code));
2040
+ return (required === void 0 || required.has(country)) && (only === void 0 || only.has(code)) && inCountryList;
1784
2041
  });
1785
2042
  return new Set(codes);
1786
2043
  }
1787
- //#endregion
1788
- //#region src/wire/provider-amount.ts
2044
+ // src/wire/provider-amount.ts
1789
2045
  /**
1790
2046
  * A provider's major-unit amount (finite number, or text read by the separator engine, which
1791
2047
  * strips the currency's symbol and code) as Money, rounded once to the storage digits. Null on
@@ -1820,24 +2076,27 @@ function parseProviderAmount(value, currency, options = {}) {
1820
2076
  return null;
1821
2077
  }
1822
2078
  }
1823
- //#endregion
1824
- //#region src/wire/providers.ts
2079
+ // src/wire/providers.ts
1825
2080
  /** RBI e-mandate cap Razorpay token registrations carry as `max_amount`: INR 15,000 (1,500,000 paise = stored). */
1826
2081
  const RAZORPAY_AFA_FREE_CAP = Object.freeze(fromMajor(RAZORPAY_AFA_FREE_CAP_MAJOR, "INR"));
1827
- /**
1828
- * The symbolic charge a saved-card setup makes: Paystack one major unit, Razorpay one INR (any
1829
- * other currency is `wire_unsupported`), Mollie one smallest wire unit (`'0.01'`, `'1'` for ISK
1830
- * and JPY), Adyen zero. Vault charges are always new, so the iso-minor-v2 convention applies.
1831
- */
2082
+ const VERIFICATION_AMOUNTS = {
2083
+ paystack: "one-major-unit",
2084
+ razorpay: "one-major-unit",
2085
+ mollie: "one-wire-unit",
2086
+ adyen: "zero"
2087
+ };
2088
+ function verificationMoney(psp, code) {
2089
+ const amount = VERIFICATION_AMOUNTS[psp];
2090
+ if (amount === "one-major-unit") return fromMajor("1", code);
2091
+ if (amount === "one-wire-unit") return wireUnit(psp, code);
2092
+ return boundedMoney(0n, resolveWireCurrency(code));
2093
+ }
1832
2094
  function verificationCharge(psp, currency) {
1833
- const code = assertPspCurrency(psp, currency);
1834
- let charge;
1835
- if (psp === "paystack") charge = fromMajor("1", code);
1836
- else if (psp === "razorpay") {
1837
- if (code !== "INR") throw new MoneyError("wire_unsupported", `[Razorpay] Verification charges are made in INR only, not ${code}.`);
1838
- charge = fromMajor("1", code);
1839
- } else if (psp === "mollie") charge = wireUnit("mollie", code);
1840
- else charge = boundedMoney(0n, resolveWireCurrency(code));
2095
+ const d = pspDescriptor(psp);
2096
+ const documented = d.verificationCurrency;
2097
+ const code = assertPspCurrency(psp, currency === void 0 ? documented?.code : currency);
2098
+ if (documented?.only && code !== documented.code) throw new MoneyError("wire_unsupported", `[${d.tag}] Verification charges are made in ${documented.code} only, not ${code}.`);
2099
+ const charge = verificationMoney(psp, code);
1841
2100
  return {
1842
2101
  wire: encodeWire(psp, charge, {
1843
2102
  convention: ISO_MINOR_V2,
@@ -1857,8 +2116,7 @@ function iyzicoPrice(wire) {
1857
2116
  const text = toDecimalText(parsed);
1858
2117
  return text.includes(".") ? text : `${text}.0`;
1859
2118
  }
1860
- //#endregion
1861
- //#region src/wire/slot.ts
2119
+ // src/wire/slot.ts
1862
2120
  /** `m` for a slot context's `money` key. */
1863
2121
  function slotMoney(m) {
1864
2122
  const { info } = storedDecimal(m);
@@ -1884,5 +2142,4 @@ function readSlotMoney(context) {
1884
2142
  const money = context.money;
1885
2143
  return (isRecord(money) ? read(money.amount, money.currency_code) : void 0) ?? read(context.total ?? context.price, context.currency_code, context.currency);
1886
2144
  }
1887
- //#endregion
1888
- export { WIRE_SCALE_KEY as A, pspSupportsCurrency as C, ISO_MINOR_V2 as D, wireFactor as E, jsonDecimalLiteral as F, conventionOf as M, PSP_IDS as N, PRE_CUTOVER as O, authorizeNetReversibleAmount as P, pspMinimumAmount as S, tryDecodeWire as T, assertPspCurrency as _, verificationCharge as a, pspCurrencies as b, pspPresentmentCurrencies as c, feedPrice as d, googleMicros as f, wireBreakdown as g, wireKeyPart as h, iyzicoPrice as i, WIRE_SCALE_MARKER as j, WIRE_SCALE_ISO_MINOR_V2 as k, destinationAmount as l, sameWireAmount as m, slotMoney as n, parseProviderAmount as o, oneWireUnit as p, RAZORPAY_AFA_FREE_CAP as r, pspPresentment as s, readSlotMoney as t, eventMoney as u, decodeWire as v, pspWireDigits as w, pspDefaultCurrency as x, encodeWire as y };
2145
+ export { wireFactor as A, mayHoldLegacyFloatRounding as B, pspDefaultCurrency as C, pspSupportsCurrency as D, pspMinimumAmount as E, WIRE_ROUNDING_MARKER as F, authorizeNetReversibleAmount as H, WIRE_SCALE_ISO_MINOR_V2 as I, WIRE_SCALE_KEY as L, PRE_CUTOVER as M, WIRE_ROUNDING_EXACT as N, pspWireDigits as O, WIRE_ROUNDING_KEY as P, WIRE_SCALE_MARKER as R, pspCurrencies as S, pspHomeCurrency as T, jsonDecimalLiteral as U, PSP_IDS as V, PAYSTACK_CURRENCIES as W, wireKeyPart as _, verificationCharge as a, decodeWire as b, pspPresentment as c, destinationAmount as d, eventMoney as f, sameWireAmount as g, oneWireUnit as h, iyzicoPrice as i, ISO_MINOR_V2 as j, tryDecodeWire as k, pspPresentmentCurrencies as l, googleMicros as m, slotMoney as n, parseProviderAmount as o, feedPrice as p, RAZORPAY_AFA_FREE_CAP as r, pspAccountCountryForCurrency as s, readSlotMoney as t, legacyFloatRefundClamp as u, wireBreakdown as v, pspHomeCountry as w, encodeWire as x, assertPspCurrency as y, conventionOf as z };