@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.
- package/CHANGELOG.md +19 -1
- package/README.md +17 -4
- package/dist/aci.d.ts +0 -7
- package/dist/aci.js +0 -19
- package/dist/card-fields.generated.js +963 -33
- package/dist/client.d.ts +24 -1
- package/dist/client.js +198 -57
- package/dist/datatrans.d.ts +2 -2
- package/dist/datatrans.generated.js +16 -11
- package/dist/datatrans.js +2 -2
- package/dist/pelecard.generated.d.ts +2 -1
- package/dist/pelecard.generated.js +14 -5
- package/dist/primer.generated.js +987 -57
- package/dist/stripe-checkout.generated.js +491 -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: 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
|
|
313
|
+
for (const environment2 of
|
|
314
314
|
/** @type {const} */
|
|
315
315
|
["production", "sandbox"]) {
|
|
316
|
-
if (MONERIS_TOKENIZE_HOSTS[
|
|
317
|
-
return
|
|
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
|
|
369
|
-
return
|
|
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
|
|
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)
|
|
@@ -754,13 +754,13 @@ var PADDLE_TOKENEX_KEYS = /* @__PURE__ */ Object.freeze({
|
|
|
754
754
|
sha256: "92529bd289bb24d52a1bdcc42edc9ac0bb1dacbb58f7568573d44771e1287762"
|
|
755
755
|
})
|
|
756
756
|
});
|
|
757
|
-
function paddleTokenexKey(
|
|
758
|
-
if (
|
|
757
|
+
function paddleTokenexKey(environment2) {
|
|
758
|
+
if (environment2 !== "sandbox" && environment2 !== "production")
|
|
759
759
|
return null;
|
|
760
|
-
return PADDLE_TOKENEX_KEYS[
|
|
760
|
+
return PADDLE_TOKENEX_KEYS[environment2] ?? null;
|
|
761
761
|
}
|
|
762
|
-
function paddleTokenexKeyBytes(
|
|
763
|
-
const key = paddleTokenexKey(
|
|
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
|
|
779
|
-
return
|
|
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,
|
|
825
|
-
const bytes = paddleTokenexKeyBytes(
|
|
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,
|
|
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 (
|
|
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,
|
|
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
|
|
1269
|
-
return
|
|
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
|
|
1472
|
-
return
|
|
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
|
|
1502
|
-
if (
|
|
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
|
|
2634
|
+
var BODY_LIMIT14 = 16384;
|
|
1705
2635
|
var RESPONSE_LIMIT = 32768;
|
|
1706
|
-
var
|
|
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
|
|
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
|
|
1717
|
-
var
|
|
1718
|
-
var
|
|
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
|
|
1732
|
-
if (typeof body !== "string" || body === "" || body.length >
|
|
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 (!
|
|
2671
|
+
if (!record12(value) || !roundTrips(value, body))
|
|
1742
2672
|
return null;
|
|
1743
|
-
if (!Object.keys(value).every((key) =>
|
|
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 (!
|
|
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(
|
|
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(
|
|
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 =
|
|
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 =
|
|
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
|
|
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 (!
|
|
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(
|
|
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 (!
|
|
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) &&
|
|
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 =
|
|
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 =
|
|
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
|
|
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
|
|
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 (!
|
|
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",
|
|
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 (
|
|
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 (!
|
|
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 &&
|
|
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) {
|