@agent-cards/sdk 0.23.17 → 0.23.19

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.
@@ -1,6 +1,6 @@
1
1
  // @ts-nocheck
2
2
  // Generated from @agent-cards/payment-core. Do not edit.
3
- // artifact-sha256: c3b720efaa20837c1bf50cc511610282f324867e9fe5538ac155b2ff79f2d9b4
3
+ // artifact-sha256: 16332ca203bb18be112c4fb3f5605a1e7520cdef85c954bed2f14292c8284212
4
4
  // src/card-number-key.js
5
5
  var CARD_NUMBER_KEY = /^(number|card_number|cardnumber|cardNum|card_num|pan)$/i;
6
6
  // src/json-path.js
@@ -310,11 +310,11 @@ var MONERIS_TOKENIZE_PATH = "/HPPtoken/request.php";
310
310
  function monerisTokenizeEnvironment(url) {
311
311
  if (typeof url !== "string")
312
312
  return null;
313
- for (const environment of
313
+ for (const environment2 of
314
314
  /** @type {const} */
315
315
  ["production", "sandbox"]) {
316
- if (MONERIS_TOKENIZE_HOSTS[environment].some((host) => url === `https://${host}${MONERIS_TOKENIZE_PATH}`))
317
- return environment;
316
+ if (MONERIS_TOKENIZE_HOSTS[environment2].some((host) => url === `https://${host}${MONERIS_TOKENIZE_PATH}`))
317
+ return environment2;
318
318
  }
319
319
  return null;
320
320
  }
@@ -365,8 +365,8 @@ var CONTROL = /[\u0000-\u001f\u007f]/;
365
365
  var cardLikeName = (name) => (name.match(/[0-9]/g) ?? []).length >= 12;
366
366
  var record3 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
367
367
  var sameKeys = (value, keys) => {
368
- const own2 = Object.keys(value);
369
- return own2.length === keys.length && own2.every((key, at) => key === keys[at]);
368
+ const own3 = Object.keys(value);
369
+ return own3.length === keys.length && own3.every((key, at) => key === keys[at]);
370
370
  };
371
371
  var refuse4 = (code) => Object.freeze({ verdict: "refuse", code });
372
372
  var CARD4 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
@@ -671,10 +671,10 @@ var TYPED_ARRAY = Object.getPrototypeOf(Uint8Array.prototype);
671
671
  var typedArrayName = Object.getOwnPropertyDescriptor(TYPED_ARRAY, Symbol.toStringTag).get;
672
672
  function parseRsaPublicKey(key) {
673
673
  const spki = key && typeof key === "object" ? key.spki : void 0;
674
- const pin4 = key && typeof key === "object" ? key.sha256 : void 0;
674
+ const pin5 = key && typeof key === "object" ? key.sha256 : void 0;
675
675
  if (typeof spki !== "string" || spki.length > 1024 || spki.length % 4 !== 0 || !BASE64.test(spki))
676
676
  throw refuse6("key");
677
- if (typeof pin4 !== "string" || !SHA256_HEX.test(pin4))
677
+ if (typeof pin5 !== "string" || !SHA256_HEX.test(pin5))
678
678
  throw refuse6("key");
679
679
  let binary;
680
680
  try {
@@ -686,7 +686,7 @@ function parseRsaPublicKey(key) {
686
686
  if (btoa(binary) !== spki)
687
687
  throw refuse6("key");
688
688
  const der = Uint8Array.from(binary, (c) => c.charCodeAt(0));
689
- if (sha256Hex(der) !== pin4)
689
+ if (sha256Hex(der) !== pin5)
690
690
  throw refuse6("key");
691
691
  const outer = readElement(der, 0, 48);
692
692
  if (outer.end !== der.length || outer.start + RSA_ALGORITHM.length > der.length)
@@ -754,13 +754,13 @@ var PADDLE_TOKENEX_KEYS = /* @__PURE__ */ Object.freeze({
754
754
  sha256: "92529bd289bb24d52a1bdcc42edc9ac0bb1dacbb58f7568573d44771e1287762"
755
755
  })
756
756
  });
757
- function paddleTokenexKey(environment) {
758
- if (environment !== "sandbox" && environment !== "production")
757
+ function paddleTokenexKey(environment2) {
758
+ if (environment2 !== "sandbox" && environment2 !== "production")
759
759
  return null;
760
- return PADDLE_TOKENEX_KEYS[environment] ?? null;
760
+ return PADDLE_TOKENEX_KEYS[environment2] ?? null;
761
761
  }
762
- function paddleTokenexKeyBytes(environment) {
763
- const key = paddleTokenexKey(environment);
762
+ function paddleTokenexKeyBytes(environment2) {
763
+ const key = paddleTokenexKey(environment2);
764
764
  if (!key)
765
765
  return null;
766
766
  try {
@@ -775,8 +775,8 @@ var PADDLE_TOKENEX_PSP = "paddle_tokenex";
775
775
  var PADDLE_TOKENEX_FACT_KEYS = /* @__PURE__ */ Object.freeze(["card_first_six", "card_last_four", "expiry_month", "expiry_year", "card_brand"]);
776
776
  var record4 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
777
777
  var sameKeys2 = (value, keys) => {
778
- const own2 = Object.keys(value);
779
- return own2.length === keys.length && own2.every((key, at) => key === keys[at]);
778
+ const own3 = Object.keys(value);
779
+ return own3.length === keys.length && own3.every((key, at) => key === keys[at]);
780
780
  };
781
781
  var refuse7 = (code) => Object.freeze({ verdict: "refuse", code });
782
782
  var CARD6 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
@@ -821,11 +821,11 @@ function isBase64OfBytes(value, bytes) {
821
821
  const pad = value.endsWith("==") ? 2 : value.endsWith("=") ? 1 : 0;
822
822
  return value.length / 4 * 3 - pad === bytes && btoa(atob(value)) === value;
823
823
  }
824
- function isPaddleTokenexCiphertext(value, environment) {
825
- const bytes = paddleTokenexKeyBytes(environment);
824
+ function isPaddleTokenexCiphertext(value, environment2) {
825
+ const bytes = paddleTokenexKeyBytes(environment2);
826
826
  return bytes !== null && isBase64OfBytes(value, bytes);
827
827
  }
828
- function readPay(body, line, environment) {
828
+ function readPay(body, line, environment2) {
829
829
  if (typeof body !== "string" || body === "" || body.length > PAY_BODY_LIMIT)
830
830
  return null;
831
831
  let value;
@@ -857,11 +857,11 @@ function readPay(body, line, environment) {
857
857
  return null;
858
858
  for (const name of CARD_KEYS3) {
859
859
  const blob = tokenex[name];
860
- if (environment === void 0) {
860
+ if (environment2 === void 0) {
861
861
  if (typeof blob !== "string" || !BASE642.test(blob) || blob.length < 4 || blob.length > 4096)
862
862
  return null;
863
863
  }
864
- else if (!isPaddleTokenexCiphertext(blob, environment))
864
+ else if (!isPaddleTokenexCiphertext(blob, environment2))
865
865
  return null;
866
866
  }
867
867
  if (tokenex.encrypted_card_number === tokenex.encrypted_cvv)
@@ -1265,8 +1265,8 @@ var TEXT_LIMIT = 256;
1265
1265
  var CONTROL4 = /[\u0000-\u001f\u007f]/;
1266
1266
  var record6 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
1267
1267
  var sameKeys3 = (value, keys) => {
1268
- const own2 = Object.keys(value);
1269
- return own2.length === keys.length && own2.every((key, at) => key === keys[at]);
1268
+ const own3 = Object.keys(value);
1269
+ return own3.length === keys.length && own3.every((key, at) => key === keys[at]);
1270
1270
  };
1271
1271
  var plainText = (value) => typeof value === "string" && value.length <= TEXT_LIMIT && !CONTROL4.test(value) && (value.match(/[0-9]/g) ?? []).length < 12;
1272
1272
  var refuse9 = (code) => Object.freeze({ verdict: "refuse", code });
@@ -1468,8 +1468,8 @@ var EXPIRATION = /^[0-9]{2}(?:0[1-9]|1[0-2])$/;
1468
1468
  var CARD_PAYMENT = "PAYMENT_CARD";
1469
1469
  var record8 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
1470
1470
  var sameKeys4 = (value, keys) => {
1471
- const own2 = Object.keys(value);
1472
- return own2.length === keys.length && own2.every((key, at) => key === keys[at]);
1471
+ const own3 = Object.keys(value);
1472
+ return own3.length === keys.length && own3.every((key, at) => key === keys[at]);
1473
1473
  };
1474
1474
  var refuse11 = (code) => Object.freeze({ verdict: "refuse", code });
1475
1475
  var CARD10 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
@@ -1498,8 +1498,8 @@ function gopayCardFormUrl(url) {
1498
1498
  }
1499
1499
  if (parsed.href !== url || parsed.protocol !== "https:" || parsed.port || parsed.username || parsed.password)
1500
1500
  return null;
1501
- const environment = Object.prototype.hasOwnProperty.call(GOPAY_CARD_FORM_HOSTS, parsed.hostname) ? GOPAY_CARD_FORM_HOSTS[parsed.hostname] : null;
1502
- if (environment === null || !parsed.pathname.startsWith(GOPAY_CARD_FORM_PATH))
1501
+ const environment2 = Object.prototype.hasOwnProperty.call(GOPAY_CARD_FORM_HOSTS, parsed.hostname) ? GOPAY_CARD_FORM_HOSTS[parsed.hostname] : null;
1502
+ if (environment2 === null || !parsed.pathname.startsWith(GOPAY_CARD_FORM_PATH))
1503
1503
  return null;
1504
1504
  if (!TOKEN2.test(parsed.pathname.slice(GOPAY_CARD_FORM_PATH.length)))
1505
1505
  return null;
@@ -1511,7 +1511,7 @@ function gopayCardFormUrl(url) {
1511
1511
  const version = parsed.searchParams.get("ver");
1512
1512
  if (signature === null || !SIGNATURE.test(signature) || language !== null && !LANGUAGE.test(language) || version !== null && !VERSION.test(version))
1513
1513
  return null;
1514
- return Object.freeze({ host: parsed.hostname, environment, signature });
1514
+ return Object.freeze({ host: parsed.hostname, environment: environment2, signature });
1515
1515
  }
1516
1516
  function readBody4(body) {
1517
1517
  if (typeof body !== "string" || body === "" || body.length > BODY_LIMIT7)
@@ -1548,6 +1548,916 @@ function gopayBodyVerdict(body, url) {
1548
1548
  return refuse11("gopay_signature_mismatch");
1549
1549
  return CARD10;
1550
1550
  }
1551
+ // src/payrexx.js
1552
+ var PAYREXX_PSP = "payrexx";
1553
+ var PAYREXX_FRAME_HOST = "checkout.payrexx.com";
1554
+ var PAYREXX_PAY_PSP_ID = "44";
1555
+ var PAYREXX_BODY_KEYS = /* @__PURE__ */ Object.freeze([
1556
+ "instance",
1557
+ "pspId",
1558
+ "card[number]",
1559
+ "card[cardholder]",
1560
+ "card[exp_month]",
1561
+ "card[exp_year]",
1562
+ "card[cvc]",
1563
+ "card[brand]",
1564
+ "amount",
1565
+ "currency",
1566
+ "isTokenization",
1567
+ "isSubscription",
1568
+ "isPreAuthorization",
1569
+ "isMoto",
1570
+ "email"
1571
+ ]);
1572
+ var BODY_LIMIT8 = 16384;
1573
+ var URL_LIMIT3 = 128;
1574
+ var FRAME_QUERY = /^\?pspId=([1-9][0-9]{0,3})&lang=([a-z]{2})$/;
1575
+ var GROUPED = /^[0-9]{4} [0-9]{4} [0-9]{4} [0-9]{4}$/;
1576
+ var VISA2 = /^4[0-9]{15}$/;
1577
+ var MASTERCARD2 = /^(?:5[1-5][0-9]{14}|2(?:2(?:2[1-9]|[3-9][0-9])|[3-6][0-9]{2}|7(?:[01][0-9]|20))[0-9]{12})$/;
1578
+ var SECURITY_CODE7 = /^[0-9]{3}$/;
1579
+ var MONTH3 = /^(?:0[1-9]|1[0-2])$/;
1580
+ var YEAR3 = /^20[0-9]{2}$/;
1581
+ var HOLDER2 = /^[\p{L}\p{M}][\p{L}\p{M} '.-]{0,44}$/u;
1582
+ var INSTANCE = /^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$/;
1583
+ var AMOUNT2 = /^[1-9][0-9]{0,8}$/;
1584
+ var CURRENCY = /^[A-Z]{3}$/;
1585
+ var EMAIL = /^[^\s@]{1,64}@[^\s@]{1,189}$/;
1586
+ var FLAGS = /* @__PURE__ */ Object.freeze(["isTokenization", "isSubscription", "isPreAuthorization", "isMoto"]);
1587
+ var CARD_DIGITS = /[0-9](?:[ -]?[0-9]){11}/;
1588
+ var THREE_DS_KEY = /^(?:threeDSServerTransID|threeDSVersion|postAuth|authData\[[A-Za-z]{1,32}\])$/;
1589
+ var refuse12 = (code) => Object.freeze({ verdict: "refuse", code });
1590
+ var CARD11 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
1591
+ var CONTINUE5 = /* @__PURE__ */ Object.freeze({ verdict: "continue" });
1592
+ function payrexxFrameTarget(url) {
1593
+ if (typeof url !== "string" || url.length > URL_LIMIT3 || url.includes("#"))
1594
+ return null;
1595
+ let parsed;
1596
+ try {
1597
+ parsed = new URL(url);
1598
+ }
1599
+ catch {
1600
+ return null;
1601
+ }
1602
+ if (parsed.href !== url || parsed.protocol !== "https:" || parsed.port || parsed.username || parsed.password || parsed.hostname !== PAYREXX_FRAME_HOST || parsed.pathname !== "/")
1603
+ return null;
1604
+ const query = FRAME_QUERY.exec(parsed.search);
1605
+ return query ? Object.freeze({ pspId: query[1], lang: query[2] }) : null;
1606
+ }
1607
+ function readForm2(body) {
1608
+ if (typeof body !== "string" || body === "" || body.length > BODY_LIMIT8)
1609
+ return null;
1610
+ try {
1611
+ const pairs = body.split("&").map((chunk) => {
1612
+ const eq = chunk.indexOf("=");
1613
+ if (eq <= 0)
1614
+ throw new URIError("not a form pair");
1615
+ return [decodeURIComponent(chunk.slice(0, eq)), decodeURIComponent(chunk.slice(eq + 1))];
1616
+ });
1617
+ return pairs.map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`).join("&") === body ? pairs : null;
1618
+ }
1619
+ catch {
1620
+ return null;
1621
+ }
1622
+ }
1623
+ function cardNetwork2(digits2) {
1624
+ if (VISA2.test(digits2))
1625
+ return "visa";
1626
+ return MASTERCARD2.test(digits2) ? "mastercard" : null;
1627
+ }
1628
+ function judgeBody2(body) {
1629
+ const pairs = readForm2(body);
1630
+ if (pairs === null)
1631
+ return { verdict: refuse12("payrexx_body_unsupported"), pairs: null };
1632
+ const keys = pairs.map(([key]) => key);
1633
+ const value = Object.fromEntries(pairs);
1634
+ if (!pairs.some(([key, entry]) => key.startsWith("card[") && key !== "card[brand]" && entry !== "")) {
1635
+ return pairs.some(([key, entry]) => key !== "encryptedCard" && CARD_DIGITS.test(entry)) ? { verdict: refuse12("payrexx_body_unsupported"), pairs: null } : { verdict: CONTINUE5, pairs: null };
1636
+ }
1637
+ if (new Set(keys).size !== keys.length)
1638
+ return { verdict: refuse12("payrexx_body_unsupported"), pairs: null };
1639
+ if (keys.includes("encryptedCard"))
1640
+ return { verdict: refuse12("payrexx_wallet_card"), pairs: null };
1641
+ if (keys.some((key) => THREE_DS_KEY.test(key)))
1642
+ return { verdict: refuse12("payrexx_three_ds_resend"), pairs: null };
1643
+ if (value.pspId !== PAYREXX_PAY_PSP_ID)
1644
+ return { verdict: refuse12("payrexx_other_provider"), pairs: null };
1645
+ if (keys.length !== PAYREXX_BODY_KEYS.length || !keys.every((key, at) => key === PAYREXX_BODY_KEYS[at])) {
1646
+ return { verdict: refuse12("payrexx_body_unsupported"), pairs: null };
1647
+ }
1648
+ const number = value["card[number]"];
1649
+ const network = GROUPED.test(number) ? cardNetwork2(number.replace(/ /g, "")) : null;
1650
+ if (network === null || value["card[brand]"] !== network || !SECURITY_CODE7.test(value["card[cvc]"]) || !MONTH3.test(value["card[exp_month]"]) || !YEAR3.test(value["card[exp_year]"]) || !HOLDER2.test(value["card[cardholder]"]) || !INSTANCE.test(value.instance) || !AMOUNT2.test(value.amount) || !CURRENCY.test(value.currency) || !(value.email === "" || value.email.length <= 254 && EMAIL.test(value.email)) || !FLAGS.every((flag) => value[flag] === "true" || value[flag] === "false")) {
1651
+ return { verdict: refuse12("payrexx_body_unsupported"), pairs: null };
1652
+ }
1653
+ if (value.isTokenization === "true" || value.isSubscription === "true")
1654
+ return { verdict: refuse12("payrexx_keep_on_file"), pairs: null };
1655
+ if (value.isPreAuthorization === "true" || value.isMoto === "true")
1656
+ return { verdict: refuse12("payrexx_not_a_sale"), pairs: null };
1657
+ return { verdict: CARD11, pairs };
1658
+ }
1659
+ function payrexxBodyVerdict(body) {
1660
+ return judgeBody2(body).verdict;
1661
+ }
1662
+ function payrexxGateVerdict(url, body) {
1663
+ const target = payrexxFrameTarget(url);
1664
+ if (target === null)
1665
+ return refuse12("payrexx_url_refused");
1666
+ const verdict = payrexxBodyVerdict(body);
1667
+ return verdict.verdict === "card" && target.pspId !== PAYREXX_PAY_PSP_ID ? refuse12("payrexx_other_provider") : verdict;
1668
+ }
1669
+ // src/komoju.js
1670
+ var KOMOJU_PSP = "komoju";
1671
+ var KOMOJU_HOST = "komoju.com";
1672
+ var KOMOJU_SECURE_TOKEN_URL = "https://komoju.com/api/v1/secure_tokens";
1673
+ var KOMOJU_TOKEN_URL = "https://komoju.com/api/v1/tokens";
1674
+ var KOMOJU_RETURN_URL_PREFIX = "https://multipay.komoju.com/secure-token-return.html?session_id=";
1675
+ var BODY_LIMIT9 = 4096;
1676
+ var URL_LIMIT4 = 128;
1677
+ var SESSION_ID = /^[a-z0-9]{25}$/;
1678
+ var SESSION_PAY_PATH = /^\/api\/v1\/sessions\/([a-z0-9]{25})\/pay$/;
1679
+ var TOKEN_ID = /^tok_[a-z0-9]{20,32}$/;
1680
+ var TOP_KEYS = /* @__PURE__ */ Object.freeze(["amount", "currency", "payment_details", "return_url"]);
1681
+ var KOMOJU_CARD_KEYS = /* @__PURE__ */ Object.freeze(["type", "name", "number", "month", "year", "verification_value", "email"]);
1682
+ var PAY_KEYS = /* @__PURE__ */ Object.freeze(["payment_details", "api_locale"]);
1683
+ var AMOUNT_MAX = 99999999;
1684
+ var CURRENCY2 = /^[A-Z]{3}$/;
1685
+ var NUMBER2 = /^[0-9]{12,19}$/;
1686
+ var MONTH4 = /^(?:0[1-9]|1[0-2])$/;
1687
+ var YEAR4 = /^[0-9]{2}$/;
1688
+ var SECURITY_CODE8 = /^[0-9]{3,4}$/;
1689
+ var PAGE_NAME = /^[\x20-\x7e]{1,64}$/;
1690
+ var NAME_DIGITS_MAX = 11;
1691
+ var EMAIL2 = /^[\x21-\x7e]{1,64}@[\x21-\x7e]{1,189}$/;
1692
+ var LOCALE = /^[a-z]{2}(?:-[A-Za-z]{2,4})?$/;
1693
+ var PAN_LIKE3 = /(?:[0-9][ _.:-]*){12,}/;
1694
+ var record9 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
1695
+ var sameKeys5 = (value, keys) => {
1696
+ const own3 = Object.keys(value);
1697
+ return own3.length === keys.length && own3.every((key, at) => key === keys[at]);
1698
+ };
1699
+ var refuse13 = (code) => Object.freeze({ verdict: "refuse", code });
1700
+ var CARD12 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
1701
+ var CONTINUE6 = /* @__PURE__ */ Object.freeze({ verdict: "continue" });
1702
+ function komojuTarget(url) {
1703
+ if (typeof url !== "string" || url.length > URL_LIMIT4 || url.includes("?") || url.includes("#"))
1704
+ return null;
1705
+ let parsed;
1706
+ try {
1707
+ parsed = new URL(url);
1708
+ }
1709
+ catch {
1710
+ return null;
1711
+ }
1712
+ if (parsed.href !== url || parsed.protocol !== "https:" || parsed.port || parsed.username || parsed.password || parsed.hostname !== KOMOJU_HOST)
1713
+ return null;
1714
+ if (url === KOMOJU_SECURE_TOKEN_URL)
1715
+ return Object.freeze({ kind: "secure_token" });
1716
+ if (url === KOMOJU_TOKEN_URL)
1717
+ return Object.freeze({ kind: "token" });
1718
+ const pay = SESSION_PAY_PATH.exec(parsed.pathname);
1719
+ return pay ? Object.freeze({ kind: "session_pay", session: pay[1] }) : null;
1720
+ }
1721
+ function readJson3(body) {
1722
+ if (typeof body !== "string" || body === "" || body.length > BODY_LIMIT9)
1723
+ return null;
1724
+ try {
1725
+ const value = JSON.parse(body);
1726
+ return record9(value) && JSON.stringify(value) === body ? value : null;
1727
+ }
1728
+ catch {
1729
+ return null;
1730
+ }
1731
+ }
1732
+ function carriesCard(details) {
1733
+ return record9(details) && Object.keys(details).some((key) => /^(?:number|card_?number|pan)$/i.test(key));
1734
+ }
1735
+ function judgeSecureToken(value) {
1736
+ if (!sameKeys5(value, TOP_KEYS))
1737
+ return "komoju_body_unsupported";
1738
+ const details = value.payment_details;
1739
+ if (!Number.isSafeInteger(value.amount) || value.amount < 0 || value.amount > AMOUNT_MAX || typeof value.currency !== "string" || !CURRENCY2.test(value.currency) || typeof value.return_url !== "string" || !value.return_url.startsWith(KOMOJU_RETURN_URL_PREFIX) || !SESSION_ID.test(value.return_url.slice(KOMOJU_RETURN_URL_PREFIX.length)) || !record9(details) || !sameKeys5(details, KOMOJU_CARD_KEYS) || details.type !== "credit_card" || typeof details.name !== "string" || !PAGE_NAME.test(details.name) || details.name.trim() === "" || details.name.replace(/[^0-9]/g, "").length > NAME_DIGITS_MAX || typeof details.number !== "string" || !NUMBER2.test(details.number) || typeof details.month !== "string" || !MONTH4.test(details.month) || typeof details.year !== "string" || !YEAR4.test(details.year) || typeof details.verification_value !== "string" || !SECURITY_CODE8.test(details.verification_value) || typeof details.email !== "string" || !EMAIL2.test(details.email) || PAN_LIKE3.test(details.email)) {
1740
+ return "komoju_body_unsupported";
1741
+ }
1742
+ return value.amount === 0 ? "komoju_keeps_card" : null;
1743
+ }
1744
+ function tokenPay(value) {
1745
+ const keys = Object.keys(value);
1746
+ return (sameKeys5(value, PAY_KEYS) || keys.length === 1 && keys[0] === "payment_details") && typeof value.payment_details === "string" && TOKEN_ID.test(value.payment_details) && (value.api_locale === void 0 || typeof value.api_locale === "string" && LOCALE.test(value.api_locale));
1747
+ }
1748
+ function komojuBodyVerdict(body, url) {
1749
+ let target = null;
1750
+ if (url !== void 0) {
1751
+ target = komojuTarget(url);
1752
+ if (target === null)
1753
+ return refuse13("komoju_url_refused");
1754
+ }
1755
+ const value = readJson3(body);
1756
+ if (target !== null && target.kind !== "secure_token") {
1757
+ if (value !== null && target.kind === "session_pay" && tokenPay(value))
1758
+ return CONTINUE6;
1759
+ return refuse13(value !== null && carriesCard(value.payment_details) ? "komoju_fallback_refused" : "komoju_body_unsupported");
1760
+ }
1761
+ if (value === null)
1762
+ return refuse13("komoju_body_unsupported");
1763
+ if (target === null && tokenPay(value))
1764
+ return CONTINUE6;
1765
+ if (target === null && !Object.prototype.hasOwnProperty.call(value, "return_url") && carriesCard(value.payment_details)) {
1766
+ return refuse13("komoju_fallback_refused");
1767
+ }
1768
+ const code = judgeSecureToken(value);
1769
+ return code === null ? CARD12 : refuse13(code);
1770
+ }
1771
+ // src/paygent.js
1772
+ var PAYGENT_PSP = "paygent";
1773
+ var PAYGENT_TOKEN_HOSTS = /* @__PURE__ */ Object.freeze({
1774
+ production: Object.freeze(["token.paygent.co.jp"]),
1775
+ sandbox: Object.freeze(["sandbox.paygent.co.jp"])
1776
+ });
1777
+ var PAYGENT_TOKEN_PATH = "/n/token/request";
1778
+ var PAYGENT_BODY_KEYS = /* @__PURE__ */ Object.freeze([
1779
+ "merchant_id",
1780
+ "token_generate_key",
1781
+ "card_number",
1782
+ "card_expire_year",
1783
+ "card_expire_month",
1784
+ "card_cvc",
1785
+ "card_name"
1786
+ ]);
1787
+ var BODY_LIMIT10 = 2048;
1788
+ var URL_LIMIT5 = 128;
1789
+ var MERCHANT_ID = /^[0-9]{5,6}$/;
1790
+ var LIVE_KEY = /^live_[A-Za-z0-9]{24}$/;
1791
+ var SANDBOX_KEY = /^(?!live_)[a-z]{1,8}_[A-Za-z0-9]{24}$/;
1792
+ var NUMBER3 = /^[0-9]{12,19}$/;
1793
+ var YEAR5 = /^[0-9]{2}$/;
1794
+ var MONTH5 = /^(?:0?[1-9]|1[0-2])$/;
1795
+ var SECURITY_CODE9 = /^[0-9]{3,4}$/;
1796
+ var PAGE_HOLDER = /^(?:[A-Za-z][A-Za-z .'-]{0,44})?$/;
1797
+ var refuse14 = (code) => Object.freeze({ verdict: "refuse", code });
1798
+ var CARD13 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
1799
+ function paygentEnvironment(url) {
1800
+ if (typeof url !== "string" || url.length > URL_LIMIT5 || url.includes("?") || url.includes("#"))
1801
+ return null;
1802
+ let parsed;
1803
+ try {
1804
+ parsed = new URL(url);
1805
+ }
1806
+ catch {
1807
+ return null;
1808
+ }
1809
+ if (parsed.href !== url || parsed.protocol !== "https:" || parsed.port || parsed.username || parsed.password || parsed.pathname !== PAYGENT_TOKEN_PATH)
1810
+ return null;
1811
+ if (PAYGENT_TOKEN_HOSTS.production.includes(parsed.hostname))
1812
+ return "production";
1813
+ if (PAYGENT_TOKEN_HOSTS.sandbox.includes(parsed.hostname))
1814
+ return "sandbox";
1815
+ return null;
1816
+ }
1817
+ function readBody5(body) {
1818
+ if (typeof body !== "string" || body === "" || body.length > BODY_LIMIT10)
1819
+ return null;
1820
+ try {
1821
+ const pairs = body.split("&").map((chunk) => {
1822
+ const eq = chunk.indexOf("=");
1823
+ if (eq <= 0)
1824
+ throw new URIError("not a pair");
1825
+ return [chunk.slice(0, eq), decodeURIComponent(chunk.slice(eq + 1))];
1826
+ });
1827
+ return pairs.map(([key, value]) => `${key}=${encodeURIComponent(value)}`).join("&") === body ? pairs : null;
1828
+ }
1829
+ catch {
1830
+ return null;
1831
+ }
1832
+ }
1833
+ var CVC_ONLY_KEYS = /* @__PURE__ */ Object.freeze(["merchant_id", "token_generate_key", "card_cvc", "cvc_only_flg"]);
1834
+ var sameKeys6 = (pairs, keys) => pairs.length === keys.length && pairs.every(([key], at) => key === keys[at]);
1835
+ function judgeBody3(body) {
1836
+ const pairs = readBody5(body);
1837
+ if (pairs === null)
1838
+ return { code: "paygent_body_unsupported", pairs: null };
1839
+ if (sameKeys6(pairs, CVC_ONLY_KEYS))
1840
+ return { code: "paygent_cvc_only", pairs: null };
1841
+ if (!sameKeys6(pairs, PAYGENT_BODY_KEYS))
1842
+ return { code: "paygent_body_unsupported", pairs: null };
1843
+ const value = Object.fromEntries(pairs);
1844
+ if (!MERCHANT_ID.test(value.merchant_id) || !(LIVE_KEY.test(value.token_generate_key) || SANDBOX_KEY.test(value.token_generate_key)) || !NUMBER3.test(value.card_number) || !YEAR5.test(value.card_expire_year) || !MONTH5.test(value.card_expire_month) || !SECURITY_CODE9.test(value.card_cvc) || !PAGE_HOLDER.test(value.card_name)) {
1845
+ return { code: "paygent_body_unsupported", pairs: null };
1846
+ }
1847
+ return { code: null, pairs };
1848
+ }
1849
+ function paygentBodyVerdict(body) {
1850
+ const { code } = judgeBody3(body);
1851
+ return code === null ? CARD13 : refuse14(code);
1852
+ }
1853
+ function paygentRequestVerdict(url, body) {
1854
+ const environment2 = paygentEnvironment(url);
1855
+ if (environment2 === null)
1856
+ return refuse14("paygent_url_refused");
1857
+ const { code, pairs } = judgeBody3(body);
1858
+ if (code !== null)
1859
+ return refuse14(code);
1860
+ const key = pairs[1][1];
1861
+ return (environment2 === "production" ? LIVE_KEY : SANDBOX_KEY).test(key) ? CARD13 : refuse14("paygent_key_environment");
1862
+ }
1863
+ // src/multipart-form.js
1864
+ var BODY_LIMIT11 = 65536;
1865
+ var CRLF = "\r\n";
1866
+ var BOUNDARY_CHARACTERS = "[A-Za-z0-9'+_.-]{1,70}";
1867
+ var BOUNDARY = new RegExp(`^${BOUNDARY_CHARACTERS}$`);
1868
+ var CONTENT_TYPE = new RegExp(`^multipart/form-data; ?boundary=(${BOUNDARY_CHARACTERS})$`, "i");
1869
+ var DISPOSITION = /^content-disposition: ?form-data; name="([^"\\\r\n]*)"$/i;
1870
+ var FILE_HINT = /^content-disposition:.*;\s*filename\*?=|^content-type:/i;
1871
+ var refusal = (code) => Object.freeze({ refusal: code });
1872
+ var listed = (list, name) => Array.isArray(list) && list.includes(name);
1873
+ function multipartBoundary(contentType) {
1874
+ const match = typeof contentType === "string" ? CONTENT_TYPE.exec(contentType) : null;
1875
+ return match ? match[1] : null;
1876
+ }
1877
+ function boundaryOf(body, contentType) {
1878
+ const lineEnd = body.indexOf(CRLF);
1879
+ const firstLine = body.startsWith("--") && lineEnd !== -1 ? body.slice(2, lineEnd) : null;
1880
+ if (firstLine === null || !BOUNDARY.test(firstLine))
1881
+ return null;
1882
+ if (contentType === void 0 || contentType === null)
1883
+ return firstLine;
1884
+ return multipartBoundary(contentType) === firstLine ? firstLine : null;
1885
+ }
1886
+ function readMultipartForm(body, contentType) {
1887
+ if (typeof body !== "string" || body.length > BODY_LIMIT11)
1888
+ return refusal("multipart_not_form");
1889
+ const boundary = boundaryOf(body, contentType);
1890
+ if (boundary === null)
1891
+ return refusal("multipart_not_form");
1892
+ const dash = `--${boundary}`;
1893
+ const delimiter = `${CRLF}${dash}`;
1894
+ const parts = [];
1895
+ let position = dash.length + CRLF.length;
1896
+ for (;;) {
1897
+ const headerEnd = body.indexOf(`${CRLF}${CRLF}`, position);
1898
+ if (headerEnd === -1)
1899
+ return refusal("multipart_not_form");
1900
+ const headers = body.slice(position, headerEnd).split(CRLF);
1901
+ if (headers.some((line) => FILE_HINT.test(line)))
1902
+ return refusal("multipart_file_part");
1903
+ const disposition = headers.length === 1 ? DISPOSITION.exec(headers[0]) : null;
1904
+ if (!disposition)
1905
+ return refusal("multipart_not_form");
1906
+ const start = headerEnd + 2 * CRLF.length;
1907
+ const end = body.indexOf(delimiter, start);
1908
+ if (end === -1)
1909
+ return refusal("multipart_not_form");
1910
+ parts.push(Object.freeze({ name: disposition[1], value: body.slice(start, end), start, end }));
1911
+ position = end + delimiter.length;
1912
+ if (body.startsWith("--", position)) {
1913
+ const rest = body.slice(position + 2);
1914
+ return rest === "" || rest === CRLF ? Object.freeze({ boundary, parts: Object.freeze(parts) }) : refusal("multipart_not_form");
1915
+ }
1916
+ if (!body.startsWith(CRLF, position))
1917
+ return refusal("multipart_not_form");
1918
+ position += CRLF.length;
1919
+ }
1920
+ }
1921
+ function soundRule(rule) {
1922
+ if (!rule || typeof rule !== "object" || !Array.isArray(rule.parts) || !Array.isArray(rule.card) || rule.card.length === 0)
1923
+ return false;
1924
+ const names = [...rule.parts, ...rule.card];
1925
+ if (!names.every((name) => typeof name === "string" && name !== ""))
1926
+ return false;
1927
+ return new Set(rule.card).size === rule.card.length && rule.card.every((name) => rule.parts.includes(name));
1928
+ }
1929
+ function judge(body, contentType, rule) {
1930
+ if (!soundRule(rule))
1931
+ throw new TypeError("A multipart rule lists its part names and, among them, its card parts.");
1932
+ const read = readMultipartForm(body, contentType);
1933
+ if (read.refusal)
1934
+ return read;
1935
+ if (read.parts.some((part) => !listed(rule.parts, part.name)))
1936
+ return refusal("multipart_unknown_part");
1937
+ for (const name of rule.card) {
1938
+ const count = read.parts.filter((part) => part.name === name).length;
1939
+ if (count === 0)
1940
+ return refusal("multipart_missing_card_part");
1941
+ if (count > 1)
1942
+ return refusal("multipart_duplicate_card_part");
1943
+ }
1944
+ return read;
1945
+ }
1946
+ function multipartFormRefusal(body, contentType, rule) {
1947
+ const read = judge(body, contentType, rule);
1948
+ return read.refusal ?? null;
1949
+ }
1950
+ // src/pay-nl.js
1951
+ var PAY_NL_PSP = "pay_nl";
1952
+ var PAY_NL_TOKEN_URL = "https://payment.pay.nl/v1/Payment/getCardToken/json";
1953
+ var PAY_NL_PARTS = /* @__PURE__ */ Object.freeze([
1954
+ "serviceId",
1955
+ "requestToken",
1956
+ "payment[method]",
1957
+ "payment[card][number]",
1958
+ "payment[card][name]",
1959
+ "payment[card][cvc]",
1960
+ "payment[card][expire_month]",
1961
+ "payment[card][expire_year]"
1962
+ ]);
1963
+ var PAY_NL_CARD_PARTS = /* @__PURE__ */ Object.freeze([
1964
+ "payment[card][number]",
1965
+ "payment[card][name]",
1966
+ "payment[card][cvc]",
1967
+ "payment[card][expire_month]",
1968
+ "payment[card][expire_year]"
1969
+ ]);
1970
+ var pin4 = (fields) => Object.freeze({ ...fields, origins: Object.freeze([...fields.origins]), serviceIds: Object.freeze([...fields.serviceIds]) });
1971
+ var PAY_NL_MERCHANT_PINS = /* @__PURE__ */ Object.freeze([
1972
+ pin4({ id: "weeztix", merchant: "Weeztix", origins: ["https://shop.weeztix.com"], serviceIds: ["SL-6399-2740"] })
1973
+ ]);
1974
+ var RULE = /* @__PURE__ */ Object.freeze({ parts: PAY_NL_PARTS, card: PAY_NL_CARD_PARTS });
1975
+ var SERVICE_ID = /^SL-\d{4}-\d{4}$/;
1976
+ var REQUEST_TOKEN = /^[0-9a-f]{40}$/i;
1977
+ var NUMBER4 = /^[0-9]{8,19}$/;
1978
+ var HOLDER3 = /^\p{L}+(?: \p{L}+)*$/u;
1979
+ var HOLDER_LIMIT2 = 256;
1980
+ var SECURITY_CODE10 = /^[0-9]{3,4}$/;
1981
+ var MONTH6 = /^(?:0[1-9]|1[0-2])$/;
1982
+ var YEAR6 = /^[0-9]{2}$/;
1983
+ var refuse15 = (code) => Object.freeze({ verdict: "refuse", code });
1984
+ var CARD14 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
1985
+ function isPayNlTokenUrl(url) {
1986
+ return url === PAY_NL_TOKEN_URL;
1987
+ }
1988
+ function readBody6(body, contentType) {
1989
+ if (multipartFormRefusal(body, contentType, RULE) !== null)
1990
+ return null;
1991
+ const { parts } = readMultipartForm(body, contentType);
1992
+ if (parts.length !== PAY_NL_PARTS.length || !parts.every((part, at) => part.name === PAY_NL_PARTS[at]))
1993
+ return null;
1994
+ const value = Object.fromEntries(parts.map((part) => [part.name, part.value]));
1995
+ const name = value["payment[card][name]"];
1996
+ if (!SERVICE_ID.test(value.serviceId) || !REQUEST_TOKEN.test(value.requestToken) || value["payment[method]"] !== "card" || !NUMBER4.test(value["payment[card][number]"]) || name.length > HOLDER_LIMIT2 || !HOLDER3.test(name) || !SECURITY_CODE10.test(value["payment[card][cvc]"]) || !MONTH6.test(value["payment[card][expire_month]"]) || !YEAR6.test(value["payment[card][expire_year]"]))
1997
+ return null;
1998
+ return value;
1999
+ }
2000
+ function payNlBodyVerdict(body, contentType) {
2001
+ return readBody6(body, contentType) === null ? refuse15("pay_nl_body_unsupported") : CARD14;
2002
+ }
2003
+ var ERROR_KEYS = /* @__PURE__ */ Object.freeze(["errorId", "errorTag", "errorMessage", "errorFieldName"]);
2004
+ var REQUEST_KEYS = /* @__PURE__ */ Object.freeze(["result", ...ERROR_KEYS]);
2005
+ // src/revolut.js
2006
+ var REVOLUT_PSP = "revolut";
2007
+ var REVOLUT_HOSTS = /* @__PURE__ */ Object.freeze(["merchant.revolut.com", "sandbox-merchant.revolut.com"]);
2008
+ var REVOLUT_BODY_KEYS = /* @__PURE__ */ Object.freeze(["payment_method", "customer", "amount", "channel"]);
2009
+ var REVOLUT_CARD_FIELD_KEYS = /* @__PURE__ */ Object.freeze([
2010
+ "type",
2011
+ "number",
2012
+ "expiry_month",
2013
+ "expiry_year",
2014
+ "cvv",
2015
+ "kount_session_id",
2016
+ "billing_address",
2017
+ "cardholder_name",
2018
+ "shipping_address",
2019
+ "save_for",
2020
+ "environment"
2021
+ ]);
2022
+ var REVOLUT_CARD_POPUP_KEYS = /* @__PURE__ */ Object.freeze([
2023
+ "type",
2024
+ "number",
2025
+ "expiry_month",
2026
+ "expiry_year",
2027
+ "cvv",
2028
+ "kount_session_id",
2029
+ "cardholder_name",
2030
+ "billing_address",
2031
+ "shipping_address",
2032
+ "save_for",
2033
+ "environment"
2034
+ ]);
2035
+ var REVOLUT_CHANNELS = /* @__PURE__ */ Object.freeze(["WEB_SDK", "REV_CHECKOUT", "HOSTED_PAYMENT_PAGE"]);
2036
+ var BODY_LIMIT12 = 16384;
2037
+ var URL_LIMIT6 = 128;
2038
+ var UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;
2039
+ var PAYMENTS_PATH = /^\/api\/public\/orders\/([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})\/payments$/;
2040
+ var CARD_NUMBER8 = /^[0-9]{12,19}$/;
2041
+ var SECURITY_CODE11 = /^[0-9]{3,4}$/;
2042
+ var KOUNT_SESSION = /^[0-9a-f]{32}$/;
2043
+ var AMOUNT_LIMIT = 1e11;
2044
+ var ADDRESS_KEYS = /* @__PURE__ */ Object.freeze(["country", "region", "city", "postcode", "street_line_1", "street_line_2"]);
2045
+ var ENVIRONMENT_KEYS = /* @__PURE__ */ Object.freeze([
2046
+ "type",
2047
+ "color_depth",
2048
+ "screen_width",
2049
+ "screen_height",
2050
+ "java_enabled",
2051
+ "time_zone_utc_offset",
2052
+ "challenge_window_width",
2053
+ "browser_url",
2054
+ "referrer_url"
2055
+ ]);
2056
+ var NEW_CUSTOMER_KEYS = /* @__PURE__ */ Object.freeze(["type", "email", "name", "phone"]);
2057
+ var COUNTRY = /^[A-Z]{2}$/;
2058
+ var PHONE = /^\+?[0-9 \u00a0\/().-]{6,32}$/;
2059
+ var EMAIL3 = /^[^\s@]{1,64}@[^\s@]{1,255}$/;
2060
+ var TEXT_LIMIT2 = 256;
2061
+ var CONTROL5 = /[\u0000-\u001f\u007f]/;
2062
+ var CARD_MEMBER2 = /^(?:number|card_?number|cardnumber|cardnum|card_num|pan|cvv|cvc|cvv2)$/i;
2063
+ var record10 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
2064
+ var own2 = (value, key) => Object.prototype.hasOwnProperty.call(value, key);
2065
+ var inOrder = (value, keys) => {
2066
+ let at = 0;
2067
+ for (const name of Object.keys(value)) {
2068
+ while (at < keys.length && keys[at] !== name)
2069
+ at += 1;
2070
+ if (at === keys.length)
2071
+ return false;
2072
+ at += 1;
2073
+ }
2074
+ return true;
2075
+ };
2076
+ var wellFormed = (value) => {
2077
+ try {
2078
+ encodeURIComponent(value);
2079
+ return true;
2080
+ }
2081
+ catch {
2082
+ return false;
2083
+ }
2084
+ };
2085
+ var plainText2 = (value) => typeof value === "string" && value.length >= 1 && value.length <= TEXT_LIMIT2 && !CONTROL5.test(value) && (value.match(/[0-9]/g) ?? []).length < 12 && wellFormed(value);
2086
+ var between = (value, min, max) => Number.isSafeInteger(value) && value >= min && value <= max;
2087
+ var NETWORK = /^(?:4[0-9]{15}|4[0-9]{12}|5[1-5][0-9]{14}|2(?:2(?:2[1-9]|[3-9][0-9])|[3-6][0-9]{2}|7(?:[01][0-9]|20))[0-9]{12}|3[47][0-9]{13})$/;
2088
+ var luhn2 = (digits2) => {
2089
+ let sum = 0;
2090
+ for (let at = 0; at < digits2.length; at += 1) {
2091
+ let d = digits2.charCodeAt(digits2.length - 1 - at) - 48;
2092
+ if (at % 2 === 1) {
2093
+ d *= 2;
2094
+ if (d > 9)
2095
+ d -= 9;
2096
+ }
2097
+ sum += d;
2098
+ }
2099
+ return sum % 10 === 0;
2100
+ };
2101
+ var ANY_NETWORK = /^[2-6][0-9]{12,18}$/;
2102
+ var holdsCardShape = (text3, shape = NETWORK) => (text3.match(/[0-9]{13,}/g) ?? []).some((run) => run.length > 19 || shape.test(run) && luhn2(run));
2103
+ var phone = (value) => typeof value === "string" && PHONE.test(value) && (value.match(/[0-9]/g) ?? []).length >= 6 && (value.match(/[0-9]/g) ?? []).length <= 15;
2104
+ var refuse16 = (code) => Object.freeze({ verdict: "refuse", code });
2105
+ var CARD15 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
2106
+ var CONTINUE7 = /* @__PURE__ */ Object.freeze({ verdict: "continue" });
2107
+ function revolutPaymentsTarget(url) {
2108
+ if (typeof url !== "string" || url.length > URL_LIMIT6 || url.includes("?") || url.includes("#"))
2109
+ return null;
2110
+ let parsed;
2111
+ try {
2112
+ parsed = new URL(url);
2113
+ }
2114
+ catch {
2115
+ return null;
2116
+ }
2117
+ if (parsed.href !== url || parsed.protocol !== "https:" || parsed.port || parsed.username || parsed.password || !REVOLUT_HOSTS.includes(parsed.hostname))
2118
+ return null;
2119
+ const match = PAYMENTS_PATH.exec(parsed.pathname);
2120
+ return match ? Object.freeze({ host: parsed.hostname, order: match[1] }) : null;
2121
+ }
2122
+ function isRevolutPaymentsUrl(url) {
2123
+ return revolutPaymentsTarget(url) !== null;
2124
+ }
2125
+ function readBody7(body) {
2126
+ if (typeof body !== "string" || body === "" || body.length > BODY_LIMIT12)
2127
+ return null;
2128
+ let value;
2129
+ try {
2130
+ value = JSON.parse(body);
2131
+ if (!record10(value) || JSON.stringify(value) !== body)
2132
+ return null;
2133
+ }
2134
+ catch {
2135
+ return null;
2136
+ }
2137
+ return value;
2138
+ }
2139
+ function address(value) {
2140
+ if (!record10(value) || !inOrder(value, ADDRESS_KEYS))
2141
+ return false;
2142
+ const names = Object.keys(value);
2143
+ if (!names.some((key) => typeof value[key] === "string" && value[key].trim() !== ""))
2144
+ return false;
2145
+ return names.every((key) => value[key] === "" || (key === "country" ? typeof value[key] === "string" && COUNTRY.test(value[key]) : plainText2(value[key])));
2146
+ }
2147
+ function pageUrl(value) {
2148
+ if (typeof value !== "string" || value.length > 2048 || CONTROL5.test(value) || holdsCardShape(value, ANY_NETWORK) || !wellFormed(value))
2149
+ return false;
2150
+ let parsed;
2151
+ try {
2152
+ parsed = new URL(value);
2153
+ }
2154
+ catch {
2155
+ return false;
2156
+ }
2157
+ return parsed.protocol === "https:" || parsed.protocol === "http:";
2158
+ }
2159
+ function referrerOrigin(value) {
2160
+ if (value === "" || value === "null")
2161
+ return true;
2162
+ if (typeof value !== "string" || value.length > 512 || holdsCardShape(value, ANY_NETWORK))
2163
+ return false;
2164
+ let parsed;
2165
+ try {
2166
+ parsed = new URL(value);
2167
+ }
2168
+ catch {
2169
+ return false;
2170
+ }
2171
+ return (parsed.protocol === "https:" || parsed.protocol === "http:") && parsed.origin === value;
2172
+ }
2173
+ function environment(value) {
2174
+ if (!record10(value) || !inOrder(value, ENVIRONMENT_KEYS))
2175
+ return false;
2176
+ return value.type === "browser" && between(value.color_depth, 0, 256) && between(value.screen_width, 0, 1e5) && between(value.screen_height, 0, 1e5) && typeof value.java_enabled === "boolean" && between(value.time_zone_utc_offset, -1440, 1440) && between(value.challenge_window_width, 1, 1e4) && (!own2(value, "browser_url") || pageUrl(value.browser_url)) && (!own2(value, "referrer_url") || referrerOrigin(value.referrer_url));
2177
+ }
2178
+ function customer(value) {
2179
+ if (!record10(value))
2180
+ return false;
2181
+ if (value.type === "existing") {
2182
+ const names = Object.keys(value);
2183
+ return names.length === 2 && names[0] === "type" && names[1] === "id" && typeof value.id === "string" && UUID.test(value.id);
2184
+ }
2185
+ if (value.type !== "new" || !inOrder(value, NEW_CUSTOMER_KEYS) || !own2(value, "email"))
2186
+ return false;
2187
+ if (typeof value.email !== "string" || !EMAIL3.test(value.email) || !plainText2(value.email))
2188
+ return false;
2189
+ if (own2(value, "name") && !plainText2(value.name))
2190
+ return false;
2191
+ return !own2(value, "phone") || phone(value.phone);
2192
+ }
2193
+ function cardMethod(value) {
2194
+ if (!record10(value) || value.type !== "card")
2195
+ return "revolut_body_unsupported";
2196
+ if (!inOrder(value, REVOLUT_CARD_FIELD_KEYS) && !inOrder(value, REVOLUT_CARD_POPUP_KEYS))
2197
+ return "revolut_body_unsupported";
2198
+ if (typeof value.number !== "string" || !CARD_NUMBER8.test(value.number) || !between(value.expiry_month, 1, 12) || !between(value.expiry_year, 2e3, 2099) || typeof value.cvv !== "string" || !SECURITY_CODE11.test(value.cvv))
2199
+ return "revolut_body_unsupported";
2200
+ if (!own2(value, "environment") || !environment(value.environment))
2201
+ return "revolut_body_unsupported";
2202
+ if (own2(value, "kount_session_id") && (typeof value.kount_session_id !== "string" || !KOUNT_SESSION.test(value.kount_session_id))) {
2203
+ return "revolut_body_unsupported";
2204
+ }
2205
+ for (const key of ["billing_address", "shipping_address"]) {
2206
+ if (own2(value, key) && !address(value[key]))
2207
+ return "revolut_body_unsupported";
2208
+ }
2209
+ if (own2(value, "cardholder_name") && !plainText2(value.cardholder_name))
2210
+ return "revolut_body_unsupported";
2211
+ if (own2(value, "save_for")) {
2212
+ if (value.save_for === "CUSTOMER" || value.save_for === "MERCHANT")
2213
+ return "revolut_card_on_file";
2214
+ if (value.save_for !== "NONE")
2215
+ return "revolut_body_unsupported";
2216
+ }
2217
+ return null;
2218
+ }
2219
+ function namesCardValue2(parsed) {
2220
+ const pending = record10(parsed) || Array.isArray(parsed) ? [parsed] : [];
2221
+ while (pending.length > 0) {
2222
+ const node = pending.pop();
2223
+ for (const key of Object.keys(node)) {
2224
+ if (!Array.isArray(node) && CARD_MEMBER2.test(key))
2225
+ return true;
2226
+ const value = node[key];
2227
+ if (value !== null && typeof value === "object")
2228
+ pending.push(value);
2229
+ }
2230
+ }
2231
+ return false;
2232
+ }
2233
+ function revolutBodyVerdict(body) {
2234
+ const value = readBody7(body);
2235
+ if (value === null) {
2236
+ return body === void 0 || body === null || body === "" ? CONTINUE7 : refuse16("revolut_body_unsupported");
2237
+ }
2238
+ const method = record10(value.payment_method) ? value.payment_method.type : void 0;
2239
+ if (method !== "card")
2240
+ return namesCardValue2(value) ? refuse16("revolut_body_unsupported") : CONTINUE7;
2241
+ if (!inOrder(value, REVOLUT_BODY_KEYS) || Object.keys(value).length !== REVOLUT_BODY_KEYS.length)
2242
+ return refuse16("revolut_body_unsupported");
2243
+ const code = cardMethod(value.payment_method);
2244
+ if (code !== null)
2245
+ return refuse16(code);
2246
+ if (!customer(value.customer) || !between(value.amount, 1, AMOUNT_LIMIT) || !REVOLUT_CHANNELS.includes(value.channel)) {
2247
+ return refuse16("revolut_body_unsupported");
2248
+ }
2249
+ return CARD15;
2250
+ }
2251
+ // src/sumup.js
2252
+ var SUMUP_PSP = "sumup";
2253
+ var SUMUP_API_HOST = "api.sumup.com";
2254
+ var SUMUP_CHECKOUT_PATH = "/v0.2/checkouts/";
2255
+ var BODY_LIMIT13 = 16384;
2256
+ var CHECKOUT_ID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-5][0-9a-f]{3}-[089ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
2257
+ var ROOT_KEYS5 = /* @__PURE__ */ Object.freeze([
2258
+ "payment_type",
2259
+ "device_information",
2260
+ "method_details",
2261
+ "personal_details",
2262
+ "card",
2263
+ "installments",
2264
+ "mandate",
2265
+ "lxn_session_token",
2266
+ "customer_details",
2267
+ "sca_experience"
2268
+ ]);
2269
+ var CARD_KEYS7 = /* @__PURE__ */ Object.freeze(["zip_code", "name", "number", "expiry_month", "expiry_year", "cvv"]);
2270
+ var PERSONAL_KEYS = /* @__PURE__ */ Object.freeze(["first_name", "last_name", "email", "address", "birth_date", "phone"]);
2271
+ var ADDRESS_KEYS2 = /* @__PURE__ */ Object.freeze(["country", "city", "line1", "line2", "postal_code", "state"]);
2272
+ var CUSTOMER_KEYS = /* @__PURE__ */ Object.freeze(["first_name", "last_name", "email", "note_for_merchant"]);
2273
+ var CARD_NUMBER9 = /^[0-9]{12,19}$/;
2274
+ var MONTH7 = /^(?:0[1-9]|1[0-2])$/;
2275
+ var YEAR7 = /^(?:[0-9]{2}|[0-9]{4})$/;
2276
+ var CODE2 = /^[0-9]{3,4}$/;
2277
+ var BASE643 = /^[A-Za-z0-9+/]{4,4096}={0,2}$/;
2278
+ var BASE64_ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
2279
+ var DEVICE_KEYS2 = /* @__PURE__ */ Object.freeze([
2280
+ "user_agent",
2281
+ "language",
2282
+ "timezone_offset",
2283
+ "screen_width",
2284
+ "screen_height",
2285
+ "color_depth",
2286
+ "modal_width",
2287
+ "modal_height",
2288
+ "adblock",
2289
+ "realIp",
2290
+ "route"
2291
+ ]);
2292
+ var RISK_TOKEN = /^[A-Za-z0-9_+/=-]+\.[A-Za-z0-9_+/=-]+\.[A-Za-z0-9_+/=-]*$/;
2293
+ var RISK_TOKEN_LIMIT = 4096;
2294
+ var PAN_LIKE4 = /(?:[0-9][ _.:-]*){12,}/;
2295
+ var DATE = /^[0-9]{4}-[0-9]{2}-[0-9]{2}$/;
2296
+ var COUNTRY2 = /^[A-Z]{2}$/;
2297
+ var PHONE2 = /^[ #0-9_+\/().-]{1,32}$/;
2298
+ var CARD_PAYMENT2 = "card";
2299
+ var SCA_EXPERIENCE = "iframe";
2300
+ var record11 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
2301
+ var refuse17 = (code) => Object.freeze({ verdict: "refuse", code });
2302
+ var CARD16 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
2303
+ function orderedSubset(value, keys) {
2304
+ let at = -1;
2305
+ for (const key of Object.keys(value)) {
2306
+ const next = keys.indexOf(key);
2307
+ if (next <= at)
2308
+ return false;
2309
+ at = next;
2310
+ }
2311
+ return true;
2312
+ }
2313
+ function luhn3(digits2) {
2314
+ let sum = 0;
2315
+ for (let at = 0; at < digits2.length; at += 1) {
2316
+ let digit = Number(digits2[digits2.length - 1 - at]);
2317
+ if (at % 2 === 1) {
2318
+ digit *= 2;
2319
+ if (digit > 9)
2320
+ digit -= 9;
2321
+ }
2322
+ sum += digit;
2323
+ }
2324
+ return sum % 10 === 0 && sum > 0;
2325
+ }
2326
+ var printable = (value) => [...value].every((ch) => ch.charCodeAt(0) >= 32 && ch.charCodeAt(0) !== 127);
2327
+ function typed(value, limit = 256) {
2328
+ return typeof value === "string" && value.length >= 1 && value.length <= limit && !PAN_LIKE4.test(value) && printable(value);
2329
+ }
2330
+ function decodeBase64(text3) {
2331
+ if (typeof text3 !== "string" || !BASE643.test(text3) || text3.length % 4 !== 0)
2332
+ return null;
2333
+ let bits = 0;
2334
+ let value = 0;
2335
+ let out = "";
2336
+ for (const ch of text3.replace(/=+$/, "")) {
2337
+ value = (value << 6 | BASE64_ALPHABET.indexOf(ch)) & 16777215;
2338
+ bits += 6;
2339
+ if (bits >= 8) {
2340
+ bits -= 8;
2341
+ out += String.fromCharCode(value >> bits & 255);
2342
+ }
2343
+ }
2344
+ return out;
2345
+ }
2346
+ function soundDevice(text3) {
2347
+ const json = decodeBase64(text3);
2348
+ if (json === null)
2349
+ return false;
2350
+ let value;
2351
+ try {
2352
+ value = JSON.parse(json);
2353
+ if (JSON.stringify(value) !== json)
2354
+ return false;
2355
+ }
2356
+ catch {
2357
+ return false;
2358
+ }
2359
+ if (!record11(value) || Object.keys(value).join() !== "deviceId,components" || typeof value.deviceId !== "string" || value.deviceId.length > 256 || PAN_LIKE4.test(value.deviceId) || !printable(value.deviceId) || !Array.isArray(value.components) || value.components.length !== DEVICE_KEYS2.length) {
2360
+ return false;
2361
+ }
2362
+ return value.components.every((component, at) => record11(component) && Object.keys(component).join() === "key,value" && component.key === DEVICE_KEYS2[at] && typeof component.value === "string" && component.value.length <= 1024 && !PAN_LIKE4.test(component.value) && printable(component.value));
2363
+ }
2364
+ var soundRiskToken = (token) => typeof token === "string" && token.length <= RISK_TOKEN_LIMIT && RISK_TOKEN.test(token) && !PAN_LIKE4.test(token);
2365
+ function sumupCheckoutUrl(url) {
2366
+ if (typeof url !== "string" || url.length > 256 || url.includes("#") || url.includes("?"))
2367
+ return null;
2368
+ let parsed;
2369
+ try {
2370
+ parsed = new URL(url);
2371
+ }
2372
+ catch {
2373
+ return null;
2374
+ }
2375
+ if (parsed.href !== url || parsed.protocol !== "https:" || parsed.port || parsed.username || parsed.password)
2376
+ return null;
2377
+ if (parsed.hostname !== SUMUP_API_HOST || !parsed.pathname.startsWith(SUMUP_CHECKOUT_PATH))
2378
+ return null;
2379
+ const checkoutId = parsed.pathname.slice(SUMUP_CHECKOUT_PATH.length);
2380
+ return CHECKOUT_ID.test(checkoutId) ? Object.freeze({ checkoutId }) : null;
2381
+ }
2382
+ function readBody8(body) {
2383
+ if (typeof body !== "string" || body === "" || body.length > BODY_LIMIT13)
2384
+ return null;
2385
+ let value;
2386
+ try {
2387
+ value = JSON.parse(body);
2388
+ if (!record11(value) || JSON.stringify(value) !== body)
2389
+ return null;
2390
+ }
2391
+ catch {
2392
+ return null;
2393
+ }
2394
+ return value;
2395
+ }
2396
+ function soundCard(card) {
2397
+ if (!record11(card) || !orderedSubset(card, CARD_KEYS7))
2398
+ return false;
2399
+ if (typeof card.number !== "string" || !CARD_NUMBER9.test(card.number) || !luhn3(card.number))
2400
+ return false;
2401
+ if (typeof card.expiry_month !== "string" || !MONTH7.test(card.expiry_month))
2402
+ return false;
2403
+ if (typeof card.expiry_year !== "string" || !YEAR7.test(card.expiry_year))
2404
+ return false;
2405
+ if (typeof card.cvv !== "string" || !CODE2.test(card.cvv))
2406
+ return false;
2407
+ if (card.name !== void 0 && (!typed(card.name, 129) || /[0-9]/.test(card.name)))
2408
+ return false;
2409
+ if (card.zip_code !== void 0 && !typed(card.zip_code, 10))
2410
+ return false;
2411
+ return true;
2412
+ }
2413
+ function soundPersonal(details) {
2414
+ if (!record11(details) || !orderedSubset(details, PERSONAL_KEYS) || Object.keys(details).length === 0)
2415
+ return false;
2416
+ for (const key of ["first_name", "last_name", "email"]) {
2417
+ if (details[key] !== void 0 && !typed(details[key]))
2418
+ return false;
2419
+ }
2420
+ if (details.birth_date !== void 0 && (typeof details.birth_date !== "string" || !DATE.test(details.birth_date)))
2421
+ return false;
2422
+ if (details.phone !== void 0 && (typeof details.phone !== "string" || !PHONE2.test(details.phone) || (details.phone.match(/[0-9]/g) ?? []).length > 15))
2423
+ return false;
2424
+ if (details.address === void 0)
2425
+ return true;
2426
+ const address2 = details.address;
2427
+ if (!record11(address2) || !orderedSubset(address2, ADDRESS_KEYS2) || Object.keys(address2).length === 0)
2428
+ return false;
2429
+ if (address2.country !== void 0 && (typeof address2.country !== "string" || !COUNTRY2.test(address2.country)))
2430
+ return false;
2431
+ return ["city", "line1", "line2", "postal_code", "state"].every((key) => address2[key] === void 0 || typed(address2[key]));
2432
+ }
2433
+ function soundCustomer(details) {
2434
+ if (!record11(details) || !orderedSubset(details, CUSTOMER_KEYS) || Object.keys(details).length === 0)
2435
+ return false;
2436
+ return CUSTOMER_KEYS.every((key) => details[key] === void 0 || typed(details[key], key === "note_for_merchant" ? 1024 : 256));
2437
+ }
2438
+ function sumupBodyVerdict(body, url) {
2439
+ if (url !== void 0 && sumupCheckoutUrl(url) === null)
2440
+ return refuse17("sumup_url_refused");
2441
+ const value = readBody8(body);
2442
+ if (value === null || !orderedSubset(value, ROOT_KEYS5))
2443
+ return refuse17("sumup_body_unsupported");
2444
+ if (value.payment_type !== CARD_PAYMENT2 || !soundDevice(value.device_information) || !soundCard(value.card) || value.installments !== 1) {
2445
+ return refuse17("sumup_body_unsupported");
2446
+ }
2447
+ if (value.method_details !== void 0 && !(record11(value.method_details) && orderedSubset(value.method_details, ["zip_code"]) && typed(value.method_details.zip_code, 10)))
2448
+ return refuse17("sumup_body_unsupported");
2449
+ if (value.personal_details !== void 0 && !soundPersonal(value.personal_details))
2450
+ return refuse17("sumup_body_unsupported");
2451
+ if (value.customer_details !== void 0 && !soundCustomer(value.customer_details))
2452
+ return refuse17("sumup_body_unsupported");
2453
+ if (value.lxn_session_token !== void 0 && !soundRiskToken(value.lxn_session_token))
2454
+ return refuse17("sumup_body_unsupported");
2455
+ if (value.sca_experience !== void 0 && value.sca_experience !== SCA_EXPERIENCE)
2456
+ return refuse17("sumup_body_unsupported");
2457
+ if (value.mandate !== void 0)
2458
+ return refuse17("sumup_card_saving_refused");
2459
+ return CARD16;
2460
+ }
1551
2461
  // src/card-fields.js
1552
2462
  function processorGate(recognizer, url, body) {
1553
2463
  if (recognizer && recognizer.psp === LYRA_PSP)
@@ -1557,6 +2467,8 @@ function processorGate(recognizer, url, body) {
1557
2467
  return { verdict: "refuse", code: "wix_payments_url_refused" };
1558
2468
  return wixPaymentsBodyVerdict(body);
1559
2469
  }
2470
+ if (recognizer && recognizer.psp === KOMOJU_PSP)
2471
+ return komojuBodyVerdict(body, url);
1560
2472
  if (recognizer && recognizer.psp === PADDLE_VGS_PSP) {
1561
2473
  if (url !== void 0 && !isPaddleVgsCardsUrl(url))
1562
2474
  return { verdict: "refuse", code: "paddle_vgs_url_refused" };
@@ -1567,6 +2479,17 @@ function processorGate(recognizer, url, body) {
1567
2479
  return { verdict: "refuse", code: "payfast_url_refused" };
1568
2480
  return payfastBodyVerdict(body);
1569
2481
  }
2482
+ if (recognizer && recognizer.psp === PAYREXX_PSP) {
2483
+ return url !== void 0 ? payrexxGateVerdict(url, body) : payrexxBodyVerdict(body);
2484
+ }
2485
+ if (recognizer && recognizer.psp === PAYGENT_PSP) {
2486
+ return url !== void 0 ? paygentRequestVerdict(url, body) : paygentBodyVerdict(body);
2487
+ }
2488
+ if (recognizer && recognizer.psp === PAY_NL_PSP) {
2489
+ if (url !== void 0 && !isPayNlTokenUrl(url))
2490
+ return { verdict: "refuse", code: "pay_nl_url_refused" };
2491
+ return payNlBodyVerdict(body);
2492
+ }
1570
2493
  if (recognizer && recognizer.psp === PADDLE_TOKENEX_PSP) {
1571
2494
  const target = url !== void 0 ? paddleTokenexPayTarget(url) : null;
1572
2495
  if (url !== void 0 && target === null)
@@ -1581,6 +2504,13 @@ function processorGate(recognizer, url, body) {
1581
2504
  }
1582
2505
  if (recognizer && recognizer.psp === GOPAY_PSP)
1583
2506
  return gopayBodyVerdict(body, url);
2507
+ if (recognizer && recognizer.psp === REVOLUT_PSP) {
2508
+ if (url !== void 0 && !isRevolutPaymentsUrl(url))
2509
+ return { verdict: "refuse", code: "revolut_url_refused" };
2510
+ return revolutBodyVerdict(body);
2511
+ }
2512
+ if (recognizer && recognizer.psp === SUMUP_PSP)
2513
+ return sumupBodyVerdict(body, url);
1584
2514
  if (recognizer && recognizer.psp === GRAVY_PSP)
1585
2515
  return gravyBodyVerdict(body);
1586
2516
  if (recognizer && recognizer.psp === MONERIS_PSP) {
@@ -1701,21 +2631,21 @@ var KEEP_ON_FILE_REFUSAL = "Refusing to pay: this Primer payment would keep the
1701
2631
  var UNSUPPORTED_SDK_REFUSAL = "Refusing to pay: this checkout uses a Primer SDK Agentcard does not support yet. Nothing was sent.";
1702
2632
  var NETWORK_MISMATCH_REFUSAL = "Refusing to pay: this Primer payment names a card network that is not your card's. Nothing was sent.";
1703
2633
  var FILL_REFUSAL = "Could not fill the card fields for Primer. Nothing was sent.";
1704
- var BODY_LIMIT8 = 16384;
2634
+ var BODY_LIMIT14 = 16384;
1705
2635
  var RESPONSE_LIMIT = 32768;
1706
- var ROOT_KEYS5 = ["paymentInstrument", "userDescription", "tokenType", "paymentFlow"];
2636
+ var ROOT_KEYS6 = ["paymentInstrument", "userDescription", "tokenType", "paymentFlow"];
1707
2637
  var INSTRUMENT_KEYS = ["number", "cvv", "expirationMonth", "expirationYear", "cardholderName", "preferredNetwork"];
1708
2638
  var REQUIRED_INSTRUMENT_KEYS = ["number", "cvv", "expirationMonth", "expirationYear"];
1709
- var record9 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
2639
+ var record12 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
1710
2640
  var owns5 = (value, key) => Object.prototype.hasOwnProperty.call(value, key);
1711
2641
  var exact = (pattern, value) => typeof value === "string" && pattern.exec(value)?.[0] === value;
1712
2642
  var text2 = (value, max) => typeof value === "string" && value.length <= max && !/[\u0000-\u001f\u007f]/.test(value);
1713
2643
  var digits = (value, min, max) => typeof value === "string" && value.length >= min && value.length <= max && !/[^0-9]/.test(value);
1714
2644
  var panLike = (value) => /(?:[0-9][ _.:-]*){12,}/.test(value);
1715
2645
  var plain = (value, max) => text2(value, max) && !panLike(value);
1716
- var MONTH3 = /^(?:0[1-9]|1[0-2])$/;
1717
- var YEAR3 = /^20[0-9]{2}$/;
1718
- var NETWORK = /^[A-Z][A-Z_]{1,31}$/;
2646
+ var MONTH8 = /^(?:0[1-9]|1[0-2])$/;
2647
+ var YEAR8 = /^20[0-9]{2}$/;
2648
+ var NETWORK2 = /^[A-Z][A-Z_]{1,31}$/;
1719
2649
  function isPrimerTokenizeUrl(url, method = "POST") {
1720
2650
  if (method !== "POST" || typeof url !== "string" || url.length > 256 || url.includes("?") || url.includes("#"))
1721
2651
  return false;
@@ -1728,8 +2658,8 @@ function isPrimerTokenizeUrl(url, method = "POST") {
1728
2658
  }
1729
2659
  return parsed.href === url && parsed.protocol === "https:" && !parsed.port && !parsed.username && !parsed.password && !parsed.search && !parsed.hash && PRIMER_PCI_HOSTS.includes(parsed.hostname) && parsed.pathname === PRIMER_TOKENIZE_PATH;
1730
2660
  }
1731
- function judgeBody2(body) {
1732
- if (typeof body !== "string" || body === "" || body.length > BODY_LIMIT8)
2661
+ function judgeBody4(body) {
2662
+ if (typeof body !== "string" || body === "" || body.length > BODY_LIMIT14)
1733
2663
  return null;
1734
2664
  let value;
1735
2665
  try {
@@ -1738,21 +2668,21 @@ function judgeBody2(body) {
1738
2668
  catch {
1739
2669
  return null;
1740
2670
  }
1741
- if (!record9(value) || !roundTrips(value, body))
2671
+ if (!record12(value) || !roundTrips(value, body))
1742
2672
  return null;
1743
- if (!Object.keys(value).every((key) => ROOT_KEYS5.includes(key)) || !owns5(value, "paymentInstrument"))
2673
+ if (!Object.keys(value).every((key) => ROOT_KEYS6.includes(key)) || !owns5(value, "paymentInstrument"))
1744
2674
  return null;
1745
2675
  const instrument = value.paymentInstrument;
1746
- if (!record9(instrument) || !Object.keys(instrument).every((key) => INSTRUMENT_KEYS.includes(key)) || !REQUIRED_INSTRUMENT_KEYS.every((key) => owns5(instrument, key)))
2676
+ if (!record12(instrument) || !Object.keys(instrument).every((key) => INSTRUMENT_KEYS.includes(key)) || !REQUIRED_INSTRUMENT_KEYS.every((key) => owns5(instrument, key)))
1747
2677
  return null;
1748
- if (!digits(instrument.number, 12, 19) || !digits(instrument.cvv, 3, 4) || !exact(MONTH3, instrument.expirationMonth) || !exact(YEAR3, instrument.expirationYear))
2678
+ if (!digits(instrument.number, 12, 19) || !digits(instrument.cvv, 3, 4) || !exact(MONTH8, instrument.expirationMonth) || !exact(YEAR8, instrument.expirationYear))
1749
2679
  return null;
1750
- if (owns5(instrument, "cardholderName") && instrument.cardholderName !== null && !plain(instrument.cardholderName, 256) || owns5(instrument, "preferredNetwork") && instrument.preferredNetwork !== null && !exact(NETWORK, instrument.preferredNetwork) || owns5(value, "userDescription") && value.userDescription !== null && !plain(value.userDescription, 256) || owns5(value, "tokenType") && value.tokenType !== "MULTI_USE" || owns5(value, "paymentFlow") && value.paymentFlow !== "VAULT")
2680
+ if (owns5(instrument, "cardholderName") && instrument.cardholderName !== null && !plain(instrument.cardholderName, 256) || owns5(instrument, "preferredNetwork") && instrument.preferredNetwork !== null && !exact(NETWORK2, instrument.preferredNetwork) || owns5(value, "userDescription") && value.userDescription !== null && !plain(value.userDescription, 256) || owns5(value, "tokenType") && value.tokenType !== "MULTI_USE" || owns5(value, "paymentFlow") && value.paymentFlow !== "VAULT")
1751
2681
  return null;
1752
2682
  return { value, keepOnFile: owns5(value, "tokenType") || owns5(value, "paymentFlow") };
1753
2683
  }
1754
2684
  function primerBodyRefusal(body) {
1755
- const judged = judgeBody2(body);
2685
+ const judged = judgeBody4(body);
1756
2686
  if (!judged)
1757
2687
  return "unsupported";
1758
2688
  return judged.keepOnFile ? "keep_on_file" : null;
@@ -1761,17 +2691,17 @@ function isPrimerNewCardBody(body) {
1761
2691
  return primerBodyRefusal(body) === null;
1762
2692
  }
1763
2693
  function primerKeepOnFileRequested(body) {
1764
- const judged = judgeBody2(body);
2694
+ const judged = judgeBody4(body);
1765
2695
  return judged ? judged.keepOnFile : null;
1766
2696
  }
1767
2697
  var CARD_GATE = /* @__PURE__ */ Object.freeze({ psp: "primer", encoding: "json", jsonCardFields: [["paymentInstrument", "number"]] });
1768
- var CONTENT_TYPE = /^application\/json(?:;\s*charset=utf-8)?$/i;
2698
+ var CONTENT_TYPE2 = /^application\/json(?:;\s*charset=utf-8)?$/i;
1769
2699
  var LEGACY_SDK_VERSION = /^v2\.[0-9]{1,3}\.[0-9]{1,3}$/;
1770
2700
  var CLIENT_TOKEN = /^[A-Za-z0-9._~+/=-]{16,4096}$/;
1771
2701
  var REQUEST_ID = /^[A-Za-z0-9-]{1,64}$/;
1772
2702
  var API_VERSION = /^2\.[0-9]{1,2}$/;
1773
2703
  function readHeaders(headers) {
1774
- if (!record9(headers))
2704
+ if (!record12(headers))
1775
2705
  return null;
1776
2706
  const folded = /* @__PURE__ */ new Map();
1777
2707
  for (const [name, value] of Object.entries(headers)) {
@@ -1791,7 +2721,7 @@ function headersRefusal(headers) {
1791
2721
  return "unsupported";
1792
2722
  if (!exact(LEGACY_SDK_VERSION, version))
1793
2723
  return "unsupported_sdk";
1794
- if (!exact(CONTENT_TYPE, folded.get("content-type")) || !exact(CLIENT_TOKEN, folded.get("primer-client-token")) || folded.has("primer-sdk-client") && folded.get("primer-sdk-client") !== "WEB" || folded.has("x-api-version") && !exact(API_VERSION, folded.get("x-api-version")) || folded.has("primer-sdk-checkout-session-id") && !exact(REQUEST_ID, folded.get("primer-sdk-checkout-session-id")) || folded.has("x-request-id") && !exact(REQUEST_ID, folded.get("x-request-id")))
2724
+ if (!exact(CONTENT_TYPE2, folded.get("content-type")) || !exact(CLIENT_TOKEN, folded.get("primer-client-token")) || folded.has("primer-sdk-client") && folded.get("primer-sdk-client") !== "WEB" || folded.has("x-api-version") && !exact(API_VERSION, folded.get("x-api-version")) || folded.has("primer-sdk-checkout-session-id") && !exact(REQUEST_ID, folded.get("primer-sdk-checkout-session-id")) || folded.has("x-request-id") && !exact(REQUEST_ID, folded.get("x-request-id")))
1795
2725
  return "unsupported";
1796
2726
  return null;
1797
2727
  }
@@ -1818,7 +2748,7 @@ function onTokenizePath(url) {
1818
2748
  }
1819
2749
  }
1820
2750
  function primerTokenizeRefusal(request) {
1821
- if (!record9(request) || request.method !== "POST" || !isPrimerTokenizeUrl(request.url))
2751
+ if (!record12(request) || request.method !== "POST" || !isPrimerTokenizeUrl(request.url))
1822
2752
  return "unsupported";
1823
2753
  return headersRefusal(request.headers) ?? primerBodyRefusal(request.body);
1824
2754
  }
@@ -1833,7 +2763,7 @@ function primerCardOnFileRefusal(url, options, policy = PRIMER_SESSION_CARD_ON_F
1833
2763
  return "unsupported";
1834
2764
  if (new URL(url).hostname !== LIVE_PCI_HOST)
1835
2765
  return null;
1836
- return primerCardOnFileDisclosure(url, policy) && record9(options) && options.keepOnFile === true ? null : "keep_on_file";
2766
+ return primerCardOnFileDisclosure(url, policy) && record12(options) && options.keepOnFile === true ? null : "keep_on_file";
1837
2767
  }
1838
2768
  function primerRefusalMessage(reason) {
1839
2769
  if (reason === "keep_on_file")
@@ -1858,7 +2788,7 @@ function primerCardNetwork(number) {
1858
2788
  return null;
1859
2789
  }
1860
2790
  function primerNetworkRefusal(body, card) {
1861
- const judged = judgeBody2(body);
2791
+ const judged = judgeBody4(body);
1862
2792
  if (!judged)
1863
2793
  return "unsupported";
1864
2794
  const preferred = judged.value.paymentInstrument.preferredNetwork;
@@ -1868,7 +2798,7 @@ function primerNetworkRefusal(body, card) {
1868
2798
  return network !== null && network === preferred ? null : "network_mismatch";
1869
2799
  }
1870
2800
  function injectPrimerCard(body, card) {
1871
- const judged = judgeBody2(body);
2801
+ const judged = judgeBody4(body);
1872
2802
  if (!judged)
1873
2803
  throw new Error(UNSUPPORTED_REFUSAL);
1874
2804
  if (judged.keepOnFile)
@@ -1894,7 +2824,7 @@ function injectPrimerCard(body, card) {
1894
2824
  }
1895
2825
  var TOKEN3 = /^[A-Za-z0-9_-]{8,256}$/;
1896
2826
  var ERROR_ID = /^[A-Za-z][A-Za-z0-9_.-]{0,63}$/;
1897
- var CODE2 = /^[A-Z][A-Z0-9_]{0,63}$/;
2827
+ var CODE3 = /^[A-Z][A-Z0-9_]{0,63}$/;
1898
2828
  var NETWORK_NAME = /^[A-Za-z][A-Za-z0-9 _-]{0,31}$/;
1899
2829
  var RESPONSE_MONTH = /^(?:0?[1-9]|1[0-2])$/;
1900
2830
  var RESPONSE_YEAR = /^(?:[0-9]{2}|20[0-9]{2})$/;
@@ -1917,7 +2847,7 @@ function readAnswer(body) {
1917
2847
  return null;
1918
2848
  try {
1919
2849
  const value = JSON.parse(body);
1920
- return record9(value) ? value : null;
2850
+ return record12(value) ? value : null;
1921
2851
  }
1922
2852
  catch {
1923
2853
  return null;
@@ -1926,16 +2856,16 @@ function readAnswer(body) {
1926
2856
  var tokenValue = (value) => exact(TOKEN3, value) && !panLike(value);
1927
2857
  var optional = (value, key, check) => !owns5(value, key) || value[key] === null || check(value[key]);
1928
2858
  function cardDetails(data) {
1929
- if (!record9(data) || !exact(/^[0-9]{4}$/, data.last4Digits))
2859
+ if (!record12(data) || !exact(/^[0-9]{4}$/, data.last4Digits))
1930
2860
  return null;
1931
- if (!optional(data, "first6Digits", (v) => exact(/^[0-9]{6}$/, v)) || !optional(data, "expirationMonth", (v) => exact(RESPONSE_MONTH, v)) || !optional(data, "expirationYear", (v) => exact(RESPONSE_YEAR, v)) || !optional(data, "cardholderName", (v) => plain(v, 256)) || !optional(data, "network", (v) => exact(NETWORK_NAME, v)) || !optional(data, "isNetworkTokenized", (v) => typeof v === "boolean") || !optional(data, "binData", record9))
2861
+ if (!optional(data, "first6Digits", (v) => exact(/^[0-9]{6}$/, v)) || !optional(data, "expirationMonth", (v) => exact(RESPONSE_MONTH, v)) || !optional(data, "expirationYear", (v) => exact(RESPONSE_YEAR, v)) || !optional(data, "cardholderName", (v) => plain(v, 256)) || !optional(data, "network", (v) => exact(NETWORK_NAME, v)) || !optional(data, "isNetworkTokenized", (v) => typeof v === "boolean") || !optional(data, "binData", record12))
1932
2862
  return null;
1933
2863
  const safe = { last4Digits: data.last4Digits };
1934
2864
  for (const key of ["first6Digits", "expirationMonth", "expirationYear", "cardholderName", "network", "isNetworkTokenized"]) {
1935
2865
  if (owns5(data, key) && data[key] !== null)
1936
2866
  safe[key] = data[key];
1937
2867
  }
1938
- if (record9(data.binData)) {
2868
+ if (record12(data.binData)) {
1939
2869
  const bin = {};
1940
2870
  for (const key of BIN_KEYS) {
1941
2871
  if (!owns5(data.binData, key) || data.binData[key] === null)
@@ -1951,7 +2881,7 @@ function cardDetails(data) {
1951
2881
  function threeDsSummary(value) {
1952
2882
  if (value === void 0 || value === null)
1953
2883
  return null;
1954
- if (!record9(value) || !exact(CODE2, value.responseCode) || !optional(value, "reasonCode", (v) => exact(CODE2, v)) || !optional(value, "reasonText", (v) => plain(v, 256)) || !optional(value, "protocolVersion", (v) => v === "" || exact(PROTOCOL, v)) || !optional(value, "challengeIssued", (v) => typeof v === "boolean"))
2884
+ if (!record12(value) || !exact(CODE3, value.responseCode) || !optional(value, "reasonCode", (v) => exact(CODE3, v)) || !optional(value, "reasonText", (v) => plain(v, 256)) || !optional(value, "protocolVersion", (v) => v === "" || exact(PROTOCOL, v)) || !optional(value, "challengeIssued", (v) => typeof v === "boolean"))
1955
2885
  return void 0;
1956
2886
  const safe = { responseCode: value.responseCode };
1957
2887
  for (const key of ["reasonCode", "reasonText", "protocolVersion", "challengeIssued"]) {
@@ -1979,7 +2909,7 @@ function rebuildToken(value) {
1979
2909
  }
1980
2910
  function primerErrorId(body) {
1981
2911
  const value = readAnswer(body);
1982
- const id = value && record9(value.error) ? value.error.errorId : null;
2912
+ const id = value && record12(value.error) ? value.error.errorId : null;
1983
2913
  return exact(ERROR_ID, id) && !panLike(id) ? id : null;
1984
2914
  }
1985
2915
  function matchesCard(details, card) {