@agent-cards/sdk 0.23.20 → 0.23.21
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 +41 -2
- package/PREFLIGHT.md +2 -0
- package/README.md +143 -5
- package/dist/card-fields.generated.js +984 -57
- package/dist/cdp.js +146 -10
- package/dist/client.d.ts +104 -3
- package/dist/client.js +233 -23
- package/dist/comgate.d.ts +50 -0
- package/dist/comgate.js +80 -0
- package/dist/cybersource-secure-acceptance.generated.d.ts +1 -1
- package/dist/eprotect.generated.d.ts +1 -1
- package/dist/gmo.generated.js +7 -3
- package/dist/hipay.generated.d.ts +5 -5
- package/dist/hipay.generated.js +5 -2
- package/dist/hold.d.ts +1 -1
- package/dist/hold.js +10 -4
- package/dist/hosted-entry.d.ts +4 -0
- package/dist/hosted-entry.js +32 -0
- package/dist/index.d.ts +1 -0
- package/dist/paddle-tokenex.generated.js +7 -3
- package/dist/payrails.generated.js +7 -3
- package/dist/pre-claim.d.ts +7 -1
- package/dist/pre-claim.js +127 -20
- package/dist/preflight-catalog.json +58 -0
- package/dist/preflight-schemas.json +4 -0
- package/dist/preflight.generated.js +26 -2
- package/dist/primer.generated.js +1027 -100
- package/dist/przelewy24.d.ts +47 -0
- package/dist/przelewy24.js +88 -0
- package/dist/registry.d.ts +6 -5
- package/dist/registry.js +27 -7
- package/dist/shiji-sts.generated.js +7 -3
- package/dist/stripe-checkout.generated.js +621 -12
- package/dist/tokenex-iframe.d.ts +93 -0
- package/dist/tokenex-iframe.generated.d.ts +81 -0
- package/dist/tokenex-iframe.generated.js +403 -0
- package/dist/tokenex-iframe.js +195 -0
- package/dist/transbank.d.ts +45 -0
- package/dist/transbank.js +73 -0
- package/dist/twoc2p.generated.js +7 -3
- package/examples/preflight/kernel-native/inventory.json +1 -1
- package/package.json +3 -3
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: 2212f400551ed9deef56926befac7e0a0704717658d13228b1245199050dad1d
|
|
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
|
|
@@ -109,8 +109,8 @@ function parseConvergeBody(body) {
|
|
|
109
109
|
return parsed;
|
|
110
110
|
}
|
|
111
111
|
function convergeAmountCents(value) {
|
|
112
|
-
const
|
|
113
|
-
const m = typeof
|
|
112
|
+
const text7 = typeof value === "number" && Number.isFinite(value) ? String(value) : value;
|
|
113
|
+
const m = typeof text7 === "string" ? AMOUNT.exec(text7) : null;
|
|
114
114
|
if (!m)
|
|
115
115
|
return null;
|
|
116
116
|
const cents = Number(m[1]) * 100 + Number(((m[2] ?? "") + "00").slice(0, 2));
|
|
@@ -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 own6 = Object.keys(value);
|
|
369
|
+
return own6.length === keys.length && own6.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" });
|
|
@@ -590,9 +590,9 @@ var K = /* @__PURE__ */ new Uint32Array([
|
|
|
590
590
|
3329325298
|
|
591
591
|
]);
|
|
592
592
|
var rotr = (x, n) => x >>> n | x << 32 - n;
|
|
593
|
-
function utf8(
|
|
593
|
+
function utf8(text7) {
|
|
594
594
|
const out = [];
|
|
595
|
-
for (const char of
|
|
595
|
+
for (const char of text7) {
|
|
596
596
|
let cp = char.codePointAt(0);
|
|
597
597
|
if (cp >= 55296 && cp <= 57343)
|
|
598
598
|
cp = 65533;
|
|
@@ -671,10 +671,13 @@ 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 pin8 = key && typeof key === "object" ? key.sha256 : void 0;
|
|
675
|
+
const named = key && typeof key === "object" && Object.prototype.hasOwnProperty.call(key, "exponent") ? key.exponent : void 0;
|
|
676
|
+
if (named !== void 0 && named !== 17)
|
|
677
|
+
throw refuse6("key");
|
|
675
678
|
if (typeof spki !== "string" || spki.length > 1024 || spki.length % 4 !== 0 || !BASE64.test(spki))
|
|
676
679
|
throw refuse6("key");
|
|
677
|
-
if (typeof
|
|
680
|
+
if (typeof pin8 !== "string" || !SHA256_HEX.test(pin8))
|
|
678
681
|
throw refuse6("key");
|
|
679
682
|
let binary;
|
|
680
683
|
try {
|
|
@@ -686,7 +689,7 @@ function parseRsaPublicKey(key) {
|
|
|
686
689
|
if (btoa(binary) !== spki)
|
|
687
690
|
throw refuse6("key");
|
|
688
691
|
const der = Uint8Array.from(binary, (c) => c.charCodeAt(0));
|
|
689
|
-
if (sha256Hex(der) !==
|
|
692
|
+
if (sha256Hex(der) !== pin8)
|
|
690
693
|
throw refuse6("key");
|
|
691
694
|
const outer = readElement(der, 0, 48);
|
|
692
695
|
if (outer.end !== der.length || outer.start + RSA_ALGORITHM.length > der.length)
|
|
@@ -707,9 +710,10 @@ function parseRsaPublicKey(key) {
|
|
|
707
710
|
if (!MODULUS_BYTES.includes(n.length) || !(n[0] & 128) || !(n[n.length - 1] & 1))
|
|
708
711
|
throw refuse6("key");
|
|
709
712
|
const e = exponent.bytes;
|
|
710
|
-
|
|
713
|
+
const expected = named === 17 ? [17] : [1, 0, 1];
|
|
714
|
+
if (e.length !== expected.length || !expected.every((byte, i) => e[i] === byte))
|
|
711
715
|
throw refuse6("key");
|
|
712
|
-
return Object.freeze({ n: toBigInt(n), e: 65537n, size: n.length });
|
|
716
|
+
return Object.freeze({ n: toBigInt(n), e: named === 17 ? 17n : 65537n, size: n.length });
|
|
713
717
|
}
|
|
714
718
|
function readElement(der, at, tag) {
|
|
715
719
|
if (at + 2 > der.length || der[at] !== tag)
|
|
@@ -775,8 +779,8 @@ var PADDLE_TOKENEX_PSP = "paddle_tokenex";
|
|
|
775
779
|
var PADDLE_TOKENEX_FACT_KEYS = /* @__PURE__ */ Object.freeze(["card_first_six", "card_last_four", "expiry_month", "expiry_year", "card_brand"]);
|
|
776
780
|
var record4 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
777
781
|
var sameKeys2 = (value, keys) => {
|
|
778
|
-
const
|
|
779
|
-
return
|
|
782
|
+
const own6 = Object.keys(value);
|
|
783
|
+
return own6.length === keys.length && own6.every((key, at) => key === keys[at]);
|
|
780
784
|
};
|
|
781
785
|
var refuse7 = (code) => Object.freeze({ verdict: "refuse", code });
|
|
782
786
|
var CARD6 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
|
|
@@ -1265,8 +1269,8 @@ var TEXT_LIMIT = 256;
|
|
|
1265
1269
|
var CONTROL4 = /[\u0000-\u001f\u007f]/;
|
|
1266
1270
|
var record6 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
1267
1271
|
var sameKeys3 = (value, keys) => {
|
|
1268
|
-
const
|
|
1269
|
-
return
|
|
1272
|
+
const own6 = Object.keys(value);
|
|
1273
|
+
return own6.length === keys.length && own6.every((key, at) => key === keys[at]);
|
|
1270
1274
|
};
|
|
1271
1275
|
var plainText = (value) => typeof value === "string" && value.length <= TEXT_LIMIT && !CONTROL4.test(value) && (value.match(/[0-9]/g) ?? []).length < 12;
|
|
1272
1276
|
var refuse9 = (code) => Object.freeze({ verdict: "refuse", code });
|
|
@@ -1376,14 +1380,14 @@ function readJson2(body) {
|
|
|
1376
1380
|
catch {
|
|
1377
1381
|
return { parsed: null, exact: false };
|
|
1378
1382
|
}
|
|
1379
|
-
let
|
|
1383
|
+
let exact4 = false;
|
|
1380
1384
|
try {
|
|
1381
|
-
|
|
1385
|
+
exact4 = body.length <= BODY_LIMIT6 && JSON.stringify(parsed) === body;
|
|
1382
1386
|
}
|
|
1383
1387
|
catch {
|
|
1384
|
-
|
|
1388
|
+
exact4 = false;
|
|
1385
1389
|
}
|
|
1386
|
-
return { parsed, exact:
|
|
1390
|
+
return { parsed, exact: exact4 };
|
|
1387
1391
|
}
|
|
1388
1392
|
function billingValue(value) {
|
|
1389
1393
|
if (value === UNDEFINED)
|
|
@@ -1438,14 +1442,14 @@ function attachType(parsed) {
|
|
|
1438
1442
|
return typeof type === "string" ? type : null;
|
|
1439
1443
|
}
|
|
1440
1444
|
function paymongoBodyVerdict(body, session) {
|
|
1441
|
-
const { parsed, exact:
|
|
1445
|
+
const { parsed, exact: exact4 } = readJson2(body);
|
|
1442
1446
|
const type = parsed === null ? null : attachType(parsed);
|
|
1443
1447
|
if (type !== "card") {
|
|
1444
1448
|
if (parsed === null)
|
|
1445
1449
|
return body === void 0 || body === null || body === "" ? CONTINUE4 : refuse10("paymongo_body_unsupported");
|
|
1446
1450
|
return namesCardValue(parsed) ? refuse10("paymongo_body_unsupported") : CONTINUE4;
|
|
1447
1451
|
}
|
|
1448
|
-
if (!
|
|
1452
|
+
if (!exact4)
|
|
1449
1453
|
return refuse10("paymongo_body_unsupported");
|
|
1450
1454
|
const code = judgeCardAttach(parsed, session);
|
|
1451
1455
|
return code === null ? CARD9 : refuse10(code);
|
|
@@ -1468,15 +1472,15 @@ var EXPIRATION = /^[0-9]{2}(?:0[1-9]|1[0-2])$/;
|
|
|
1468
1472
|
var CARD_PAYMENT = "PAYMENT_CARD";
|
|
1469
1473
|
var record8 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
1470
1474
|
var sameKeys4 = (value, keys) => {
|
|
1471
|
-
const
|
|
1472
|
-
return
|
|
1475
|
+
const own6 = Object.keys(value);
|
|
1476
|
+
return own6.length === keys.length && own6.every((key, at) => key === keys[at]);
|
|
1473
1477
|
};
|
|
1474
1478
|
var refuse11 = (code) => Object.freeze({ verdict: "refuse", code });
|
|
1475
1479
|
var CARD10 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
|
|
1476
|
-
function luhn(
|
|
1480
|
+
function luhn(digits3) {
|
|
1477
1481
|
let sum = 0;
|
|
1478
|
-
for (let at = 0; at <
|
|
1479
|
-
let digit = Number(
|
|
1482
|
+
for (let at = 0; at < digits3.length; at += 1) {
|
|
1483
|
+
let digit = Number(digits3[digits3.length - 1 - at]);
|
|
1480
1484
|
if (at % 2 === 1) {
|
|
1481
1485
|
digit *= 2;
|
|
1482
1486
|
if (digit > 9)
|
|
@@ -1484,7 +1488,7 @@ function luhn(digits2) {
|
|
|
1484
1488
|
}
|
|
1485
1489
|
sum += digit;
|
|
1486
1490
|
}
|
|
1487
|
-
return sum % 10 === 0;
|
|
1491
|
+
return sum > 0 && sum % 10 === 0;
|
|
1488
1492
|
}
|
|
1489
1493
|
function gopayCardFormUrl(url) {
|
|
1490
1494
|
if (typeof url !== "string" || url.length > 2048 || url.includes("#"))
|
|
@@ -1548,6 +1552,9 @@ function gopayBodyVerdict(body, url) {
|
|
|
1548
1552
|
return refuse11("gopay_signature_mismatch");
|
|
1549
1553
|
return CARD10;
|
|
1550
1554
|
}
|
|
1555
|
+
var GOPAY_MERCHANT_PINS = /* @__PURE__ */ Object.freeze([
|
|
1556
|
+
Object.freeze({ id: "caramilla", merchant: "Caramilla.cz", origins: Object.freeze(["https://www.caramilla.cz"]) })
|
|
1557
|
+
]);
|
|
1551
1558
|
// src/payrexx.js
|
|
1552
1559
|
var PAYREXX_PSP = "payrexx";
|
|
1553
1560
|
var PAYREXX_FRAME_HOST = "checkout.payrexx.com";
|
|
@@ -1620,10 +1627,10 @@ function readForm2(body) {
|
|
|
1620
1627
|
return null;
|
|
1621
1628
|
}
|
|
1622
1629
|
}
|
|
1623
|
-
function cardNetwork2(
|
|
1624
|
-
if (VISA2.test(
|
|
1630
|
+
function cardNetwork2(digits3) {
|
|
1631
|
+
if (VISA2.test(digits3))
|
|
1625
1632
|
return "visa";
|
|
1626
|
-
return MASTERCARD2.test(
|
|
1633
|
+
return MASTERCARD2.test(digits3) ? "mastercard" : null;
|
|
1627
1634
|
}
|
|
1628
1635
|
function judgeBody2(body) {
|
|
1629
1636
|
const pairs = readForm2(body);
|
|
@@ -1696,8 +1703,8 @@ var LOCALE = /^[a-z]{2}(?:-[A-Za-z]{2,4})?$/;
|
|
|
1696
1703
|
var PAN_LIKE3 = /(?:[0-9][ _.:-]*){12,}/;
|
|
1697
1704
|
var record9 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
1698
1705
|
var sameKeys5 = (value, keys) => {
|
|
1699
|
-
const
|
|
1700
|
-
return
|
|
1706
|
+
const own6 = Object.keys(value);
|
|
1707
|
+
return own6.length === keys.length && own6.every((key, at) => key === keys[at]);
|
|
1701
1708
|
};
|
|
1702
1709
|
var refuse13 = (code) => Object.freeze({ verdict: "refuse", code });
|
|
1703
1710
|
var CARD12 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
|
|
@@ -1982,7 +1989,7 @@ var HOLDER3 = /^\p{L}+(?: \p{L}+)*$/u;
|
|
|
1982
1989
|
var HOLDER_LIMIT2 = 256;
|
|
1983
1990
|
var SECURITY_CODE10 = /^[0-9]{3,4}$/;
|
|
1984
1991
|
var MONTH6 = /^(?:0[1-9]|1[0-2])$/;
|
|
1985
|
-
var YEAR6 = /^[0-9]{2}$/;
|
|
1992
|
+
var YEAR6 = /^(?:[0-9]{2}|20[0-9]{2})$/;
|
|
1986
1993
|
var refuse15 = (code) => Object.freeze({ verdict: "refuse", code });
|
|
1987
1994
|
var CARD14 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
|
|
1988
1995
|
function isPayNlTokenUrl(url) {
|
|
@@ -2088,10 +2095,10 @@ var wellFormed = (value) => {
|
|
|
2088
2095
|
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);
|
|
2089
2096
|
var between = (value, min, max) => Number.isSafeInteger(value) && value >= min && value <= max;
|
|
2090
2097
|
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})$/;
|
|
2091
|
-
var luhn2 = (
|
|
2098
|
+
var luhn2 = (digits3) => {
|
|
2092
2099
|
let sum = 0;
|
|
2093
|
-
for (let at = 0; at <
|
|
2094
|
-
let d =
|
|
2100
|
+
for (let at = 0; at < digits3.length; at += 1) {
|
|
2101
|
+
let d = digits3.charCodeAt(digits3.length - 1 - at) - 48;
|
|
2095
2102
|
if (at % 2 === 1) {
|
|
2096
2103
|
d *= 2;
|
|
2097
2104
|
if (d > 9)
|
|
@@ -2102,7 +2109,7 @@ var luhn2 = (digits2) => {
|
|
|
2102
2109
|
return sum % 10 === 0;
|
|
2103
2110
|
};
|
|
2104
2111
|
var ANY_NETWORK = /^[2-6][0-9]{12,18}$/;
|
|
2105
|
-
var holdsCardShape = (
|
|
2112
|
+
var holdsCardShape = (text7, shape = NETWORK) => (text7.match(/[0-9]{13,}/g) ?? []).some((run) => run.length > 19 || shape.test(run) && luhn2(run));
|
|
2106
2113
|
var phone = (value) => typeof value === "string" && PHONE.test(value) && (value.match(/[0-9]/g) ?? []).length >= 6 && (value.match(/[0-9]/g) ?? []).length <= 15;
|
|
2107
2114
|
var refuse16 = (code) => Object.freeze({ verdict: "refuse", code });
|
|
2108
2115
|
var CARD15 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
|
|
@@ -2313,10 +2320,10 @@ function orderedSubset(value, keys) {
|
|
|
2313
2320
|
}
|
|
2314
2321
|
return true;
|
|
2315
2322
|
}
|
|
2316
|
-
function luhn3(
|
|
2323
|
+
function luhn3(digits3) {
|
|
2317
2324
|
let sum = 0;
|
|
2318
|
-
for (let at = 0; at <
|
|
2319
|
-
let digit = Number(
|
|
2325
|
+
for (let at = 0; at < digits3.length; at += 1) {
|
|
2326
|
+
let digit = Number(digits3[digits3.length - 1 - at]);
|
|
2320
2327
|
if (at % 2 === 1) {
|
|
2321
2328
|
digit *= 2;
|
|
2322
2329
|
if (digit > 9)
|
|
@@ -2330,13 +2337,13 @@ var printable = (value) => [...value].every((ch) => ch.charCodeAt(0) >= 32 && ch
|
|
|
2330
2337
|
function typed(value, limit = 256) {
|
|
2331
2338
|
return typeof value === "string" && value.length >= 1 && value.length <= limit && !PAN_LIKE4.test(value) && printable(value);
|
|
2332
2339
|
}
|
|
2333
|
-
function decodeBase64(
|
|
2334
|
-
if (typeof
|
|
2340
|
+
function decodeBase64(text7) {
|
|
2341
|
+
if (typeof text7 !== "string" || !BASE643.test(text7) || text7.length % 4 !== 0)
|
|
2335
2342
|
return null;
|
|
2336
2343
|
let bits = 0;
|
|
2337
2344
|
let value = 0;
|
|
2338
2345
|
let out = "";
|
|
2339
|
-
for (const ch of
|
|
2346
|
+
for (const ch of text7.replace(/=+$/, "")) {
|
|
2340
2347
|
value = (value << 6 | BASE64_ALPHABET.indexOf(ch)) & 16777215;
|
|
2341
2348
|
bits += 6;
|
|
2342
2349
|
if (bits >= 8) {
|
|
@@ -2346,8 +2353,8 @@ function decodeBase64(text4) {
|
|
|
2346
2353
|
}
|
|
2347
2354
|
return out;
|
|
2348
2355
|
}
|
|
2349
|
-
function soundDevice(
|
|
2350
|
-
const json = decodeBase64(
|
|
2356
|
+
function soundDevice(text7) {
|
|
2357
|
+
const json = decodeBase64(text7);
|
|
2351
2358
|
if (json === null)
|
|
2352
2359
|
return false;
|
|
2353
2360
|
let value;
|
|
@@ -2465,17 +2472,17 @@ function sumupBodyVerdict(body, url) {
|
|
|
2465
2472
|
var SALTED = /* @__PURE__ */ Object.freeze([83, 97, 108, 116, 101, 100, 95, 95]);
|
|
2466
2473
|
var B64 = /^[A-Za-z0-9+/]+={0,2}$/;
|
|
2467
2474
|
var FIELD_LIMIT = 1024;
|
|
2468
|
-
function decodeCanonical(
|
|
2469
|
-
if (typeof
|
|
2475
|
+
function decodeCanonical(text7) {
|
|
2476
|
+
if (typeof text7 !== "string" || text7.length === 0 || text7.length % 4 !== 0 || !B64.test(text7))
|
|
2470
2477
|
return null;
|
|
2471
2478
|
let binary;
|
|
2472
2479
|
try {
|
|
2473
|
-
binary = atob(
|
|
2480
|
+
binary = atob(text7);
|
|
2474
2481
|
}
|
|
2475
2482
|
catch {
|
|
2476
2483
|
return null;
|
|
2477
2484
|
}
|
|
2478
|
-
if (btoa(binary) !==
|
|
2485
|
+
if (btoa(binary) !== text7)
|
|
2479
2486
|
return null;
|
|
2480
2487
|
return Uint8Array.from(binary, (char) => char.charCodeAt(0));
|
|
2481
2488
|
}
|
|
@@ -2717,8 +2724,8 @@ var TEXT_LIMIT3 = 256;
|
|
|
2717
2724
|
var CONTROL7 = /[\u0000-\u001f\u007f]/;
|
|
2718
2725
|
var record13 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
2719
2726
|
var sameKeys7 = (value, keys) => {
|
|
2720
|
-
const
|
|
2721
|
-
return
|
|
2727
|
+
const own6 = Object.keys(value);
|
|
2728
|
+
return own6.length === keys.length && own6.every((key, at) => key === keys[at]);
|
|
2722
2729
|
};
|
|
2723
2730
|
var plainText3 = (value) => typeof value === "string" && value.length <= TEXT_LIMIT3 && !CONTROL7.test(value) && (value.match(/[0-9]/g) ?? []).length < 12;
|
|
2724
2731
|
var refuse19 = (code) => Object.freeze({ verdict: "refuse", code });
|
|
@@ -2762,6 +2769,10 @@ function hipayBodyVerdict(body) {
|
|
|
2762
2769
|
return refuse19("hipay_keeps_card");
|
|
2763
2770
|
return value.multi_use === 0 ? CARD18 : refuse19("hipay_body_unsupported");
|
|
2764
2771
|
}
|
|
2772
|
+
var pin5 = (fields) => Object.freeze({ ...fields, origins: Object.freeze([...fields.origins]), usernames: Object.freeze([...fields.usernames]) });
|
|
2773
|
+
var HIPAY_MERCHANT_PINS = /* @__PURE__ */ Object.freeze([
|
|
2774
|
+
pin5({ id: "happybulle", merchant: "HappyBulle", origins: ["https://www.happybulle.com"], usernames: ["94683309.secure-gateway.hipay-tpp.com"] })
|
|
2775
|
+
]);
|
|
2765
2776
|
// src/amazon-payment-services.js
|
|
2766
2777
|
var APS_PSP = "amazon_payment_services";
|
|
2767
2778
|
var APS_HOSTS = /* @__PURE__ */ Object.freeze({ "checkout.payfort.com": "production", "sbcheckout.payfort.com": "sandbox" });
|
|
@@ -2906,6 +2917,899 @@ function apsBodyVerdict(body, url) {
|
|
|
2906
2917
|
return code ? { verdict: "refuse", code } : { verdict: "card" };
|
|
2907
2918
|
}
|
|
2908
2919
|
var ANSWER_LIMIT = 64 * 1024;
|
|
2920
|
+
// src/paypal.js
|
|
2921
|
+
var PAYPAL_PSP = "paypal";
|
|
2922
|
+
var PAYPAL_CONFIRM_HOSTS = /* @__PURE__ */ Object.freeze(["www.paypal.com", "www.sandbox.paypal.com", "api-m.paypal.com", "api-m.sandbox.paypal.com"]);
|
|
2923
|
+
var CONFIRM_PATH = /^\/v2\/checkout\/orders\/([A-Z0-9]{1,36})\/confirm-payment-source$/;
|
|
2924
|
+
var BODY_LIMIT17 = 8192;
|
|
2925
|
+
var CARD_KEYS8 = /* @__PURE__ */ Object.freeze(["number", "expiry", "security_code", "name", "billing_address", "attributes", "brand_preference"]);
|
|
2926
|
+
var ADDRESS_KEYS3 = /* @__PURE__ */ Object.freeze([
|
|
2927
|
+
"address_line_1",
|
|
2928
|
+
"address_line_2",
|
|
2929
|
+
"address_line_3",
|
|
2930
|
+
"admin_area_1",
|
|
2931
|
+
"admin_area_2",
|
|
2932
|
+
"admin_area_3",
|
|
2933
|
+
"admin_area_4",
|
|
2934
|
+
"postal_code",
|
|
2935
|
+
"country_code"
|
|
2936
|
+
]);
|
|
2937
|
+
var CONTROL8 = /[\u0000-\u001f\u007f]/;
|
|
2938
|
+
var TEXT_LIMIT4 = 300;
|
|
2939
|
+
var cardLike = (value) => (value.match(/[0-9]/g) ?? []).length >= 12;
|
|
2940
|
+
var text3 = (value) => typeof value === "string" && value.length <= TEXT_LIMIT4 && !CONTROL8.test(value) && !cardLike(value);
|
|
2941
|
+
var record14 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
2942
|
+
var own3 = (value, key) => Object.prototype.hasOwnProperty.call(value, key);
|
|
2943
|
+
var keysWithin2 = (value, allowed) => record14(value) && Object.keys(value).every((key) => allowed.includes(key));
|
|
2944
|
+
var refuse20 = (code) => Object.freeze({ verdict: "refuse", code });
|
|
2945
|
+
var CARD19 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
|
|
2946
|
+
var CONTINUE9 = /* @__PURE__ */ Object.freeze({ verdict: "continue" });
|
|
2947
|
+
function paypalConfirmOrderId(url) {
|
|
2948
|
+
if (typeof url !== "string" || url.length > 256 || url.includes("?") || url.includes("#"))
|
|
2949
|
+
return null;
|
|
2950
|
+
let parsed;
|
|
2951
|
+
try {
|
|
2952
|
+
parsed = new URL(url);
|
|
2953
|
+
}
|
|
2954
|
+
catch {
|
|
2955
|
+
return null;
|
|
2956
|
+
}
|
|
2957
|
+
if (parsed.href !== url || parsed.protocol !== "https:" || parsed.port || parsed.username || parsed.password || !PAYPAL_CONFIRM_HOSTS.includes(parsed.hostname))
|
|
2958
|
+
return null;
|
|
2959
|
+
return CONFIRM_PATH.exec(parsed.pathname)?.[1] ?? null;
|
|
2960
|
+
}
|
|
2961
|
+
function isPaypalConfirmUrl(url) {
|
|
2962
|
+
return paypalConfirmOrderId(url) !== null;
|
|
2963
|
+
}
|
|
2964
|
+
function readBody10(body) {
|
|
2965
|
+
if (typeof body !== "string" || body === "" || body.length > BODY_LIMIT17)
|
|
2966
|
+
return null;
|
|
2967
|
+
let value;
|
|
2968
|
+
try {
|
|
2969
|
+
value = JSON.parse(body);
|
|
2970
|
+
if (!record14(value) || JSON.stringify(value) !== body)
|
|
2971
|
+
return null;
|
|
2972
|
+
}
|
|
2973
|
+
catch {
|
|
2974
|
+
return null;
|
|
2975
|
+
}
|
|
2976
|
+
return value;
|
|
2977
|
+
}
|
|
2978
|
+
var typedNumber = (value) => typeof value === "string" && value.length <= 23 && /^[0-9]+(?: [0-9]+)*$/.test(value) && value.replace(/ /g, "").length >= 12 && value.replace(/ /g, "").length <= 19;
|
|
2979
|
+
function installmentsOk(value) {
|
|
2980
|
+
if (!keysWithin2(value, ["term", "interval_duration"]) || Object.keys(value).length === 0)
|
|
2981
|
+
return false;
|
|
2982
|
+
if (own3(value, "term") && !(Number.isSafeInteger(value.term) && value.term >= 1 && value.term <= 99))
|
|
2983
|
+
return false;
|
|
2984
|
+
return !own3(value, "interval_duration") || typeof value.interval_duration === "string" && /^P[0-9]{1,3}[DWMY]$/.test(value.interval_duration);
|
|
2985
|
+
}
|
|
2986
|
+
function paypalBodyVerdict(body) {
|
|
2987
|
+
const value = readBody10(body);
|
|
2988
|
+
if (value === null)
|
|
2989
|
+
return refuse20("paypal_body_unsupported");
|
|
2990
|
+
const source = value.payment_source;
|
|
2991
|
+
const card = record14(source) ? source.card : void 0;
|
|
2992
|
+
const number = record14(card) ? card.number : void 0;
|
|
2993
|
+
if (number === void 0 || number === null || number === "")
|
|
2994
|
+
return CONTINUE9;
|
|
2995
|
+
const context = value.application_context;
|
|
2996
|
+
const attributes = record14(card.attributes) ? card.attributes : null;
|
|
2997
|
+
if (record14(context) && context.vault === true || own3(card, "stored_credential") || attributes && (own3(attributes, "vault") || own3(attributes, "customer")))
|
|
2998
|
+
return refuse20("paypal_card_on_file");
|
|
2999
|
+
if (attributes && record14(attributes.verification) && attributes.verification.method === "SCA_ALWAYS")
|
|
3000
|
+
return refuse20("paypal_three_ds");
|
|
3001
|
+
if (!keysWithin2(value, ["payment_source"]) || !keysWithin2(source, ["card"]) || !keysWithin2(card, CARD_KEYS8) || !typedNumber(card.number) || typeof card.expiry !== "string" || !/^[0-9]{4}-(?:0[1-9]|1[0-2])$/.test(card.expiry))
|
|
3002
|
+
return refuse20("paypal_body_unsupported");
|
|
3003
|
+
if (own3(card, "security_code") && !(typeof card.security_code === "string" && /^[0-9]{3,4}$/.test(card.security_code)))
|
|
3004
|
+
return refuse20("paypal_body_unsupported");
|
|
3005
|
+
if (own3(card, "name") && !(text3(card.name) && card.name.trim() !== ""))
|
|
3006
|
+
return refuse20("paypal_body_unsupported");
|
|
3007
|
+
if (own3(card, "brand_preference") && !(typeof card.brand_preference === "string" && /^[A-Z][A-Z_]{1,31}$/.test(card.brand_preference))) {
|
|
3008
|
+
return refuse20("paypal_body_unsupported");
|
|
3009
|
+
}
|
|
3010
|
+
if (own3(card, "billing_address") && !(keysWithin2(card.billing_address, ADDRESS_KEYS3) && Object.values(card.billing_address).every(text3))) {
|
|
3011
|
+
return refuse20("paypal_body_unsupported");
|
|
3012
|
+
}
|
|
3013
|
+
if (own3(card, "attributes") && !(keysWithin2(attributes, ["installments"]) && installmentsOk(attributes.installments))) {
|
|
3014
|
+
return refuse20("paypal_body_unsupported");
|
|
3015
|
+
}
|
|
3016
|
+
return CARD19;
|
|
3017
|
+
}
|
|
3018
|
+
// src/clover.js
|
|
3019
|
+
var CLOVER_PSP = "clover";
|
|
3020
|
+
var CLOVER_TOKEN_HOSTS = /* @__PURE__ */ Object.freeze({ "token.clover.com": "production", "token-sandbox.dev.clover.com": "test" });
|
|
3021
|
+
var CLOVER_TOKEN_PATH = "/v1/tokens";
|
|
3022
|
+
var BODY_LIMIT18 = 4096;
|
|
3023
|
+
var REQUIRED_KEYS = /* @__PURE__ */ Object.freeze(["encrypted_pan", "exp_month", "exp_year", "cvv", "first6", "last4", "brand"]);
|
|
3024
|
+
var OPTIONAL_KEYS = /* @__PURE__ */ Object.freeze(["address_line1", "phone_numbers", "email_address", "name", "address_zip"]);
|
|
3025
|
+
var CARD_ORDER = /* @__PURE__ */ Object.freeze([...REQUIRED_KEYS, ...OPTIONAL_KEYS]);
|
|
3026
|
+
var ENCRYPTED_PAN = /^[A-Za-z0-9+/]{341}[AQgw]==$/;
|
|
3027
|
+
var MONTH9 = /^(?:[1-9]|1[0-2])$/;
|
|
3028
|
+
var YEAR9 = /^(?:[0-9]|[1-9][0-9])$/;
|
|
3029
|
+
var CODE3 = /^[0-9]{3,4}$/;
|
|
3030
|
+
var FIRST6 = /^[0-9]{6}$/;
|
|
3031
|
+
var LAST4 = /^[0-9]{4}$/;
|
|
3032
|
+
var BRANDS = /* @__PURE__ */ new Set(["VISA", "MC", "AMEX", "DISCOVER", "DINERS_CLUB", "JCB"]);
|
|
3033
|
+
var PHONE_TYPES = /* @__PURE__ */ new Set(["home_number", "mobile_number", "work_number"]);
|
|
3034
|
+
var COUNTRY_CODE2 = /^[0-9]{1,4}$/;
|
|
3035
|
+
var SUBSCRIBER = /^[0-9]{1,11}$/;
|
|
3036
|
+
var POSTAL_CODE2 = /^[A-Za-z0-9]{1,10}$/;
|
|
3037
|
+
var TEXT_LIMIT5 = 256;
|
|
3038
|
+
var EMAIL_LIMIT = 254;
|
|
3039
|
+
var CARD_LIKE_RUN = /[0-9]{12,}/;
|
|
3040
|
+
var record15 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
3041
|
+
var own4 = (value, key) => Object.prototype.hasOwnProperty.call(value, key);
|
|
3042
|
+
var refuse21 = (code) => Object.freeze({ verdict: "refuse", code });
|
|
3043
|
+
var CARD20 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
|
|
3044
|
+
function cloverTokenUrl(url) {
|
|
3045
|
+
if (typeof url !== "string" || url.length > 256 || url.includes("?") || url.includes("#"))
|
|
3046
|
+
return null;
|
|
3047
|
+
let parsed;
|
|
3048
|
+
try {
|
|
3049
|
+
parsed = new URL(url);
|
|
3050
|
+
}
|
|
3051
|
+
catch {
|
|
3052
|
+
return null;
|
|
3053
|
+
}
|
|
3054
|
+
if (parsed.href !== url || parsed.protocol !== "https:" || parsed.port || parsed.username || parsed.password)
|
|
3055
|
+
return null;
|
|
3056
|
+
if (!own4(CLOVER_TOKEN_HOSTS, parsed.hostname) || parsed.pathname !== CLOVER_TOKEN_PATH)
|
|
3057
|
+
return null;
|
|
3058
|
+
return Object.freeze({ host: parsed.hostname, environment: CLOVER_TOKEN_HOSTS[parsed.hostname] });
|
|
3059
|
+
}
|
|
3060
|
+
function cloverBrand(digits3) {
|
|
3061
|
+
if (typeof digits3 !== "string" || !/^[0-9]{6,19}$/.test(digits3))
|
|
3062
|
+
return null;
|
|
3063
|
+
const two = Number(digits3.slice(0, 2));
|
|
3064
|
+
const three = Number(digits3.slice(0, 3));
|
|
3065
|
+
const four = Number(digits3.slice(0, 4));
|
|
3066
|
+
const six = Number(digits3.slice(0, 6));
|
|
3067
|
+
if (digits3.startsWith("4"))
|
|
3068
|
+
return "VISA";
|
|
3069
|
+
if (two === 34 || two === 37)
|
|
3070
|
+
return "AMEX";
|
|
3071
|
+
if (two >= 51 && two <= 55 || four >= 2221 && four < 2721)
|
|
3072
|
+
return "MC";
|
|
3073
|
+
if (four >= 3528 && four <= 3589)
|
|
3074
|
+
return "JCB";
|
|
3075
|
+
if (two === 64 || three >= 644 && three <= 659 || four === 6011 || six >= 622129 && six <= 622925)
|
|
3076
|
+
return "DISCOVER";
|
|
3077
|
+
if (two === 36 || two === 38 || two === 39 || three === 309 || three >= 300 && three <= 305)
|
|
3078
|
+
return "DINERS_CLUB";
|
|
3079
|
+
if ([5018, 5020, 5038, 5893, 6e3, 6304, 6759, 6761, 6762, 6763, 6799].includes(four))
|
|
3080
|
+
return "MAESTRO";
|
|
3081
|
+
return "UNKNOWN";
|
|
3082
|
+
}
|
|
3083
|
+
var isCiphertext = (value) => typeof value === "string" && ENCRYPTED_PAN.test(value);
|
|
3084
|
+
function readBody11(body) {
|
|
3085
|
+
if (typeof body !== "string" || body === "" || body.length > BODY_LIMIT18)
|
|
3086
|
+
return null;
|
|
3087
|
+
let value;
|
|
3088
|
+
try {
|
|
3089
|
+
value = JSON.parse(body);
|
|
3090
|
+
if (!record15(value) || JSON.stringify(value) !== body)
|
|
3091
|
+
return null;
|
|
3092
|
+
}
|
|
3093
|
+
catch {
|
|
3094
|
+
return null;
|
|
3095
|
+
}
|
|
3096
|
+
return value;
|
|
3097
|
+
}
|
|
3098
|
+
function inFrameOrder(keys) {
|
|
3099
|
+
let last = -1;
|
|
3100
|
+
for (const key of keys) {
|
|
3101
|
+
const at = CARD_ORDER.indexOf(key);
|
|
3102
|
+
if (at <= last)
|
|
3103
|
+
return false;
|
|
3104
|
+
last = at;
|
|
3105
|
+
}
|
|
3106
|
+
return REQUIRED_KEYS.every((key) => keys.includes(key));
|
|
3107
|
+
}
|
|
3108
|
+
var sideText = (value, limit = TEXT_LIMIT5) => typeof value === "string" && value.length <= limit && !CARD_LIKE_RUN.test(value);
|
|
3109
|
+
function isPhoneNumbers(value) {
|
|
3110
|
+
if (!record15(value))
|
|
3111
|
+
return false;
|
|
3112
|
+
const types = Object.keys(value);
|
|
3113
|
+
if (types.length !== 1 || !PHONE_TYPES.has(types[0]))
|
|
3114
|
+
return false;
|
|
3115
|
+
const phone2 = value[types[0]];
|
|
3116
|
+
if (!record15(phone2))
|
|
3117
|
+
return false;
|
|
3118
|
+
const keys = Object.keys(phone2);
|
|
3119
|
+
return keys.length === 2 && keys[0] === "country_code" && keys[1] === "subscriber" && typeof phone2.country_code === "string" && COUNTRY_CODE2.test(phone2.country_code) && typeof phone2.subscriber === "string" && SUBSCRIBER.test(phone2.subscriber);
|
|
3120
|
+
}
|
|
3121
|
+
function isCardMember(card) {
|
|
3122
|
+
if (!record15(card) || !inFrameOrder(Object.keys(card)))
|
|
3123
|
+
return false;
|
|
3124
|
+
if (!isCiphertext(card.encrypted_pan))
|
|
3125
|
+
return false;
|
|
3126
|
+
if (typeof card.exp_month !== "string" || !MONTH9.test(card.exp_month))
|
|
3127
|
+
return false;
|
|
3128
|
+
if (typeof card.exp_year !== "string" || !YEAR9.test(card.exp_year))
|
|
3129
|
+
return false;
|
|
3130
|
+
if (typeof card.cvv !== "string" || !CODE3.test(card.cvv))
|
|
3131
|
+
return false;
|
|
3132
|
+
if (typeof card.first6 !== "string" || !FIRST6.test(card.first6))
|
|
3133
|
+
return false;
|
|
3134
|
+
if (typeof card.last4 !== "string" || !LAST4.test(card.last4))
|
|
3135
|
+
return false;
|
|
3136
|
+
if (typeof card.brand !== "string" || !BRANDS.has(card.brand) || cloverBrand(card.first6) !== card.brand)
|
|
3137
|
+
return false;
|
|
3138
|
+
if (own4(card, "address_line1") && !sideText(card.address_line1))
|
|
3139
|
+
return false;
|
|
3140
|
+
if (own4(card, "phone_numbers") && !isPhoneNumbers(card.phone_numbers))
|
|
3141
|
+
return false;
|
|
3142
|
+
if (own4(card, "email_address") && !(sideText(card.email_address, EMAIL_LIMIT) && /^[^\s@]+@[^\s@]+$/.test(card.email_address)))
|
|
3143
|
+
return false;
|
|
3144
|
+
if (own4(card, "name") && !(sideText(card.name) && card.name !== "" && card.name === card.name.trim()))
|
|
3145
|
+
return false;
|
|
3146
|
+
if (own4(card, "address_zip") && !(typeof card.address_zip === "string" && POSTAL_CODE2.test(card.address_zip)))
|
|
3147
|
+
return false;
|
|
3148
|
+
return true;
|
|
3149
|
+
}
|
|
3150
|
+
function cloverBodyVerdict(body, url) {
|
|
3151
|
+
if (url !== void 0 && cloverTokenUrl(url) === null)
|
|
3152
|
+
return refuse21("clover_url_refused");
|
|
3153
|
+
const value = readBody11(body);
|
|
3154
|
+
if (value === null)
|
|
3155
|
+
return refuse21("clover_body_unsupported");
|
|
3156
|
+
const keys = Object.keys(value);
|
|
3157
|
+
if (keys.length !== 1 || keys[0] !== "card" || !isCardMember(value.card))
|
|
3158
|
+
return refuse21("clover_body_unsupported");
|
|
3159
|
+
return CARD20;
|
|
3160
|
+
}
|
|
3161
|
+
// src/tap-payments.js
|
|
3162
|
+
var TAP_PAYMENTS_PSP = "tap_payments";
|
|
3163
|
+
var TAP_PAYMENTS_TOKEN_URL = "https://sdk.tap.company/v2/card/token";
|
|
3164
|
+
var TAP_PAYMENTS_PURPOSES = /* @__PURE__ */ Object.freeze(["CHARGE", "AUTHORIZE"]);
|
|
3165
|
+
var record16 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
3166
|
+
function isTapPaymentsTokenUrl(url) {
|
|
3167
|
+
return url === TAP_PAYMENTS_TOKEN_URL;
|
|
3168
|
+
}
|
|
3169
|
+
var pin6 = (fields) => Object.freeze({
|
|
3170
|
+
...fields,
|
|
3171
|
+
origins: Object.freeze([...fields.origins]),
|
|
3172
|
+
sessions: Object.freeze({ ...fields.sessions }),
|
|
3173
|
+
key: Object.freeze({ ...fields.key })
|
|
3174
|
+
});
|
|
3175
|
+
var TAP_PAYMENTS_MERCHANT_PINS = /* @__PURE__ */ Object.freeze([
|
|
3176
|
+
pin6({
|
|
3177
|
+
id: "casefilegame",
|
|
3178
|
+
merchant: "Casefilegame",
|
|
3179
|
+
tapMerchantId: "67977048",
|
|
3180
|
+
publishableKey: "pk_live_ydlRjrWcLXaVvpsSBQKOie86",
|
|
3181
|
+
environment: "production",
|
|
3182
|
+
origins: ["https://checkout.tap.company"],
|
|
3183
|
+
// The WooCommerce plugin's redirect (Plugin-WooCommerce-All-in-one tap.php 567-586, read 2026-10-17)
|
|
3184
|
+
// creates the src_all charge with save_card false and names no agreement, subscription or destinations.
|
|
3185
|
+
sessions: { saveCard: false, agreement: false, subscription: false, destinations: false },
|
|
3186
|
+
key: {
|
|
3187
|
+
spki: "MIIBIDANBgkqhkiG9w0BAQEFAAOCAQ0AMIIBCAKCAQEAzja2vB+Iyafj2Mm3pFg65z7Yvj9ZeoFLdMBgWFyyjF020r5HSPKVhuZ39uJkjs0U/kWgEpKDzHZAKdtGv36dS33NjMAzYpgFkD8j+9/YWqpvAGRj5nv1b/q7NaiZk3b1wm7aXHJOx5L6rPQf2qDQxhcSNHocU+Uy8wGmGxRRu6QRKN3khaz4o4jJDzqxns4h/ShzHjdZeWIVfpCAyVoED0IESBYrvGEhJeyKnga5XdHdBU2yP8P1huO4RbSKcZv00ZgxVHAQQ9CqArW3TE8SyLLnJPkSpSHHBnIPSQS1z3ld1mImy/zqTd4ltkV6XHpYqVvoPmys2EuZX3pMvCcPGwIBEQ==",
|
|
3188
|
+
sha256: "6eb4e89a1e05a06a39d631f6fb450c052a9cad9935edc1921e84e80207470552",
|
|
3189
|
+
// The shared parser takes exponent 17 only under a pin that names it (rsa-pkcs1v15.js).
|
|
3190
|
+
exponent: 17
|
|
3191
|
+
}
|
|
3192
|
+
})
|
|
3193
|
+
]);
|
|
3194
|
+
var BODY_LIMIT19 = 16384;
|
|
3195
|
+
var ROOT_KEYS7 = /* @__PURE__ */ Object.freeze([
|
|
3196
|
+
"encryptedData",
|
|
3197
|
+
"purpose",
|
|
3198
|
+
"customer",
|
|
3199
|
+
"consent",
|
|
3200
|
+
"merchant",
|
|
3201
|
+
"order",
|
|
3202
|
+
"payment_agreement",
|
|
3203
|
+
"client_ip",
|
|
3204
|
+
"device",
|
|
3205
|
+
"browser",
|
|
3206
|
+
"app"
|
|
3207
|
+
]);
|
|
3208
|
+
var REQUIRED_KEYS2 = /* @__PURE__ */ Object.freeze(["encryptedData", "purpose", "order", "device", "browser", "app"]);
|
|
3209
|
+
var SAVE_PURPOSES = /* @__PURE__ */ Object.freeze(["SAVE_TOKEN", "SAVE_AUTHENTICATED_TOKEN"]);
|
|
3210
|
+
var ORDER_KEYS = /* @__PURE__ */ Object.freeze(["amount", "currency", "id", "description", "metadata", "reference"]);
|
|
3211
|
+
var DEVICE_KEYS3 = /* @__PURE__ */ Object.freeze(["source", "ip"]);
|
|
3212
|
+
var BROWSER_KEYS = /* @__PURE__ */ Object.freeze(["name", "id"]);
|
|
3213
|
+
var APP_KEYS = /* @__PURE__ */ Object.freeze(["identifier", "name", "version", "iframe_version", "sdk_version"]);
|
|
3214
|
+
var CIPHERTEXT_BYTES = /* @__PURE__ */ Object.freeze([128, 256, 384, 512]);
|
|
3215
|
+
var BASE644 = /^[A-Za-z0-9+/]+={0,2}$/;
|
|
3216
|
+
var CURRENCY3 = /^[A-Z]{3}$/;
|
|
3217
|
+
var TEXT_LIMIT6 = 512;
|
|
3218
|
+
var CONTROL9 = /[\u0000-\u001f\u007f]/;
|
|
3219
|
+
var CARD_LONG_DIGITS = /(?:\p{Nd}[\s-]?){12}\p{Nd}/u;
|
|
3220
|
+
var NESTING_LIMIT = 4;
|
|
3221
|
+
var MEMBERS_LIMIT = 64;
|
|
3222
|
+
var refuse22 = (code) => Object.freeze({ verdict: "refuse", code });
|
|
3223
|
+
var CARD21 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
|
|
3224
|
+
function decodedBytes(value) {
|
|
3225
|
+
if (typeof value !== "string" || value.length % 4 !== 0 || !BASE644.test(value))
|
|
3226
|
+
return -1;
|
|
3227
|
+
try {
|
|
3228
|
+
if (btoa(atob(value)) !== value)
|
|
3229
|
+
return -1;
|
|
3230
|
+
}
|
|
3231
|
+
catch {
|
|
3232
|
+
return -1;
|
|
3233
|
+
}
|
|
3234
|
+
const pad = value.endsWith("==") ? 2 : value.endsWith("=") ? 1 : 0;
|
|
3235
|
+
return value.length / 4 * 3 - pad;
|
|
3236
|
+
}
|
|
3237
|
+
function isTapPaymentsCiphertext(value) {
|
|
3238
|
+
return CIPHERTEXT_BYTES.includes(decodedBytes(value));
|
|
3239
|
+
}
|
|
3240
|
+
function readBody12(body) {
|
|
3241
|
+
if (typeof body !== "string" || body === "" || body.length > BODY_LIMIT19)
|
|
3242
|
+
return null;
|
|
3243
|
+
try {
|
|
3244
|
+
const value = JSON.parse(body);
|
|
3245
|
+
return record16(value) && JSON.stringify(value) === body ? value : null;
|
|
3246
|
+
}
|
|
3247
|
+
catch {
|
|
3248
|
+
return null;
|
|
3249
|
+
}
|
|
3250
|
+
}
|
|
3251
|
+
var inOrder3 = (keys, order) => {
|
|
3252
|
+
let at = -1;
|
|
3253
|
+
for (const key of keys) {
|
|
3254
|
+
const next = order.indexOf(key);
|
|
3255
|
+
if (next <= at)
|
|
3256
|
+
return false;
|
|
3257
|
+
at = next;
|
|
3258
|
+
}
|
|
3259
|
+
return true;
|
|
3260
|
+
};
|
|
3261
|
+
var onlyKeys = (value, allowed) => record16(value) && Object.keys(value).every((key) => allowed.includes(key));
|
|
3262
|
+
var plainText4 = (value) => typeof value === "string" && value.length <= TEXT_LIMIT6 && !CONTROL9.test(value) && !CARD_LONG_DIGITS.test(value);
|
|
3263
|
+
var plainScalar = (value) => value === null || typeof value === "boolean" || typeof value === "number" && Number.isFinite(value) && !CARD_LONG_DIGITS.test(String(value)) || plainText4(value);
|
|
3264
|
+
function plainJson(value, depth = 0, budget = { members: 0 }) {
|
|
3265
|
+
if (depth > NESTING_LIMIT)
|
|
3266
|
+
return false;
|
|
3267
|
+
if (Array.isArray(value)) {
|
|
3268
|
+
budget.members += value.length;
|
|
3269
|
+
return budget.members <= MEMBERS_LIMIT && value.every((item) => plainJson(item, depth + 1, budget));
|
|
3270
|
+
}
|
|
3271
|
+
if (record16(value)) {
|
|
3272
|
+
const keys = Object.keys(value);
|
|
3273
|
+
budget.members += keys.length;
|
|
3274
|
+
return budget.members <= MEMBERS_LIMIT && keys.every((key) => plainText4(key) && plainJson(value[key], depth + 1, budget));
|
|
3275
|
+
}
|
|
3276
|
+
return plainScalar(value);
|
|
3277
|
+
}
|
|
3278
|
+
function soundOrder(order) {
|
|
3279
|
+
if (!onlyKeys(order, ORDER_KEYS) || !inOrder3(Object.keys(order), ORDER_KEYS))
|
|
3280
|
+
return false;
|
|
3281
|
+
if ("amount" in order && !(typeof order.amount === "number" && Number.isFinite(order.amount) && order.amount >= 0 && !CARD_LONG_DIGITS.test(String(order.amount))))
|
|
3282
|
+
return false;
|
|
3283
|
+
if ("currency" in order && !(typeof order.currency === "string" && CURRENCY3.test(order.currency)))
|
|
3284
|
+
return false;
|
|
3285
|
+
if ("id" in order && !plainText4(order.id))
|
|
3286
|
+
return false;
|
|
3287
|
+
if ("description" in order && !plainText4(order.description))
|
|
3288
|
+
return false;
|
|
3289
|
+
if ("metadata" in order && !plainJson(order.metadata))
|
|
3290
|
+
return false;
|
|
3291
|
+
return !("reference" in order) || plainJson(order.reference);
|
|
3292
|
+
}
|
|
3293
|
+
var soundDevice2 = (device) => onlyKeys(device, DEVICE_KEYS3) && inOrder3(Object.keys(device), DEVICE_KEYS3) && (device.source === "web" || device.source === "app") && (!("ip" in device) || plainText4(device.ip));
|
|
3294
|
+
var soundBrowser = (browser) => onlyKeys(browser, BROWSER_KEYS) && inOrder3(Object.keys(browser), BROWSER_KEYS) && (!("name" in browser) || plainText4(browser.name)) && plainText4(browser.id);
|
|
3295
|
+
var versionValue = (value) => plainText4(value) || typeof value === "number" && Number.isFinite(value) && !CARD_LONG_DIGITS.test(String(value));
|
|
3296
|
+
var soundApp = (app) => onlyKeys(app, APP_KEYS) && inOrder3(Object.keys(app), APP_KEYS) && app.identifier === "card_sdk" && app.name === "card_sdk" && ["version", "iframe_version", "sdk_version"].every((key) => !(key in app) || versionValue(app[key]));
|
|
3297
|
+
function tapPaymentsBodyVerdict(body) {
|
|
3298
|
+
const value = readBody12(body);
|
|
3299
|
+
if (value === null)
|
|
3300
|
+
return refuse22("tap_payments_body_unsupported");
|
|
3301
|
+
const keys = Object.keys(value);
|
|
3302
|
+
if (!keys.every((key) => ROOT_KEYS7.includes(key)) || !inOrder3(keys, ROOT_KEYS7) || !REQUIRED_KEYS2.every((key) => keys.includes(key))) {
|
|
3303
|
+
return refuse22("tap_payments_body_unsupported");
|
|
3304
|
+
}
|
|
3305
|
+
if (!isTapPaymentsCiphertext(value.encryptedData))
|
|
3306
|
+
return refuse22("tap_payments_body_unsupported");
|
|
3307
|
+
if (typeof value.purpose !== "string")
|
|
3308
|
+
return refuse22("tap_payments_body_unsupported");
|
|
3309
|
+
if (SAVE_PURPOSES.includes(value.purpose))
|
|
3310
|
+
return refuse22("tap_payments_keep_on_file");
|
|
3311
|
+
if (!TAP_PAYMENTS_PURPOSES.includes(value.purpose))
|
|
3312
|
+
return refuse22("tap_payments_body_unsupported");
|
|
3313
|
+
if ("payment_agreement" in value && value.payment_agreement !== null)
|
|
3314
|
+
return refuse22("tap_payments_keep_on_file");
|
|
3315
|
+
if ("consent" in value) {
|
|
3316
|
+
const consent = value.consent;
|
|
3317
|
+
if (!record16(consent) || Object.keys(consent).length !== 1 || typeof consent.acknowledge !== "boolean")
|
|
3318
|
+
return refuse22("tap_payments_body_unsupported");
|
|
3319
|
+
if (consent.acknowledge)
|
|
3320
|
+
return refuse22("tap_payments_keep_on_file");
|
|
3321
|
+
}
|
|
3322
|
+
if ("customer" in value && !(record16(value.customer) && plainJson(value.customer)) || "merchant" in value && !(record16(value.merchant) && plainJson(value.merchant)) || "client_ip" in value && value.client_ip !== null && !plainText4(value.client_ip) || !soundOrder(value.order) || !soundDevice2(value.device) || !soundBrowser(value.browser) || !soundApp(value.app)) {
|
|
3323
|
+
return refuse22("tap_payments_body_unsupported");
|
|
3324
|
+
}
|
|
3325
|
+
return CARD21;
|
|
3326
|
+
}
|
|
3327
|
+
// src/conekta.js
|
|
3328
|
+
var CONEKTA_PSP = "conekta";
|
|
3329
|
+
var CONEKTA_TOKENS_URL = "https://api.conekta.io/tokens";
|
|
3330
|
+
var CONEKTA_COMPONENT_TOKEN_URLS = /* @__PURE__ */ Object.freeze(["https://pay.conekta.com/api/tokens", "https://pay.conekta.com/api/tokens/"]);
|
|
3331
|
+
var CONEKTA_CARD_KEYS = /* @__PURE__ */ Object.freeze(["number", "name", "cvc", "exp_month", "exp_year", "exp", "address", "device_fingerprint"]);
|
|
3332
|
+
var CONEKTA_ADDRESS_KEYS = /* @__PURE__ */ Object.freeze(["street1", "street2", "street3", "city", "state", "zip", "country"]);
|
|
3333
|
+
var BODY_LIMIT20 = 4096;
|
|
3334
|
+
var URL_LIMIT8 = 64;
|
|
3335
|
+
var NUMBER5 = /^[0-9]{12,19}$/;
|
|
3336
|
+
var SECURITY_CODE13 = /^[0-9]{3,4}$/;
|
|
3337
|
+
var MONTH10 = /^(?:0?[1-9]|1[0-2])$/;
|
|
3338
|
+
var YEAR10 = /^(?:[0-9]{2}|20[0-9]{2})$/;
|
|
3339
|
+
var EXPIRY2 = /^(?:0[1-9]|1[0-2])\/(?:[0-9]{2}|20[0-9]{2})$/;
|
|
3340
|
+
var FINGERPRINT = /^(?:[a-z0-9]{31,32})?$/;
|
|
3341
|
+
var LETTERS = "A-Za-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u017F";
|
|
3342
|
+
var PAGE_NAME2 = new RegExp(`^[${LETTERS} .'-]{1,64}$`);
|
|
3343
|
+
var HAS_LETTER = new RegExp(`[${LETTERS}]`);
|
|
3344
|
+
var ADDRESS_VALUE = new RegExp(`^[\\x20-\\x7e\\u00a0-\\u017f]{0,128}$`);
|
|
3345
|
+
var PAN_LIKE5 = new RegExp(`(?:[0-9][^0-9${LETTERS}]*){12,}`);
|
|
3346
|
+
var record17 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
3347
|
+
var refuse23 = (code) => Object.freeze({ verdict: "refuse", code });
|
|
3348
|
+
var CARD22 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
|
|
3349
|
+
function conektaTarget(url) {
|
|
3350
|
+
if (typeof url !== "string" || url.length > URL_LIMIT8)
|
|
3351
|
+
return null;
|
|
3352
|
+
if (url === CONEKTA_TOKENS_URL)
|
|
3353
|
+
return Object.freeze({ kind: "tokens" });
|
|
3354
|
+
return CONEKTA_COMPONENT_TOKEN_URLS.includes(url) ? Object.freeze({ kind: "component" }) : null;
|
|
3355
|
+
}
|
|
3356
|
+
function readJson4(body) {
|
|
3357
|
+
if (typeof body !== "string" || body === "" || body.length > BODY_LIMIT20)
|
|
3358
|
+
return null;
|
|
3359
|
+
try {
|
|
3360
|
+
const value = JSON.parse(body);
|
|
3361
|
+
return record17(value) && JSON.stringify(value) === body ? value : null;
|
|
3362
|
+
}
|
|
3363
|
+
catch {
|
|
3364
|
+
return null;
|
|
3365
|
+
}
|
|
3366
|
+
}
|
|
3367
|
+
function componentBody(value) {
|
|
3368
|
+
const keys = Object.keys(value);
|
|
3369
|
+
return keys.length === 2 && keys[0] === "data" && keys[1] === "key" && typeof value.data === "string" && typeof value.key === "string";
|
|
3370
|
+
}
|
|
3371
|
+
function soundAddress(address2) {
|
|
3372
|
+
if (!record17(address2))
|
|
3373
|
+
return false;
|
|
3374
|
+
const keys = Object.keys(address2);
|
|
3375
|
+
return keys.length > 0 && keys.every((key) => CONEKTA_ADDRESS_KEYS.includes(key) && typeof address2[key] === "string" && ADDRESS_VALUE.test(address2[key]) && !PAN_LIKE5.test(address2[key])) && keys.some((key) => address2[key] !== "");
|
|
3376
|
+
}
|
|
3377
|
+
function judgeCard(card) {
|
|
3378
|
+
if (!record17(card))
|
|
3379
|
+
return "conekta_body_unsupported";
|
|
3380
|
+
const keys = Object.keys(card);
|
|
3381
|
+
if (!keys.every((key) => CONEKTA_CARD_KEYS.includes(key)) || keys[keys.length - 1] !== "device_fingerprint" || !["number", "name", "cvc", "exp_month", "exp_year"].every((key) => keys.includes(key)))
|
|
3382
|
+
return "conekta_body_unsupported";
|
|
3383
|
+
if (typeof card.number !== "string" || !NUMBER5.test(card.number) || typeof card.cvc !== "string" || !SECURITY_CODE13.test(card.cvc) || typeof card.exp_month !== "string" || !MONTH10.test(card.exp_month) || typeof card.exp_year !== "string" || !YEAR10.test(card.exp_year) || typeof card.name !== "string" || !PAGE_NAME2.test(card.name) || !HAS_LETTER.test(card.name) || typeof card.device_fingerprint !== "string" || !FINGERPRINT.test(card.device_fingerprint))
|
|
3384
|
+
return "conekta_body_unsupported";
|
|
3385
|
+
if (keys.includes("exp") && (typeof card.exp !== "string" || !EXPIRY2.test(card.exp) || card.exp !== `${card.exp_month}/${card.exp_year}`)) {
|
|
3386
|
+
return "conekta_body_unsupported";
|
|
3387
|
+
}
|
|
3388
|
+
if (keys.includes("address") && !soundAddress(card.address))
|
|
3389
|
+
return "conekta_body_unsupported";
|
|
3390
|
+
return null;
|
|
3391
|
+
}
|
|
3392
|
+
function conektaBodyVerdict(body, url) {
|
|
3393
|
+
if (url !== void 0) {
|
|
3394
|
+
const target = conektaTarget(url);
|
|
3395
|
+
if (target === null)
|
|
3396
|
+
return refuse23("conekta_url_refused");
|
|
3397
|
+
if (target.kind === "component")
|
|
3398
|
+
return refuse23("conekta_component_unsupported");
|
|
3399
|
+
}
|
|
3400
|
+
const value = readJson4(body);
|
|
3401
|
+
if (value === null)
|
|
3402
|
+
return refuse23("conekta_body_unsupported");
|
|
3403
|
+
if (componentBody(value))
|
|
3404
|
+
return refuse23("conekta_component_unsupported");
|
|
3405
|
+
const keys = Object.keys(value);
|
|
3406
|
+
if (keys.length !== 1 || keys[0] !== "card")
|
|
3407
|
+
return refuse23("conekta_body_unsupported");
|
|
3408
|
+
const code = judgeCard(value.card);
|
|
3409
|
+
return code === null ? CARD22 : refuse23(code);
|
|
3410
|
+
}
|
|
3411
|
+
var HOLDER4 = new RegExp(`^[${LETTERS}](?:[${LETTERS} .'-]{0,62}[${LETTERS}.])?$`);
|
|
3412
|
+
var ERROR_TYPE_STATUS = /* @__PURE__ */ Object.freeze({
|
|
3413
|
+
malformed_request_error: 400,
|
|
3414
|
+
authentication_error: 401,
|
|
3415
|
+
processing_error: 402,
|
|
3416
|
+
resource_not_found_error: 404,
|
|
3417
|
+
conflict_error: 409,
|
|
3418
|
+
precondition_required_error: 412,
|
|
3419
|
+
parameter_validation_error: 422
|
|
3420
|
+
});
|
|
3421
|
+
var CONEKTA_ANSWER_ERROR_TYPES = /* @__PURE__ */ Object.freeze(Object.keys(ERROR_TYPE_STATUS));
|
|
3422
|
+
// src/makecommerce.js
|
|
3423
|
+
var MAKECOMMERCE_PSP = "makecommerce";
|
|
3424
|
+
var MAKECOMMERCE_CARD_HOSTS = /* @__PURE__ */ Object.freeze({ "cc.maksekeskus.ee": "production", "cc-test.maksekeskus.ee": "test" });
|
|
3425
|
+
var MAKECOMMERCE_CARD_PATH = "/card-payment";
|
|
3426
|
+
var MAKECOMMERCE_FRAME_VERSIONS = /* @__PURE__ */ Object.freeze(["cde.31", "cde.35"]);
|
|
3427
|
+
var BODY_LIMIT21 = 4096;
|
|
3428
|
+
var HEAD_KEYS = /* @__PURE__ */ Object.freeze(["transaction", "customer", "ocp", "checkout"]);
|
|
3429
|
+
var TAIL_KEYS = /* @__PURE__ */ Object.freeze(["card", "tokenizer", "shop_id", "client_data", "hostname", "public_key"]);
|
|
3430
|
+
var CARD_KEYS9 = /* @__PURE__ */ Object.freeze(["name", "number", "exp_month", "exp_year", "cvc"]);
|
|
3431
|
+
var CLIENT_KEYS = /* @__PURE__ */ Object.freeze(["client_fingerprint", "client_tz_offset", "client_time"]);
|
|
3432
|
+
var UUID3 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;
|
|
3433
|
+
var EMAIL4 = /^(?!.*\.\.)(?!.*-$)(?!^-)[A-Za-z0-9._%+-]+@[A-Za-z0-9]+(?:-[A-Za-z0-9]+)*(?:\.[A-Za-z]{2,})+$/;
|
|
3434
|
+
var CARD_NUMBER11 = /^[0-9]{13,19}$/;
|
|
3435
|
+
var MONTH11 = /^(?:0[1-9]|1[0-2])$/;
|
|
3436
|
+
var YEAR11 = /^[0-9]{2}$/;
|
|
3437
|
+
var CODE4 = /^[0-9]{3}$/;
|
|
3438
|
+
var NAME_LIMIT3 = 100;
|
|
3439
|
+
var NAME_WORD = /[a-z]+/gi;
|
|
3440
|
+
var printable2 = (text7) => [...text7].every((character) => {
|
|
3441
|
+
const point = character.codePointAt(0);
|
|
3442
|
+
return point >= 32 && !(point >= 127 && point <= 159) && point !== 8232 && point !== 8233;
|
|
3443
|
+
});
|
|
3444
|
+
var FINGERPRINT2 = /^[0-9a-f]{40}$/i;
|
|
3445
|
+
var HOSTNAME = /^(?=.{1,253}$)[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?(?:\.[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)+$/;
|
|
3446
|
+
var PUBLISHABLE_KEY = /^[A-Za-z0-9]{16,64}$/;
|
|
3447
|
+
var record18 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
3448
|
+
var sameKeys8 = (value, keys) => {
|
|
3449
|
+
const own6 = Object.keys(value);
|
|
3450
|
+
return own6.length === keys.length && own6.every((key, at) => key === keys[at]);
|
|
3451
|
+
};
|
|
3452
|
+
var refuse24 = (code) => Object.freeze({ verdict: "refuse", code });
|
|
3453
|
+
var CARD23 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
|
|
3454
|
+
function luhn4(digits3) {
|
|
3455
|
+
let sum = 0;
|
|
3456
|
+
for (let at = 0; at < digits3.length; at += 1) {
|
|
3457
|
+
let digit = Number(digits3[digits3.length - 1 - at]);
|
|
3458
|
+
if (at % 2 === 1) {
|
|
3459
|
+
digit *= 2;
|
|
3460
|
+
if (digit > 9)
|
|
3461
|
+
digit -= 9;
|
|
3462
|
+
}
|
|
3463
|
+
sum += digit;
|
|
3464
|
+
}
|
|
3465
|
+
return sum % 10 === 0;
|
|
3466
|
+
}
|
|
3467
|
+
function makecommerceCardUrl(url) {
|
|
3468
|
+
if (typeof url !== "string" || url.length > 256 || url.includes("?") || url.includes("#"))
|
|
3469
|
+
return null;
|
|
3470
|
+
let parsed;
|
|
3471
|
+
try {
|
|
3472
|
+
parsed = new URL(url);
|
|
3473
|
+
}
|
|
3474
|
+
catch {
|
|
3475
|
+
return null;
|
|
3476
|
+
}
|
|
3477
|
+
if (parsed.href !== url || parsed.protocol !== "https:" || parsed.port || parsed.username || parsed.password || parsed.search || parsed.hash || parsed.pathname !== MAKECOMMERCE_CARD_PATH)
|
|
3478
|
+
return null;
|
|
3479
|
+
if (!Object.prototype.hasOwnProperty.call(MAKECOMMERCE_CARD_HOSTS, parsed.hostname))
|
|
3480
|
+
return null;
|
|
3481
|
+
return Object.freeze({ host: parsed.hostname, environment: MAKECOMMERCE_CARD_HOSTS[parsed.hostname] });
|
|
3482
|
+
}
|
|
3483
|
+
function isMakecommerceCardUrl(url) {
|
|
3484
|
+
return makecommerceCardUrl(url) !== null;
|
|
3485
|
+
}
|
|
3486
|
+
function readBody13(body) {
|
|
3487
|
+
if (typeof body !== "string" || body === "" || body.length > BODY_LIMIT21)
|
|
3488
|
+
return null;
|
|
3489
|
+
let value;
|
|
3490
|
+
try {
|
|
3491
|
+
value = JSON.parse(body);
|
|
3492
|
+
if (!record18(value) || JSON.stringify(value) !== body)
|
|
3493
|
+
return null;
|
|
3494
|
+
}
|
|
3495
|
+
catch {
|
|
3496
|
+
return null;
|
|
3497
|
+
}
|
|
3498
|
+
return value;
|
|
3499
|
+
}
|
|
3500
|
+
var box = (value) => record18(value) && sameKeys8(value, ["requested"]) && typeof value.requested === "boolean";
|
|
3501
|
+
var holderName = (name) => typeof name === "string" && name.length <= NAME_LIMIT3 && printable2(name) && (name.match(NAME_WORD) ?? []).length > 1;
|
|
3502
|
+
function frameCardValues(card) {
|
|
3503
|
+
return record18(card) && sameKeys8(card, CARD_KEYS9) && holderName(card.name) && typeof card.number === "string" && CARD_NUMBER11.test(card.number) && luhn4(card.number) && typeof card.exp_month === "string" && MONTH11.test(card.exp_month) && typeof card.exp_year === "string" && YEAR11.test(card.exp_year) && typeof card.cvc === "string" && CODE4.test(card.cvc);
|
|
3504
|
+
}
|
|
3505
|
+
function clientData(value) {
|
|
3506
|
+
return record18(value) && sameKeys8(value, CLIENT_KEYS) && typeof value.client_fingerprint === "string" && FINGERPRINT2.test(value.client_fingerprint) && Number.isFinite(value.client_tz_offset) && Math.abs(value.client_tz_offset) <= 14 && Number.isSafeInteger(value.client_time) && value.client_time > 0;
|
|
3507
|
+
}
|
|
3508
|
+
function makecommerceBodyVerdict(body, url) {
|
|
3509
|
+
if (url !== void 0 && !isMakecommerceCardUrl(url))
|
|
3510
|
+
return refuse24("makecommerce_url_refused");
|
|
3511
|
+
const value = readBody13(body);
|
|
3512
|
+
if (value === null)
|
|
3513
|
+
return refuse24("makecommerce_body_unsupported");
|
|
3514
|
+
const recurring = Object.prototype.hasOwnProperty.call(value, "recurring");
|
|
3515
|
+
if (!sameKeys8(value, [...HEAD_KEYS, ...recurring ? ["recurring"] : [], ...TAIL_KEYS]))
|
|
3516
|
+
return refuse24("makecommerce_body_unsupported");
|
|
3517
|
+
if (!record18(value.transaction) || !sameKeys8(value.transaction, ["id"]) || typeof value.transaction.id !== "string" || !UUID3.test(value.transaction.id) || !record18(value.customer) || !sameKeys8(value.customer, ["email"]) || typeof value.customer.email !== "string" || value.customer.email.length > 254 || !EMAIL4.test(value.customer.email) || !box(value.ocp) || recurring && !box(value.recurring) || !MAKECOMMERCE_FRAME_VERSIONS.includes(value.checkout) || value.tokenizer !== value.checkout || !frameCardValues(value.card) || typeof value.shop_id !== "string" || !UUID3.test(value.shop_id) || !clientData(value.client_data) || typeof value.hostname !== "string" || !HOSTNAME.test(value.hostname) || typeof value.public_key !== "string" || !PUBLISHABLE_KEY.test(value.public_key))
|
|
3518
|
+
return refuse24("makecommerce_body_unsupported");
|
|
3519
|
+
if (value.ocp.requested || recurring && value.recurring.requested)
|
|
3520
|
+
return refuse24("makecommerce_card_saving_refused");
|
|
3521
|
+
return CARD23;
|
|
3522
|
+
}
|
|
3523
|
+
// src/tokenex-iframe.js
|
|
3524
|
+
var TOKENEX_IFRAME_PSP = "tokenex_iframe";
|
|
3525
|
+
var TOKENEX_IFRAME_HOSTS = Object.freeze(["htp.tokenex.com", "test-htp.tokenex.com"]);
|
|
3526
|
+
var TOKENEX_IFRAME_PATH = "/iframe/v3";
|
|
3527
|
+
var TOKENEX_IFRAME_REFUSAL_REASONS = Object.freeze(["unsupported", "brand_mismatch", "unreviewed_account"]);
|
|
3528
|
+
var TOKENEX_IFRAME_BODY_KEYS = Object.freeze([
|
|
3529
|
+
"TokenExID",
|
|
3530
|
+
"Origin",
|
|
3531
|
+
"AuthenticationKey",
|
|
3532
|
+
"Timestamp",
|
|
3533
|
+
"Data",
|
|
3534
|
+
"CvvValue",
|
|
3535
|
+
"TokenScheme",
|
|
3536
|
+
"CvvOnly",
|
|
3537
|
+
"PCI",
|
|
3538
|
+
"ReturnHash",
|
|
3539
|
+
"use3DS",
|
|
3540
|
+
"ThreeDSMethodNotificationUrl",
|
|
3541
|
+
"kountSessionId",
|
|
3542
|
+
"fraudMerchantId",
|
|
3543
|
+
"UseKount",
|
|
3544
|
+
"kountMode",
|
|
3545
|
+
"kountAnId",
|
|
3546
|
+
"FraudServicesRiskRequestModel",
|
|
3547
|
+
"EnforceLuhnCompliance",
|
|
3548
|
+
"CustomDataLuhnCheck"
|
|
3549
|
+
]);
|
|
3550
|
+
var TOKENEX_IFRAME_TOKEN_SCHEMES = Object.freeze(["sixTOKENfour"]);
|
|
3551
|
+
var TOKENEX_IFRAME_REVIEWED_ACCOUNTS = Object.freeze({
|
|
3552
|
+
"htp.tokenex.com": Object.freeze({}),
|
|
3553
|
+
"test-htp.tokenex.com": Object.freeze({})
|
|
3554
|
+
});
|
|
3555
|
+
var TOKENEX_IFRAME_ACCOUNT_NAMES = Object.freeze({
|
|
3556
|
+
"htp.tokenex.com": Object.freeze({}),
|
|
3557
|
+
"test-htp.tokenex.com": Object.freeze({})
|
|
3558
|
+
});
|
|
3559
|
+
var BODY_LIMIT22 = 8192;
|
|
3560
|
+
var URL_LIMIT9 = 2048;
|
|
3561
|
+
var record19 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
3562
|
+
var owns5 = (value, key) => Object.prototype.hasOwnProperty.call(value, key);
|
|
3563
|
+
var exact2 = (pattern, value) => typeof value === "string" && pattern.exec(value)?.[0] === value;
|
|
3564
|
+
var text4 = (value, max) => typeof value === "string" && value.length <= max && !/[\u0000-\u001f\u007f]/.test(value);
|
|
3565
|
+
var digits = (value, min, max) => typeof value === "string" && value.length >= min && value.length <= max && !/[^0-9]/.test(value);
|
|
3566
|
+
var panLike = (value) => (value.match(/\p{Nd}/gu) ?? []).length >= 12;
|
|
3567
|
+
var plain = (value, max) => text4(value, max) && !panLike(value);
|
|
3568
|
+
var TOKENEX_ID = /^[0-9]{16}$/;
|
|
3569
|
+
var AUTHENTICATION_KEY = /^[A-Za-z0-9+/]{43}=$/;
|
|
3570
|
+
var TIMESTAMP = /^20[0-9]{2}(?:0[1-9]|1[0-2])(?:0[1-9]|[12][0-9]|3[01])(?:[01][0-9]|2[0-3])[0-5][0-9][0-5][0-9]$/;
|
|
3571
|
+
function isOrigin(value) {
|
|
3572
|
+
if (typeof value !== "string" || value.length > 255 || !value.startsWith("https://"))
|
|
3573
|
+
return false;
|
|
3574
|
+
try {
|
|
3575
|
+
return new URL(value).origin === value;
|
|
3576
|
+
}
|
|
3577
|
+
catch {
|
|
3578
|
+
return false;
|
|
3579
|
+
}
|
|
3580
|
+
}
|
|
3581
|
+
var BOUND = {
|
|
3582
|
+
TokenExID: (value) => exact2(TOKENEX_ID, value),
|
|
3583
|
+
Origin: isOrigin,
|
|
3584
|
+
AuthenticationKey: (value) => exact2(AUTHENTICATION_KEY, value),
|
|
3585
|
+
Timestamp: (value) => exact2(TIMESTAMP, value),
|
|
3586
|
+
TokenScheme: (value) => TOKENEX_IFRAME_TOKEN_SCHEMES.includes(value)
|
|
3587
|
+
};
|
|
3588
|
+
var BOUND_KEYS = Object.keys(BOUND);
|
|
3589
|
+
var BOOLEAN = /^(?:true|false)$/i;
|
|
3590
|
+
var QUERY_RULES = {
|
|
3591
|
+
...BOUND,
|
|
3592
|
+
Mode: (value) => value === "Data",
|
|
3593
|
+
PCI: (value) => exact2(/^true$/i, value),
|
|
3594
|
+
CVV: (value) => exact2(/^true$/i, value),
|
|
3595
|
+
Container: (value) => exact2(/^[A-Za-z][A-Za-z0-9_-]{0,63}$/, value),
|
|
3596
|
+
CvvContainer: (value) => exact2(/^[A-Za-z][A-Za-z0-9_-]{0,63}$/, value),
|
|
3597
|
+
EnforceLuhnCompliance: (value) => exact2(BOOLEAN, value),
|
|
3598
|
+
CustomDataLabel: (value) => plain(value, 64),
|
|
3599
|
+
CustomCvvDataLabel: (value) => plain(value, 64),
|
|
3600
|
+
ExpiresInSeconds: (value) => exact2(/^[1-9][0-9]{0,3}$/, value),
|
|
3601
|
+
ReturnAutoCompleteValues: (value) => exact2(BOOLEAN, value)
|
|
3602
|
+
};
|
|
3603
|
+
var QUERY_REQUIRED = [...BOUND_KEYS, "Mode", "PCI", "CVV"];
|
|
3604
|
+
function readQuery(search) {
|
|
3605
|
+
if (typeof search !== "string" || !search.startsWith("?") || search.length < 2)
|
|
3606
|
+
return null;
|
|
3607
|
+
const query = /* @__PURE__ */ new Map();
|
|
3608
|
+
for (const chunk of search.slice(1).split("&")) {
|
|
3609
|
+
const eq = chunk.indexOf("=");
|
|
3610
|
+
if (eq < 1)
|
|
3611
|
+
return null;
|
|
3612
|
+
let key, value;
|
|
3613
|
+
try {
|
|
3614
|
+
key = decodeURIComponent(chunk.slice(0, eq));
|
|
3615
|
+
value = decodeURIComponent(chunk.slice(eq + 1));
|
|
3616
|
+
}
|
|
3617
|
+
catch {
|
|
3618
|
+
return null;
|
|
3619
|
+
}
|
|
3620
|
+
if (query.has(key) || !owns5(QUERY_RULES, key) || !QUERY_RULES[key](value))
|
|
3621
|
+
return null;
|
|
3622
|
+
query.set(key, value);
|
|
3623
|
+
}
|
|
3624
|
+
return QUERY_REQUIRED.every((key) => query.has(key)) ? query : null;
|
|
3625
|
+
}
|
|
3626
|
+
function tokenexIframeTarget(url) {
|
|
3627
|
+
if (typeof url !== "string" || url.length > URL_LIMIT9 || url.includes("#"))
|
|
3628
|
+
return null;
|
|
3629
|
+
let parsed;
|
|
3630
|
+
try {
|
|
3631
|
+
parsed = new URL(url);
|
|
3632
|
+
}
|
|
3633
|
+
catch {
|
|
3634
|
+
return null;
|
|
3635
|
+
}
|
|
3636
|
+
if (parsed.href !== url || parsed.protocol !== "https:" || parsed.port || parsed.username || parsed.password)
|
|
3637
|
+
return null;
|
|
3638
|
+
if (!TOKENEX_IFRAME_HOSTS.includes(parsed.hostname) || parsed.pathname !== TOKENEX_IFRAME_PATH)
|
|
3639
|
+
return null;
|
|
3640
|
+
const query = readQuery(parsed.search);
|
|
3641
|
+
return query ? { host: parsed.hostname, query } : null;
|
|
3642
|
+
}
|
|
3643
|
+
var PLACEHOLDER = /^[0-9]{1,19}(?: [0-9]{1,19}){0,5}$/;
|
|
3644
|
+
var placeholderDigits = (value) => exact2(PLACEHOLDER, value) && value.length <= 23 ? value.replace(/ /g, "") : null;
|
|
3645
|
+
var RULES = {
|
|
3646
|
+
...BOUND,
|
|
3647
|
+
Data: (value) => {
|
|
3648
|
+
const pan = placeholderDigits(value);
|
|
3649
|
+
return pan !== null && pan.length >= 13 && pan.length <= 19;
|
|
3650
|
+
},
|
|
3651
|
+
CvvValue: (value) => digits(value, 3, 4),
|
|
3652
|
+
CvvOnly: (value) => value === "False",
|
|
3653
|
+
PCI: (value) => value === "True",
|
|
3654
|
+
ReturnHash: (value) => value === null,
|
|
3655
|
+
use3DS: (value) => value === "False",
|
|
3656
|
+
ThreeDSMethodNotificationUrl: (value) => value === "",
|
|
3657
|
+
kountSessionId: (value) => value === "",
|
|
3658
|
+
fraudMerchantId: (value) => value === "",
|
|
3659
|
+
UseKount: (value) => value === "False",
|
|
3660
|
+
kountMode: (value) => value === "",
|
|
3661
|
+
kountAnId: (value) => value === "",
|
|
3662
|
+
FraudServicesRiskRequestModel: (value) => value === "",
|
|
3663
|
+
EnforceLuhnCompliance: (value) => value === "true" || value === "false",
|
|
3664
|
+
CustomDataLuhnCheck: (value) => value === true
|
|
3665
|
+
};
|
|
3666
|
+
function readJson5(body, limit) {
|
|
3667
|
+
if (typeof body !== "string" || body === "" || body.length > limit)
|
|
3668
|
+
return null;
|
|
3669
|
+
try {
|
|
3670
|
+
const value = JSON.parse(body);
|
|
3671
|
+
return record19(value) ? value : null;
|
|
3672
|
+
}
|
|
3673
|
+
catch {
|
|
3674
|
+
return null;
|
|
3675
|
+
}
|
|
3676
|
+
}
|
|
3677
|
+
function judgeBody4(body) {
|
|
3678
|
+
const value = readJson5(body, BODY_LIMIT22);
|
|
3679
|
+
if (!value || JSON.stringify(value) !== body)
|
|
3680
|
+
return null;
|
|
3681
|
+
const keys = Object.keys(value);
|
|
3682
|
+
if (keys.length !== TOKENEX_IFRAME_BODY_KEYS.length || keys.some((key, index) => key !== TOKENEX_IFRAME_BODY_KEYS[index]))
|
|
3683
|
+
return null;
|
|
3684
|
+
return keys.every((key) => RULES[key](value[key])) ? value : null;
|
|
3685
|
+
}
|
|
3686
|
+
function carriesCard2(body) {
|
|
3687
|
+
const value = readJson5(body, BODY_LIMIT22 * 4);
|
|
3688
|
+
return value !== null && typeof value.Data === "string" && value.Data !== "";
|
|
3689
|
+
}
|
|
3690
|
+
function bindingRefusal(target, value) {
|
|
3691
|
+
return BOUND_KEYS.every((key) => target.query.get(key) === value[key]) ? null : "unsupported";
|
|
3692
|
+
}
|
|
3693
|
+
var TOKENEX_IFRAME_GATE_CODES = Object.freeze(["tokenex_iframe_url_refused", "tokenex_iframe_body_unsupported", "tokenex_iframe_query_mismatch"]);
|
|
3694
|
+
function tokenexIframeBodyVerdict(body, url) {
|
|
3695
|
+
if (!carriesCard2(body))
|
|
3696
|
+
return { verdict: "continue" };
|
|
3697
|
+
const target = url !== void 0 ? tokenexIframeTarget(url) : null;
|
|
3698
|
+
if (url !== void 0 && !target)
|
|
3699
|
+
return { verdict: "refuse", code: "tokenex_iframe_url_refused" };
|
|
3700
|
+
const value = judgeBody4(body);
|
|
3701
|
+
if (!value)
|
|
3702
|
+
return { verdict: "refuse", code: "tokenex_iframe_body_unsupported" };
|
|
3703
|
+
if (target && bindingRefusal(target, value))
|
|
3704
|
+
return { verdict: "refuse", code: "tokenex_iframe_query_mismatch" };
|
|
3705
|
+
return { verdict: "card" };
|
|
3706
|
+
}
|
|
3707
|
+
var SUCCESS_RULES = {
|
|
3708
|
+
token: (value) => digits(value, 13, 19),
|
|
3709
|
+
firstSix: (value) => digits(value, 6, 6),
|
|
3710
|
+
lastFour: (value) => digits(value, 4, 4),
|
|
3711
|
+
referenceNumber: (value) => exact2(/^[A-Za-z0-9-]{1,64}$/, value),
|
|
3712
|
+
tokenHMAC: (value) => exact2(/^[A-Za-z0-9+/]{1,128}={0,2}$/, value),
|
|
3713
|
+
cvvIncluded: (value) => typeof value === "boolean"
|
|
3714
|
+
};
|
|
3715
|
+
var SUCCESS_KEYS = Object.keys(SUCCESS_RULES);
|
|
3716
|
+
// src/poynt.js
|
|
3717
|
+
var POYNT_PSP = "poynt";
|
|
3718
|
+
var UUID4 = "[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}";
|
|
3719
|
+
var NONCE_URL = new RegExp(`^https://services\\.poynt\\.net/v1/commerce/stores/(${UUID4})/payment-tokens/generate-nonce$`);
|
|
3720
|
+
var STORE_ID = new RegExp(`^${UUID4}$`);
|
|
3721
|
+
var BODY_LIMIT23 = 8192;
|
|
3722
|
+
var ROOT_KEYS8 = /* @__PURE__ */ Object.freeze(["applicationId", "channelId", "card", "verificationData"]);
|
|
3723
|
+
var CARD_KEYS10 = /* @__PURE__ */ Object.freeze(["number", "expirationMonth", "expirationYear", "type", "cardHolderFirstName", "cardHolderLastName", "cardHolderFullName"]);
|
|
3724
|
+
var ADDRESS_KEYS4 = /* @__PURE__ */ Object.freeze(["postalCode", "line1", "line2", "city", "territory", "countryCode", "postalCodeExtension"]);
|
|
3725
|
+
var REQUIRED_ROOT = /* @__PURE__ */ Object.freeze(["applicationId", "card", "verificationData"]);
|
|
3726
|
+
var REQUIRED_CARD = /* @__PURE__ */ Object.freeze(["number", "expirationMonth", "expirationYear", "type", "cardHolderFullName"]);
|
|
3727
|
+
var CARD_ON_FILE_KEYS = /* @__PURE__ */ Object.freeze(["saveFinancialInstrumentOnFile", "financialInstrumentAgreement"]);
|
|
3728
|
+
var CARD_TYPES = /* @__PURE__ */ Object.freeze(["VISA", "MASTERCARD", "AMERICAN_EXPRESS", "DINERS_CLUB", "DISCOVER", "JCB", "UNIONPAY", "MAESTRO", "ELO", "HIPERCARD", "TROY", ""]);
|
|
3729
|
+
var CARD_NUMBER12 = /^[0-9]{12,19}$/;
|
|
3730
|
+
var MONTH12 = /^(?:0[1-9]|1[0-2])$/;
|
|
3731
|
+
var YEAR12 = /^20[0-9]{2}$/;
|
|
3732
|
+
var SECURITY_CODE14 = /^[0-9]{3,4}$/;
|
|
3733
|
+
var IDENTIFIER = /^[A-Za-z0-9:._-]{1,128}$/;
|
|
3734
|
+
var APPLICATION_ID = new RegExp(`^urn:aid:${UUID4}$`);
|
|
3735
|
+
var POSTAL_CODE3 = /^[A-Za-z0-9_]{0,16}$/;
|
|
3736
|
+
var COUNTRY3 = /^[A-Z]{2}$/;
|
|
3737
|
+
var TEXT_LIMIT7 = 256;
|
|
3738
|
+
var CONTROL10 = /[\u0000-\u001f\u007f]/;
|
|
3739
|
+
var cardLike2 = (text7) => (text7.match(/[0-9]/g) ?? []).length >= 12;
|
|
3740
|
+
var text5 = (value) => typeof value === "string" && value.length <= TEXT_LIMIT7 && !CONTROL10.test(value) && !cardLike2(value);
|
|
3741
|
+
var record20 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
3742
|
+
var own5 = (value, key) => Object.prototype.hasOwnProperty.call(value, key);
|
|
3743
|
+
var inOrder4 = (value, order, required) => {
|
|
3744
|
+
const keys = Object.keys(value);
|
|
3745
|
+
let at = -1;
|
|
3746
|
+
for (const key of keys) {
|
|
3747
|
+
const next = order.indexOf(key);
|
|
3748
|
+
if (next <= at)
|
|
3749
|
+
return false;
|
|
3750
|
+
at = next;
|
|
3751
|
+
}
|
|
3752
|
+
return required.every((key) => keys.includes(key));
|
|
3753
|
+
};
|
|
3754
|
+
var refuse25 = (code) => Object.freeze({ verdict: "refuse", code });
|
|
3755
|
+
var CARD24 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
|
|
3756
|
+
function poyntStoreId(url) {
|
|
3757
|
+
const match = typeof url === "string" ? NONCE_URL.exec(url) : null;
|
|
3758
|
+
return match ? match[1] : null;
|
|
3759
|
+
}
|
|
3760
|
+
function isPoyntNonceUrl(url) {
|
|
3761
|
+
return poyntStoreId(url) !== null;
|
|
3762
|
+
}
|
|
3763
|
+
function readBody14(body) {
|
|
3764
|
+
if (typeof body !== "string" || body === "" || body.length > BODY_LIMIT23)
|
|
3765
|
+
return null;
|
|
3766
|
+
let value;
|
|
3767
|
+
try {
|
|
3768
|
+
value = JSON.parse(body);
|
|
3769
|
+
if (!record20(value) || JSON.stringify(value) !== body)
|
|
3770
|
+
return null;
|
|
3771
|
+
}
|
|
3772
|
+
catch {
|
|
3773
|
+
return null;
|
|
3774
|
+
}
|
|
3775
|
+
return value;
|
|
3776
|
+
}
|
|
3777
|
+
function poyntBodyVerdict(body) {
|
|
3778
|
+
const value = readBody14(body);
|
|
3779
|
+
if (value === null)
|
|
3780
|
+
return refuse25("poynt_body_unsupported");
|
|
3781
|
+
if (CARD_ON_FILE_KEYS.some((key) => own5(value, key)))
|
|
3782
|
+
return refuse25("poynt_card_on_file");
|
|
3783
|
+
if (!inOrder4(value, ROOT_KEYS8, REQUIRED_ROOT) || typeof value.applicationId !== "string" || !APPLICATION_ID.test(value.applicationId) || own5(value, "channelId") && (typeof value.channelId !== "string" || !IDENTIFIER.test(value.channelId))) {
|
|
3784
|
+
return refuse25("poynt_body_unsupported");
|
|
3785
|
+
}
|
|
3786
|
+
const { card, verificationData: verification } = value;
|
|
3787
|
+
if (!record20(card) || !inOrder4(card, CARD_KEYS10, REQUIRED_CARD) || typeof card.number !== "string" || !CARD_NUMBER12.test(card.number) || typeof card.expirationMonth !== "string" || !MONTH12.test(card.expirationMonth) || typeof card.expirationYear !== "string" || !YEAR12.test(card.expirationYear) || !CARD_TYPES.includes(card.type) || !["cardHolderFirstName", "cardHolderLastName", "cardHolderFullName"].every((key) => !own5(card, key) || text5(card[key]))) {
|
|
3788
|
+
return refuse25("poynt_body_unsupported");
|
|
3789
|
+
}
|
|
3790
|
+
if (!record20(verification) || Object.keys(verification).join() !== "cardHolderBillingAddress,cvData" || typeof verification.cvData !== "string" || !SECURITY_CODE14.test(verification.cvData))
|
|
3791
|
+
return refuse25("poynt_body_unsupported");
|
|
3792
|
+
const address2 = verification.cardHolderBillingAddress;
|
|
3793
|
+
if (!record20(address2) || !inOrder4(address2, ADDRESS_KEYS4, []) || !Object.values(address2).every(text5) || own5(address2, "postalCode") && !POSTAL_CODE3.test(address2.postalCode) || own5(address2, "postalCodeExtension") && !POSTAL_CODE3.test(address2.postalCodeExtension) || own5(address2, "countryCode") && !COUNTRY3.test(address2.countryCode))
|
|
3794
|
+
return refuse25("poynt_body_unsupported");
|
|
3795
|
+
return CARD24;
|
|
3796
|
+
}
|
|
3797
|
+
var pin7 = (fields) => Object.freeze({ ...fields, origins: Object.freeze([...fields.origins]), storeIds: Object.freeze([...fields.storeIds]) });
|
|
3798
|
+
var POYNT_MERCHANT_PINS = /* @__PURE__ */ Object.freeze([
|
|
3799
|
+
pin7({
|
|
3800
|
+
id: "yearning_for_learning",
|
|
3801
|
+
merchant: "Yearning for Learning Publishing & Coaching",
|
|
3802
|
+
origins: ["https://ff305485-ba6c-423a-87b0-cebe3f83ffe9.mysimplestore.com"],
|
|
3803
|
+
storeIds: ["71ac12ed-e61f-4318-95db-db0e7c649d6f"]
|
|
3804
|
+
}),
|
|
3805
|
+
pin7({
|
|
3806
|
+
id: "timber_ridge_bookkeeping",
|
|
3807
|
+
merchant: "Timber Ridge Bookkeeping",
|
|
3808
|
+
origins: ["https://d7d64ac3-0352-4e53-af9a-f6d8e7b5fb71.mysimplestore.com"],
|
|
3809
|
+
storeIds: ["27be984a-0a03-4a54-8675-e64bbbe1c43e"]
|
|
3810
|
+
})
|
|
3811
|
+
]);
|
|
3812
|
+
var MAX_ANSWER_CHARS = 16 * 1024;
|
|
2909
3813
|
// src/card-fields.js
|
|
2910
3814
|
function processorGate(recognizer, url, body) {
|
|
2911
3815
|
if (recognizer && recognizer.psp === LYRA_PSP)
|
|
@@ -2922,6 +3826,18 @@ function processorGate(recognizer, url, body) {
|
|
|
2922
3826
|
return { verdict: "refuse", code: "hipay_url_refused" };
|
|
2923
3827
|
return hipayBodyVerdict(body);
|
|
2924
3828
|
}
|
|
3829
|
+
if (recognizer && recognizer.psp === PAYPAL_PSP) {
|
|
3830
|
+
if (url !== void 0 && !isPaypalConfirmUrl(url))
|
|
3831
|
+
return { verdict: "refuse", code: "paypal_url_refused" };
|
|
3832
|
+
return paypalBodyVerdict(body);
|
|
3833
|
+
}
|
|
3834
|
+
if (recognizer && recognizer.psp === MAKECOMMERCE_PSP)
|
|
3835
|
+
return makecommerceBodyVerdict(body, url);
|
|
3836
|
+
if (recognizer && recognizer.psp === POYNT_PSP) {
|
|
3837
|
+
if (url !== void 0 && !isPoyntNonceUrl(url))
|
|
3838
|
+
return { verdict: "refuse", code: "poynt_url_refused" };
|
|
3839
|
+
return poyntBodyVerdict(body);
|
|
3840
|
+
}
|
|
2925
3841
|
if (recognizer && recognizer.psp === PADDLE_VGS_PSP) {
|
|
2926
3842
|
if (url !== void 0 && !isPaddleVgsCardsUrl(url))
|
|
2927
3843
|
return { verdict: "refuse", code: "paddle_vgs_url_refused" };
|
|
@@ -2956,6 +3872,8 @@ function processorGate(recognizer, url, body) {
|
|
|
2956
3872
|
}
|
|
2957
3873
|
if (recognizer && recognizer.psp === APS_PSP)
|
|
2958
3874
|
return apsBodyVerdict(body, url);
|
|
3875
|
+
if (recognizer && recognizer.psp === CONEKTA_PSP)
|
|
3876
|
+
return conektaBodyVerdict(body, url);
|
|
2959
3877
|
if (recognizer && recognizer.psp === PADDLE_TOKENEX_PSP) {
|
|
2960
3878
|
const target = url !== void 0 ? paddleTokenexPayTarget(url) : null;
|
|
2961
3879
|
if (url !== void 0 && target === null)
|
|
@@ -2977,6 +3895,15 @@ function processorGate(recognizer, url, body) {
|
|
|
2977
3895
|
}
|
|
2978
3896
|
if (recognizer && recognizer.psp === SUMUP_PSP)
|
|
2979
3897
|
return sumupBodyVerdict(body, url);
|
|
3898
|
+
if (recognizer && recognizer.psp === CLOVER_PSP)
|
|
3899
|
+
return cloverBodyVerdict(body, url);
|
|
3900
|
+
if (recognizer && recognizer.psp === TAP_PAYMENTS_PSP) {
|
|
3901
|
+
if (url !== void 0 && !isTapPaymentsTokenUrl(url))
|
|
3902
|
+
return { verdict: "refuse", code: "tap_payments_url_refused" };
|
|
3903
|
+
return tapPaymentsBodyVerdict(body);
|
|
3904
|
+
}
|
|
3905
|
+
if (recognizer && recognizer.psp === TOKENEX_IFRAME_PSP)
|
|
3906
|
+
return tokenexIframeBodyVerdict(body, url);
|
|
2980
3907
|
if (recognizer && recognizer.psp === GRAVY_PSP)
|
|
2981
3908
|
return gravyBodyVerdict(body);
|
|
2982
3909
|
if (recognizer && recognizer.psp === MONERIS_PSP) {
|
|
@@ -3097,20 +4024,20 @@ var KEEP_ON_FILE_REFUSAL = "Refusing to pay: this Primer payment would keep the
|
|
|
3097
4024
|
var UNSUPPORTED_SDK_REFUSAL = "Refusing to pay: this checkout uses a Primer SDK Agentcard does not support yet. Nothing was sent.";
|
|
3098
4025
|
var NETWORK_MISMATCH_REFUSAL = "Refusing to pay: this Primer payment names a card network that is not your card's. Nothing was sent.";
|
|
3099
4026
|
var FILL_REFUSAL = "Could not fill the card fields for Primer. Nothing was sent.";
|
|
3100
|
-
var
|
|
4027
|
+
var BODY_LIMIT24 = 16384;
|
|
3101
4028
|
var RESPONSE_LIMIT = 32768;
|
|
3102
|
-
var
|
|
4029
|
+
var ROOT_KEYS9 = ["paymentInstrument", "userDescription", "tokenType", "paymentFlow"];
|
|
3103
4030
|
var INSTRUMENT_KEYS = ["number", "cvv", "expirationMonth", "expirationYear", "cardholderName", "preferredNetwork"];
|
|
3104
4031
|
var REQUIRED_INSTRUMENT_KEYS = ["number", "cvv", "expirationMonth", "expirationYear"];
|
|
3105
|
-
var
|
|
3106
|
-
var
|
|
3107
|
-
var
|
|
3108
|
-
var
|
|
3109
|
-
var
|
|
3110
|
-
var
|
|
3111
|
-
var
|
|
3112
|
-
var
|
|
3113
|
-
var
|
|
4032
|
+
var record21 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
4033
|
+
var owns6 = (value, key) => Object.prototype.hasOwnProperty.call(value, key);
|
|
4034
|
+
var exact3 = (pattern, value) => typeof value === "string" && pattern.exec(value)?.[0] === value;
|
|
4035
|
+
var text6 = (value, max) => typeof value === "string" && value.length <= max && !/[\u0000-\u001f\u007f]/.test(value);
|
|
4036
|
+
var digits2 = (value, min, max) => typeof value === "string" && value.length >= min && value.length <= max && !/[^0-9]/.test(value);
|
|
4037
|
+
var panLike2 = (value) => /(?:[0-9][ _.:-]*){12,}/.test(value);
|
|
4038
|
+
var plain2 = (value, max) => text6(value, max) && !panLike2(value);
|
|
4039
|
+
var MONTH13 = /^(?:0[1-9]|1[0-2])$/;
|
|
4040
|
+
var YEAR13 = /^20[0-9]{2}$/;
|
|
3114
4041
|
var NETWORK2 = /^[A-Z][A-Z_]{1,31}$/;
|
|
3115
4042
|
function isPrimerTokenizeUrl(url, method = "POST") {
|
|
3116
4043
|
if (method !== "POST" || typeof url !== "string" || url.length > 256 || url.includes("?") || url.includes("#"))
|
|
@@ -3124,8 +4051,8 @@ function isPrimerTokenizeUrl(url, method = "POST") {
|
|
|
3124
4051
|
}
|
|
3125
4052
|
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;
|
|
3126
4053
|
}
|
|
3127
|
-
function
|
|
3128
|
-
if (typeof body !== "string" || body === "" || body.length >
|
|
4054
|
+
function judgeBody5(body) {
|
|
4055
|
+
if (typeof body !== "string" || body === "" || body.length > BODY_LIMIT24)
|
|
3129
4056
|
return null;
|
|
3130
4057
|
let value;
|
|
3131
4058
|
try {
|
|
@@ -3134,21 +4061,21 @@ function judgeBody4(body) {
|
|
|
3134
4061
|
catch {
|
|
3135
4062
|
return null;
|
|
3136
4063
|
}
|
|
3137
|
-
if (!
|
|
4064
|
+
if (!record21(value) || !roundTrips(value, body))
|
|
3138
4065
|
return null;
|
|
3139
|
-
if (!Object.keys(value).every((key) =>
|
|
4066
|
+
if (!Object.keys(value).every((key) => ROOT_KEYS9.includes(key)) || !owns6(value, "paymentInstrument"))
|
|
3140
4067
|
return null;
|
|
3141
4068
|
const instrument = value.paymentInstrument;
|
|
3142
|
-
if (!
|
|
4069
|
+
if (!record21(instrument) || !Object.keys(instrument).every((key) => INSTRUMENT_KEYS.includes(key)) || !REQUIRED_INSTRUMENT_KEYS.every((key) => owns6(instrument, key)))
|
|
3143
4070
|
return null;
|
|
3144
|
-
if (!
|
|
4071
|
+
if (!digits2(instrument.number, 12, 19) || !digits2(instrument.cvv, 3, 4) || !exact3(MONTH13, instrument.expirationMonth) || !exact3(YEAR13, instrument.expirationYear))
|
|
3145
4072
|
return null;
|
|
3146
|
-
if (
|
|
4073
|
+
if (owns6(instrument, "cardholderName") && instrument.cardholderName !== null && !plain2(instrument.cardholderName, 256) || owns6(instrument, "preferredNetwork") && instrument.preferredNetwork !== null && !exact3(NETWORK2, instrument.preferredNetwork) || owns6(value, "userDescription") && value.userDescription !== null && !plain2(value.userDescription, 256) || owns6(value, "tokenType") && value.tokenType !== "MULTI_USE" || owns6(value, "paymentFlow") && value.paymentFlow !== "VAULT")
|
|
3147
4074
|
return null;
|
|
3148
|
-
return { value, keepOnFile:
|
|
4075
|
+
return { value, keepOnFile: owns6(value, "tokenType") || owns6(value, "paymentFlow") };
|
|
3149
4076
|
}
|
|
3150
4077
|
function primerBodyRefusal(body) {
|
|
3151
|
-
const judged =
|
|
4078
|
+
const judged = judgeBody5(body);
|
|
3152
4079
|
if (!judged)
|
|
3153
4080
|
return "unsupported";
|
|
3154
4081
|
return judged.keepOnFile ? "keep_on_file" : null;
|
|
@@ -3157,7 +4084,7 @@ function isPrimerNewCardBody(body) {
|
|
|
3157
4084
|
return primerBodyRefusal(body) === null;
|
|
3158
4085
|
}
|
|
3159
4086
|
function primerKeepOnFileRequested(body) {
|
|
3160
|
-
const judged =
|
|
4087
|
+
const judged = judgeBody5(body);
|
|
3161
4088
|
return judged ? judged.keepOnFile : null;
|
|
3162
4089
|
}
|
|
3163
4090
|
var CARD_GATE = /* @__PURE__ */ Object.freeze({ psp: "primer", encoding: "json", jsonCardFields: [["paymentInstrument", "number"]] });
|
|
@@ -3167,7 +4094,7 @@ var CLIENT_TOKEN = /^[A-Za-z0-9._~+/=-]{16,4096}$/;
|
|
|
3167
4094
|
var REQUEST_ID = /^[A-Za-z0-9-]{1,64}$/;
|
|
3168
4095
|
var API_VERSION = /^2\.[0-9]{1,2}$/;
|
|
3169
4096
|
function readHeaders(headers) {
|
|
3170
|
-
if (!
|
|
4097
|
+
if (!record21(headers))
|
|
3171
4098
|
return null;
|
|
3172
4099
|
const folded = /* @__PURE__ */ new Map();
|
|
3173
4100
|
for (const [name, value] of Object.entries(headers)) {
|
|
@@ -3185,9 +4112,9 @@ function headersRefusal(headers) {
|
|
|
3185
4112
|
const version = folded.get("primer-sdk-version");
|
|
3186
4113
|
if (typeof version !== "string")
|
|
3187
4114
|
return "unsupported";
|
|
3188
|
-
if (!
|
|
4115
|
+
if (!exact3(LEGACY_SDK_VERSION, version))
|
|
3189
4116
|
return "unsupported_sdk";
|
|
3190
|
-
if (!
|
|
4117
|
+
if (!exact3(CONTENT_TYPE2, folded.get("content-type")) || !exact3(CLIENT_TOKEN, folded.get("primer-client-token")) || folded.has("primer-sdk-client") && folded.get("primer-sdk-client") !== "WEB" || folded.has("x-api-version") && !exact3(API_VERSION, folded.get("x-api-version")) || folded.has("primer-sdk-checkout-session-id") && !exact3(REQUEST_ID, folded.get("primer-sdk-checkout-session-id")) || folded.has("x-request-id") && !exact3(REQUEST_ID, folded.get("x-request-id")))
|
|
3191
4118
|
return "unsupported";
|
|
3192
4119
|
return null;
|
|
3193
4120
|
}
|
|
@@ -3214,7 +4141,7 @@ function onTokenizePath(url) {
|
|
|
3214
4141
|
}
|
|
3215
4142
|
}
|
|
3216
4143
|
function primerTokenizeRefusal(request) {
|
|
3217
|
-
if (!
|
|
4144
|
+
if (!record21(request) || request.method !== "POST" || !isPrimerTokenizeUrl(request.url))
|
|
3218
4145
|
return "unsupported";
|
|
3219
4146
|
return headersRefusal(request.headers) ?? primerBodyRefusal(request.body);
|
|
3220
4147
|
}
|
|
@@ -3229,7 +4156,7 @@ function primerCardOnFileRefusal(url, options, policy = PRIMER_SESSION_CARD_ON_F
|
|
|
3229
4156
|
return "unsupported";
|
|
3230
4157
|
if (new URL(url).hostname !== LIVE_PCI_HOST)
|
|
3231
4158
|
return null;
|
|
3232
|
-
return primerCardOnFileDisclosure(url, policy) &&
|
|
4159
|
+
return primerCardOnFileDisclosure(url, policy) && record21(options) && options.keepOnFile === true ? null : "keep_on_file";
|
|
3233
4160
|
}
|
|
3234
4161
|
function primerRefusalMessage(reason) {
|
|
3235
4162
|
if (reason === "keep_on_file")
|
|
@@ -3241,7 +4168,7 @@ function primerRefusalMessage(reason) {
|
|
|
3241
4168
|
return UNSUPPORTED_REFUSAL;
|
|
3242
4169
|
}
|
|
3243
4170
|
function primerCardNetwork(number) {
|
|
3244
|
-
if (!
|
|
4171
|
+
if (!digits2(number, 12, 19))
|
|
3245
4172
|
return null;
|
|
3246
4173
|
const two = Number(number.slice(0, 2));
|
|
3247
4174
|
const four = Number(number.slice(0, 4));
|
|
@@ -3254,7 +4181,7 @@ function primerCardNetwork(number) {
|
|
|
3254
4181
|
return null;
|
|
3255
4182
|
}
|
|
3256
4183
|
function primerNetworkRefusal(body, card) {
|
|
3257
|
-
const judged =
|
|
4184
|
+
const judged = judgeBody5(body);
|
|
3258
4185
|
if (!judged)
|
|
3259
4186
|
return "unsupported";
|
|
3260
4187
|
const preferred = judged.value.paymentInstrument.preferredNetwork;
|
|
@@ -3264,14 +4191,14 @@ function primerNetworkRefusal(body, card) {
|
|
|
3264
4191
|
return network !== null && network === preferred ? null : "network_mismatch";
|
|
3265
4192
|
}
|
|
3266
4193
|
function injectPrimerCard(body, card) {
|
|
3267
|
-
const judged =
|
|
4194
|
+
const judged = judgeBody5(body);
|
|
3268
4195
|
if (!judged)
|
|
3269
4196
|
throw new Error(UNSUPPORTED_REFUSAL);
|
|
3270
4197
|
if (judged.keepOnFile)
|
|
3271
4198
|
throw new Error(KEEP_ON_FILE_REFUSAL);
|
|
3272
|
-
const month = card && (Number.isInteger(card.month) ||
|
|
3273
|
-
const year = card && (Number.isInteger(card.year) ||
|
|
3274
|
-
if (!card || !
|
|
4199
|
+
const month = card && (Number.isInteger(card.month) || digits2(card.month, 1, 2)) ? Number(card.month) : NaN;
|
|
4200
|
+
const year = card && (Number.isInteger(card.year) || digits2(card.year, 2, 4)) ? Number(card.year) : NaN;
|
|
4201
|
+
if (!card || !digits2(card.number, 12, 19) || !(month >= 1 && month <= 12) || !(year >= 0 && year <= 99 || year >= 2e3 && year <= 2099) || !digits2(card.cvc, 3, 4)) {
|
|
3275
4202
|
throw new Error(FILL_REFUSAL);
|
|
3276
4203
|
}
|
|
3277
4204
|
if (primerNetworkRefusal(body, card) !== null)
|
|
@@ -3282,7 +4209,7 @@ function injectPrimerCard(body, card) {
|
|
|
3282
4209
|
instrument.expirationMonth = String(month).padStart(2, "0");
|
|
3283
4210
|
instrument.expirationYear = String(year < 100 ? 2e3 + year : year);
|
|
3284
4211
|
const where = ["paymentInstrument.number", "paymentInstrument.cvv", "paymentInstrument.expirationMonth", "paymentInstrument.expirationYear"];
|
|
3285
|
-
if (typeof instrument.cardholderName === "string" && typeof card.name === "string" && card.name.trim() !== "" &&
|
|
4212
|
+
if (typeof instrument.cardholderName === "string" && typeof card.name === "string" && card.name.trim() !== "" && plain2(card.name, 256)) {
|
|
3286
4213
|
instrument.cardholderName = card.name;
|
|
3287
4214
|
where.push("paymentInstrument.cardholderName");
|
|
3288
4215
|
}
|
|
@@ -3290,7 +4217,7 @@ function injectPrimerCard(body, card) {
|
|
|
3290
4217
|
}
|
|
3291
4218
|
var TOKEN3 = /^[A-Za-z0-9_-]{8,256}$/;
|
|
3292
4219
|
var ERROR_ID = /^[A-Za-z][A-Za-z0-9_.-]{0,63}$/;
|
|
3293
|
-
var
|
|
4220
|
+
var CODE5 = /^[A-Z][A-Z0-9_]{0,63}$/;
|
|
3294
4221
|
var NETWORK_NAME = /^[A-Za-z][A-Za-z0-9 _-]{0,31}$/;
|
|
3295
4222
|
var RESPONSE_MONTH = /^(?:0?[1-9]|1[0-2])$/;
|
|
3296
4223
|
var RESPONSE_YEAR = /^(?:[0-9]{2}|20[0-9]{2})$/;
|
|
@@ -3313,30 +4240,30 @@ function readAnswer(body) {
|
|
|
3313
4240
|
return null;
|
|
3314
4241
|
try {
|
|
3315
4242
|
const value = JSON.parse(body);
|
|
3316
|
-
return
|
|
4243
|
+
return record21(value) ? value : null;
|
|
3317
4244
|
}
|
|
3318
4245
|
catch {
|
|
3319
4246
|
return null;
|
|
3320
4247
|
}
|
|
3321
4248
|
}
|
|
3322
|
-
var tokenValue = (value) =>
|
|
3323
|
-
var optional = (value, key, check) => !
|
|
4249
|
+
var tokenValue = (value) => exact3(TOKEN3, value) && !panLike2(value);
|
|
4250
|
+
var optional = (value, key, check) => !owns6(value, key) || value[key] === null || check(value[key]);
|
|
3324
4251
|
function cardDetails(data) {
|
|
3325
|
-
if (!
|
|
4252
|
+
if (!record21(data) || !exact3(/^[0-9]{4}$/, data.last4Digits))
|
|
3326
4253
|
return null;
|
|
3327
|
-
if (!optional(data, "first6Digits", (v) =>
|
|
4254
|
+
if (!optional(data, "first6Digits", (v) => exact3(/^[0-9]{6}$/, v)) || !optional(data, "expirationMonth", (v) => exact3(RESPONSE_MONTH, v)) || !optional(data, "expirationYear", (v) => exact3(RESPONSE_YEAR, v)) || !optional(data, "cardholderName", (v) => plain2(v, 256)) || !optional(data, "network", (v) => exact3(NETWORK_NAME, v)) || !optional(data, "isNetworkTokenized", (v) => typeof v === "boolean") || !optional(data, "binData", record21))
|
|
3328
4255
|
return null;
|
|
3329
4256
|
const safe = { last4Digits: data.last4Digits };
|
|
3330
4257
|
for (const key of ["first6Digits", "expirationMonth", "expirationYear", "cardholderName", "network", "isNetworkTokenized"]) {
|
|
3331
|
-
if (
|
|
4258
|
+
if (owns6(data, key) && data[key] !== null)
|
|
3332
4259
|
safe[key] = data[key];
|
|
3333
4260
|
}
|
|
3334
|
-
if (
|
|
4261
|
+
if (record21(data.binData)) {
|
|
3335
4262
|
const bin = {};
|
|
3336
4263
|
for (const key of BIN_KEYS) {
|
|
3337
|
-
if (!
|
|
4264
|
+
if (!owns6(data.binData, key) || data.binData[key] === null)
|
|
3338
4265
|
continue;
|
|
3339
|
-
if (!
|
|
4266
|
+
if (!plain2(data.binData[key], 128))
|
|
3340
4267
|
return null;
|
|
3341
4268
|
bin[key] = data.binData[key];
|
|
3342
4269
|
}
|
|
@@ -3347,11 +4274,11 @@ function cardDetails(data) {
|
|
|
3347
4274
|
function threeDsSummary(value) {
|
|
3348
4275
|
if (value === void 0 || value === null)
|
|
3349
4276
|
return null;
|
|
3350
|
-
if (!
|
|
4277
|
+
if (!record21(value) || !exact3(CODE5, value.responseCode) || !optional(value, "reasonCode", (v) => exact3(CODE5, v)) || !optional(value, "reasonText", (v) => plain2(v, 256)) || !optional(value, "protocolVersion", (v) => v === "" || exact3(PROTOCOL, v)) || !optional(value, "challengeIssued", (v) => typeof v === "boolean"))
|
|
3351
4278
|
return void 0;
|
|
3352
4279
|
const safe = { responseCode: value.responseCode };
|
|
3353
4280
|
for (const key of ["reasonCode", "reasonText", "protocolVersion", "challengeIssued"]) {
|
|
3354
|
-
if (
|
|
4281
|
+
if (owns6(value, key) && value[key] !== null)
|
|
3355
4282
|
safe[key] = value[key];
|
|
3356
4283
|
}
|
|
3357
4284
|
return safe;
|
|
@@ -3364,7 +4291,7 @@ function rebuildToken(value) {
|
|
|
3364
4291
|
if (!details || threeDs === void 0)
|
|
3365
4292
|
return null;
|
|
3366
4293
|
const safe = { token: value.token };
|
|
3367
|
-
if (
|
|
4294
|
+
if (owns6(value, "analyticsId") && value.analyticsId !== null)
|
|
3368
4295
|
safe.analyticsId = value.analyticsId;
|
|
3369
4296
|
safe.tokenType = "SINGLE_USE";
|
|
3370
4297
|
safe.paymentInstrumentType = "PAYMENT_CARD";
|
|
@@ -3375,8 +4302,8 @@ function rebuildToken(value) {
|
|
|
3375
4302
|
}
|
|
3376
4303
|
function primerErrorId(body) {
|
|
3377
4304
|
const value = readAnswer(body);
|
|
3378
|
-
const id = value &&
|
|
3379
|
-
return
|
|
4305
|
+
const id = value && record21(value.error) ? value.error.errorId : null;
|
|
4306
|
+
return exact3(ERROR_ID, id) && !panLike2(id) ? id : null;
|
|
3380
4307
|
}
|
|
3381
4308
|
function matchesCard(details, card) {
|
|
3382
4309
|
const number = card && typeof card.number === "string" ? card.number : "";
|