@agent-cards/sdk 0.23.17 → 0.23.18

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: f9b8cc9ac7688a49667fd7cec9f9452aa50c4531fbe82ec999872c2f0d9444c5
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
@@ -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)
@@ -1548,6 +1548,460 @@ 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 own2 = Object.keys(value);
1697
+ return own2.length === keys.length && own2.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 environment = paygentEnvironment(url);
1855
+ if (environment === 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 (environment === "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]);
1551
2005
  // src/card-fields.js
1552
2006
  function processorGate(recognizer, url, body) {
1553
2007
  if (recognizer && recognizer.psp === LYRA_PSP)
@@ -1557,6 +2011,8 @@ function processorGate(recognizer, url, body) {
1557
2011
  return { verdict: "refuse", code: "wix_payments_url_refused" };
1558
2012
  return wixPaymentsBodyVerdict(body);
1559
2013
  }
2014
+ if (recognizer && recognizer.psp === KOMOJU_PSP)
2015
+ return komojuBodyVerdict(body, url);
1560
2016
  if (recognizer && recognizer.psp === PADDLE_VGS_PSP) {
1561
2017
  if (url !== void 0 && !isPaddleVgsCardsUrl(url))
1562
2018
  return { verdict: "refuse", code: "paddle_vgs_url_refused" };
@@ -1567,6 +2023,17 @@ function processorGate(recognizer, url, body) {
1567
2023
  return { verdict: "refuse", code: "payfast_url_refused" };
1568
2024
  return payfastBodyVerdict(body);
1569
2025
  }
2026
+ if (recognizer && recognizer.psp === PAYREXX_PSP) {
2027
+ return url !== void 0 ? payrexxGateVerdict(url, body) : payrexxBodyVerdict(body);
2028
+ }
2029
+ if (recognizer && recognizer.psp === PAYGENT_PSP) {
2030
+ return url !== void 0 ? paygentRequestVerdict(url, body) : paygentBodyVerdict(body);
2031
+ }
2032
+ if (recognizer && recognizer.psp === PAY_NL_PSP) {
2033
+ if (url !== void 0 && !isPayNlTokenUrl(url))
2034
+ return { verdict: "refuse", code: "pay_nl_url_refused" };
2035
+ return payNlBodyVerdict(body);
2036
+ }
1570
2037
  if (recognizer && recognizer.psp === PADDLE_TOKENEX_PSP) {
1571
2038
  const target = url !== void 0 ? paddleTokenexPayTarget(url) : null;
1572
2039
  if (url !== void 0 && target === null)
@@ -1701,20 +2168,20 @@ var KEEP_ON_FILE_REFUSAL = "Refusing to pay: this Primer payment would keep the
1701
2168
  var UNSUPPORTED_SDK_REFUSAL = "Refusing to pay: this checkout uses a Primer SDK Agentcard does not support yet. Nothing was sent.";
1702
2169
  var NETWORK_MISMATCH_REFUSAL = "Refusing to pay: this Primer payment names a card network that is not your card's. Nothing was sent.";
1703
2170
  var FILL_REFUSAL = "Could not fill the card fields for Primer. Nothing was sent.";
1704
- var BODY_LIMIT8 = 16384;
2171
+ var BODY_LIMIT12 = 16384;
1705
2172
  var RESPONSE_LIMIT = 32768;
1706
2173
  var ROOT_KEYS5 = ["paymentInstrument", "userDescription", "tokenType", "paymentFlow"];
1707
2174
  var INSTRUMENT_KEYS = ["number", "cvv", "expirationMonth", "expirationYear", "cardholderName", "preferredNetwork"];
1708
2175
  var REQUIRED_INSTRUMENT_KEYS = ["number", "cvv", "expirationMonth", "expirationYear"];
1709
- var record9 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
2176
+ var record10 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
1710
2177
  var owns5 = (value, key) => Object.prototype.hasOwnProperty.call(value, key);
1711
2178
  var exact = (pattern, value) => typeof value === "string" && pattern.exec(value)?.[0] === value;
1712
2179
  var text2 = (value, max) => typeof value === "string" && value.length <= max && !/[\u0000-\u001f\u007f]/.test(value);
1713
2180
  var digits = (value, min, max) => typeof value === "string" && value.length >= min && value.length <= max && !/[^0-9]/.test(value);
1714
2181
  var panLike = (value) => /(?:[0-9][ _.:-]*){12,}/.test(value);
1715
2182
  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}$/;
2183
+ var MONTH7 = /^(?:0[1-9]|1[0-2])$/;
2184
+ var YEAR7 = /^20[0-9]{2}$/;
1718
2185
  var NETWORK = /^[A-Z][A-Z_]{1,31}$/;
1719
2186
  function isPrimerTokenizeUrl(url, method = "POST") {
1720
2187
  if (method !== "POST" || typeof url !== "string" || url.length > 256 || url.includes("?") || url.includes("#"))
@@ -1728,8 +2195,8 @@ function isPrimerTokenizeUrl(url, method = "POST") {
1728
2195
  }
1729
2196
  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
2197
  }
1731
- function judgeBody2(body) {
1732
- if (typeof body !== "string" || body === "" || body.length > BODY_LIMIT8)
2198
+ function judgeBody4(body) {
2199
+ if (typeof body !== "string" || body === "" || body.length > BODY_LIMIT12)
1733
2200
  return null;
1734
2201
  let value;
1735
2202
  try {
@@ -1738,21 +2205,21 @@ function judgeBody2(body) {
1738
2205
  catch {
1739
2206
  return null;
1740
2207
  }
1741
- if (!record9(value) || !roundTrips(value, body))
2208
+ if (!record10(value) || !roundTrips(value, body))
1742
2209
  return null;
1743
2210
  if (!Object.keys(value).every((key) => ROOT_KEYS5.includes(key)) || !owns5(value, "paymentInstrument"))
1744
2211
  return null;
1745
2212
  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)))
2213
+ if (!record10(instrument) || !Object.keys(instrument).every((key) => INSTRUMENT_KEYS.includes(key)) || !REQUIRED_INSTRUMENT_KEYS.every((key) => owns5(instrument, key)))
1747
2214
  return null;
1748
- if (!digits(instrument.number, 12, 19) || !digits(instrument.cvv, 3, 4) || !exact(MONTH3, instrument.expirationMonth) || !exact(YEAR3, instrument.expirationYear))
2215
+ if (!digits(instrument.number, 12, 19) || !digits(instrument.cvv, 3, 4) || !exact(MONTH7, instrument.expirationMonth) || !exact(YEAR7, instrument.expirationYear))
1749
2216
  return null;
1750
2217
  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")
1751
2218
  return null;
1752
2219
  return { value, keepOnFile: owns5(value, "tokenType") || owns5(value, "paymentFlow") };
1753
2220
  }
1754
2221
  function primerBodyRefusal(body) {
1755
- const judged = judgeBody2(body);
2222
+ const judged = judgeBody4(body);
1756
2223
  if (!judged)
1757
2224
  return "unsupported";
1758
2225
  return judged.keepOnFile ? "keep_on_file" : null;
@@ -1761,17 +2228,17 @@ function isPrimerNewCardBody(body) {
1761
2228
  return primerBodyRefusal(body) === null;
1762
2229
  }
1763
2230
  function primerKeepOnFileRequested(body) {
1764
- const judged = judgeBody2(body);
2231
+ const judged = judgeBody4(body);
1765
2232
  return judged ? judged.keepOnFile : null;
1766
2233
  }
1767
2234
  var CARD_GATE = /* @__PURE__ */ Object.freeze({ psp: "primer", encoding: "json", jsonCardFields: [["paymentInstrument", "number"]] });
1768
- var CONTENT_TYPE = /^application\/json(?:;\s*charset=utf-8)?$/i;
2235
+ var CONTENT_TYPE2 = /^application\/json(?:;\s*charset=utf-8)?$/i;
1769
2236
  var LEGACY_SDK_VERSION = /^v2\.[0-9]{1,3}\.[0-9]{1,3}$/;
1770
2237
  var CLIENT_TOKEN = /^[A-Za-z0-9._~+/=-]{16,4096}$/;
1771
2238
  var REQUEST_ID = /^[A-Za-z0-9-]{1,64}$/;
1772
2239
  var API_VERSION = /^2\.[0-9]{1,2}$/;
1773
2240
  function readHeaders(headers) {
1774
- if (!record9(headers))
2241
+ if (!record10(headers))
1775
2242
  return null;
1776
2243
  const folded = /* @__PURE__ */ new Map();
1777
2244
  for (const [name, value] of Object.entries(headers)) {
@@ -1791,7 +2258,7 @@ function headersRefusal(headers) {
1791
2258
  return "unsupported";
1792
2259
  if (!exact(LEGACY_SDK_VERSION, version))
1793
2260
  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")))
2261
+ 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
2262
  return "unsupported";
1796
2263
  return null;
1797
2264
  }
@@ -1818,7 +2285,7 @@ function onTokenizePath(url) {
1818
2285
  }
1819
2286
  }
1820
2287
  function primerTokenizeRefusal(request) {
1821
- if (!record9(request) || request.method !== "POST" || !isPrimerTokenizeUrl(request.url))
2288
+ if (!record10(request) || request.method !== "POST" || !isPrimerTokenizeUrl(request.url))
1822
2289
  return "unsupported";
1823
2290
  return headersRefusal(request.headers) ?? primerBodyRefusal(request.body);
1824
2291
  }
@@ -1833,7 +2300,7 @@ function primerCardOnFileRefusal(url, options, policy = PRIMER_SESSION_CARD_ON_F
1833
2300
  return "unsupported";
1834
2301
  if (new URL(url).hostname !== LIVE_PCI_HOST)
1835
2302
  return null;
1836
- return primerCardOnFileDisclosure(url, policy) && record9(options) && options.keepOnFile === true ? null : "keep_on_file";
2303
+ return primerCardOnFileDisclosure(url, policy) && record10(options) && options.keepOnFile === true ? null : "keep_on_file";
1837
2304
  }
1838
2305
  function primerRefusalMessage(reason) {
1839
2306
  if (reason === "keep_on_file")
@@ -1858,7 +2325,7 @@ function primerCardNetwork(number) {
1858
2325
  return null;
1859
2326
  }
1860
2327
  function primerNetworkRefusal(body, card) {
1861
- const judged = judgeBody2(body);
2328
+ const judged = judgeBody4(body);
1862
2329
  if (!judged)
1863
2330
  return "unsupported";
1864
2331
  const preferred = judged.value.paymentInstrument.preferredNetwork;
@@ -1868,7 +2335,7 @@ function primerNetworkRefusal(body, card) {
1868
2335
  return network !== null && network === preferred ? null : "network_mismatch";
1869
2336
  }
1870
2337
  function injectPrimerCard(body, card) {
1871
- const judged = judgeBody2(body);
2338
+ const judged = judgeBody4(body);
1872
2339
  if (!judged)
1873
2340
  throw new Error(UNSUPPORTED_REFUSAL);
1874
2341
  if (judged.keepOnFile)
@@ -1917,7 +2384,7 @@ function readAnswer(body) {
1917
2384
  return null;
1918
2385
  try {
1919
2386
  const value = JSON.parse(body);
1920
- return record9(value) ? value : null;
2387
+ return record10(value) ? value : null;
1921
2388
  }
1922
2389
  catch {
1923
2390
  return null;
@@ -1926,16 +2393,16 @@ function readAnswer(body) {
1926
2393
  var tokenValue = (value) => exact(TOKEN3, value) && !panLike(value);
1927
2394
  var optional = (value, key, check) => !owns5(value, key) || value[key] === null || check(value[key]);
1928
2395
  function cardDetails(data) {
1929
- if (!record9(data) || !exact(/^[0-9]{4}$/, data.last4Digits))
2396
+ if (!record10(data) || !exact(/^[0-9]{4}$/, data.last4Digits))
1930
2397
  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))
2398
+ 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", record10))
1932
2399
  return null;
1933
2400
  const safe = { last4Digits: data.last4Digits };
1934
2401
  for (const key of ["first6Digits", "expirationMonth", "expirationYear", "cardholderName", "network", "isNetworkTokenized"]) {
1935
2402
  if (owns5(data, key) && data[key] !== null)
1936
2403
  safe[key] = data[key];
1937
2404
  }
1938
- if (record9(data.binData)) {
2405
+ if (record10(data.binData)) {
1939
2406
  const bin = {};
1940
2407
  for (const key of BIN_KEYS) {
1941
2408
  if (!owns5(data.binData, key) || data.binData[key] === null)
@@ -1951,7 +2418,7 @@ function cardDetails(data) {
1951
2418
  function threeDsSummary(value) {
1952
2419
  if (value === void 0 || value === null)
1953
2420
  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"))
2421
+ if (!record10(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"))
1955
2422
  return void 0;
1956
2423
  const safe = { responseCode: value.responseCode };
1957
2424
  for (const key of ["reasonCode", "reasonText", "protocolVersion", "challengeIssued"]) {
@@ -1979,7 +2446,7 @@ function rebuildToken(value) {
1979
2446
  }
1980
2447
  function primerErrorId(body) {
1981
2448
  const value = readAnswer(body);
1982
- const id = value && record9(value.error) ? value.error.errorId : null;
2449
+ const id = value && record10(value.error) ? value.error.errorId : null;
1983
2450
  return exact(ERROR_ID, id) && !panLike(id) ? id : null;
1984
2451
  }
1985
2452
  function matchesCard(details, card) {