@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.
- package/CHANGELOG.md +9 -1
- package/README.md +5 -1
- package/dist/card-fields.generated.js +471 -4
- package/dist/client.d.ts +11 -0
- package/dist/client.js +93 -31
- package/dist/primer.generated.js +495 -28
- package/dist/stripe-checkout.generated.js +295 -1
- package/package.json +1 -1
package/dist/primer.generated.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// @ts-nocheck
|
|
2
2
|
// Generated from @agent-cards/payment-core. Do not edit.
|
|
3
|
-
// artifact-sha256:
|
|
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
|
|
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
|
|
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) !==
|
|
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
|
|
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
|
|
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
|
|
1717
|
-
var
|
|
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
|
|
1732
|
-
if (typeof body !== "string" || body === "" || body.length >
|
|
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 (!
|
|
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 (!
|
|
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(
|
|
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 =
|
|
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 =
|
|
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
|
|
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 (!
|
|
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(
|
|
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 (!
|
|
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) &&
|
|
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 =
|
|
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 =
|
|
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
|
|
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 (!
|
|
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",
|
|
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 (
|
|
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 (!
|
|
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 &&
|
|
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) {
|