@agent-cards/sdk 0.24.0 → 0.24.1
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 +26 -0
- package/README.md +61 -4
- package/dist/adyen-merchant-hosted.generated.d.ts +1 -1
- package/dist/adyen-merchant-hosted.generated.js +128 -35
- package/dist/agent-amount.generated.js +1 -1
- package/dist/aurus.d.ts +33 -0
- package/dist/aurus.js +75 -0
- package/dist/builtin-registry.generated.js +1 -1
- package/dist/capabilities.generated.js +1 -1
- package/dist/card-fields.generated.js +1756 -433
- package/dist/cardlink-vpos.d.ts +43 -0
- package/dist/cardlink-vpos.js +90 -0
- package/dist/cdp.js +13 -0
- package/dist/checkout-com.generated.js +5 -1
- package/dist/client.d.ts +66 -0
- package/dist/client.js +66 -0
- package/dist/cybersource-flex.generated.d.ts +39 -1
- package/dist/cybersource-flex.generated.js +100 -11
- package/dist/eghl.d.ts +40 -0
- package/dist/eghl.js +72 -0
- package/dist/gmo.generated.js +7 -2
- package/dist/hosted-entry.js +2 -0
- package/dist/paddle-tokenex.generated.js +7 -2
- package/dist/payrails.generated.js +7 -2
- package/dist/pre-claim.d.ts +2 -0
- package/dist/pre-claim.js +46 -2
- package/dist/preflight-catalog.json +154 -1
- package/dist/preflight-schemas.json +14 -0
- package/dist/preflight.generated.d.ts +5 -0
- package/dist/preflight.generated.js +40 -3
- package/dist/preparation.d.ts +7 -0
- package/dist/preparation.js +21 -0
- package/dist/primer.generated.js +1778 -455
- package/dist/shiji-sts.generated.js +7 -2
- package/dist/stripe-checkout.generated.js +1741 -470
- package/dist/substitutions.generated.js +94 -1
- package/dist/tap-payments.generated.js +7 -2
- package/dist/twoc2p.generated.js +7 -2
- package/examples/preflight/kernel-native/inventory.json +1 -1
- package/package.json +2 -2
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: 6c0e945e1d49960ab9a1af9cdcfc73ca013e927dda8e75bed8f1a19d39e81d3f
|
|
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 text11 = typeof value === "number" && Number.isFinite(value) ? String(value) : value;
|
|
113
|
+
const m = typeof text11 === "string" ? AMOUNT.exec(text11) : null;
|
|
114
114
|
if (!m)
|
|
115
115
|
return null;
|
|
116
116
|
const cents2 = 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 own23 = Object.keys(value);
|
|
369
|
+
return own23.length === keys.length && own23.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(text11) {
|
|
594
594
|
const out = [];
|
|
595
|
-
for (const char of
|
|
595
|
+
for (const char of text11) {
|
|
596
596
|
let cp = char.codePointAt(0);
|
|
597
597
|
if (cp >= 55296 && cp <= 57343)
|
|
598
598
|
cp = 65533;
|
|
@@ -667,6 +667,7 @@ var BASE64 = /^[A-Za-z0-9+/]+={0,2}$/;
|
|
|
667
667
|
var SHA256_HEX = /^[0-9a-f]{64}$/;
|
|
668
668
|
var RSA_ALGORITHM = [48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 1, 5, 0];
|
|
669
669
|
var MODULUS_BYTES = [128, 256, 384, 512];
|
|
670
|
+
var SMALL_MODULUS_BYTES = 64;
|
|
670
671
|
var TYPED_ARRAY = Object.getPrototypeOf(Uint8Array.prototype);
|
|
671
672
|
var typedArrayName = Object.getOwnPropertyDescriptor(TYPED_ARRAY, Symbol.toStringTag).get;
|
|
672
673
|
function parseRsaPublicKey(key) {
|
|
@@ -675,6 +676,9 @@ function parseRsaPublicKey(key) {
|
|
|
675
676
|
const named = key && typeof key === "object" && Object.prototype.hasOwnProperty.call(key, "exponent") ? key.exponent : void 0;
|
|
676
677
|
if (named !== void 0 && named !== 17)
|
|
677
678
|
throw refuse6("key");
|
|
679
|
+
const sized = key && typeof key === "object" && Object.prototype.hasOwnProperty.call(key, "bits") ? key.bits : void 0;
|
|
680
|
+
if (sized !== void 0 && sized !== 512)
|
|
681
|
+
throw refuse6("key");
|
|
678
682
|
if (typeof spki !== "string" || spki.length > 1024 || spki.length % 4 !== 0 || !BASE64.test(spki))
|
|
679
683
|
throw refuse6("key");
|
|
680
684
|
if (typeof pin10 !== "string" || !SHA256_HEX.test(pin10))
|
|
@@ -707,7 +711,8 @@ function parseRsaPublicKey(key) {
|
|
|
707
711
|
if (exponent.end !== rsa.end)
|
|
708
712
|
throw refuse6("key");
|
|
709
713
|
const n = modulus.bytes;
|
|
710
|
-
|
|
714
|
+
const sizes = sized === 512 ? [SMALL_MODULUS_BYTES] : MODULUS_BYTES;
|
|
715
|
+
if (!sizes.includes(n.length) || !(n[0] & 128) || !(n[n.length - 1] & 1))
|
|
711
716
|
throw refuse6("key");
|
|
712
717
|
const e = exponent.bytes;
|
|
713
718
|
const expected = named === 17 ? [17] : [1, 0, 1];
|
|
@@ -779,8 +784,8 @@ var PADDLE_TOKENEX_PSP = "paddle_tokenex";
|
|
|
779
784
|
var PADDLE_TOKENEX_FACT_KEYS = /* @__PURE__ */ Object.freeze(["card_first_six", "card_last_four", "expiry_month", "expiry_year", "card_brand"]);
|
|
780
785
|
var record4 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
781
786
|
var sameKeys2 = (value, keys) => {
|
|
782
|
-
const
|
|
783
|
-
return
|
|
787
|
+
const own23 = Object.keys(value);
|
|
788
|
+
return own23.length === keys.length && own23.every((key, at) => key === keys[at]);
|
|
784
789
|
};
|
|
785
790
|
var refuse7 = (code) => Object.freeze({ verdict: "refuse", code });
|
|
786
791
|
var CARD6 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
|
|
@@ -1269,8 +1274,8 @@ var TEXT_LIMIT = 256;
|
|
|
1269
1274
|
var CONTROL4 = /[\u0000-\u001f\u007f]/;
|
|
1270
1275
|
var record6 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
1271
1276
|
var sameKeys3 = (value, keys) => {
|
|
1272
|
-
const
|
|
1273
|
-
return
|
|
1277
|
+
const own23 = Object.keys(value);
|
|
1278
|
+
return own23.length === keys.length && own23.every((key, at) => key === keys[at]);
|
|
1274
1279
|
};
|
|
1275
1280
|
var plainText = (value) => typeof value === "string" && value.length <= TEXT_LIMIT && !CONTROL4.test(value) && (value.match(/[0-9]/g) ?? []).length < 12;
|
|
1276
1281
|
var refuse9 = (code) => Object.freeze({ verdict: "refuse", code });
|
|
@@ -1300,13 +1305,13 @@ function billingFields(value) {
|
|
|
1300
1305
|
if (names.length > MAX_FIELDS)
|
|
1301
1306
|
return false;
|
|
1302
1307
|
return names.every((name) => {
|
|
1303
|
-
const
|
|
1308
|
+
const field5 = value[name];
|
|
1304
1309
|
if (!FIELD_NAME.test(name))
|
|
1305
1310
|
return false;
|
|
1306
|
-
if (!record6(
|
|
1307
|
-
return billingText(
|
|
1308
|
-
const nested = Object.keys(
|
|
1309
|
-
return nested.length <= MAX_NESTED_FIELDS && nested.every((key) => FIELD_NAME.test(key) && billingText(
|
|
1311
|
+
if (!record6(field5))
|
|
1312
|
+
return billingText(field5);
|
|
1313
|
+
const nested = Object.keys(field5);
|
|
1314
|
+
return nested.length <= MAX_NESTED_FIELDS && nested.every((key) => FIELD_NAME.test(key) && billingText(field5[key]));
|
|
1310
1315
|
});
|
|
1311
1316
|
}
|
|
1312
1317
|
function wixPaymentsBodyVerdict(body) {
|
|
@@ -1472,8 +1477,8 @@ var EXPIRATION = /^[0-9]{2}(?:0[1-9]|1[0-2])$/;
|
|
|
1472
1477
|
var CARD_PAYMENT = "PAYMENT_CARD";
|
|
1473
1478
|
var record8 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
1474
1479
|
var sameKeys4 = (value, keys) => {
|
|
1475
|
-
const
|
|
1476
|
-
return
|
|
1480
|
+
const own23 = Object.keys(value);
|
|
1481
|
+
return own23.length === keys.length && own23.every((key, at) => key === keys[at]);
|
|
1477
1482
|
};
|
|
1478
1483
|
var refuse11 = (code) => Object.freeze({ verdict: "refuse", code });
|
|
1479
1484
|
var CARD10 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
|
|
@@ -1703,8 +1708,8 @@ var LOCALE = /^[a-z]{2}(?:-[A-Za-z]{2,4})?$/;
|
|
|
1703
1708
|
var PAN_LIKE3 = /(?:[0-9][ _.:-]*){12,}/;
|
|
1704
1709
|
var record9 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
1705
1710
|
var sameKeys5 = (value, keys) => {
|
|
1706
|
-
const
|
|
1707
|
-
return
|
|
1711
|
+
const own23 = Object.keys(value);
|
|
1712
|
+
return own23.length === keys.length && own23.every((key, at) => key === keys[at]);
|
|
1708
1713
|
};
|
|
1709
1714
|
var refuse13 = (code) => Object.freeze({ verdict: "refuse", code });
|
|
1710
1715
|
var CARD12 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
|
|
@@ -1984,8 +1989,8 @@ function enclosedValue(char) {
|
|
|
1984
1989
|
const [first, , start] = ENCLOSED.find(([from, size]) => point >= from && point < from + size);
|
|
1985
1990
|
return String(first === 127243 ? 0 : first === 10102 ? (point - first) % 10 + 1 : start + point - first);
|
|
1986
1991
|
}
|
|
1987
|
-
var asciiDigits = (
|
|
1988
|
-
var digitCount = (
|
|
1992
|
+
var asciiDigits = (text11) => (typeof text11.normalize === "function" ? text11.normalize("NFKC") : text11).replace(ENCLOSED_CHAR, enclosedValue).replace(/\p{Nd}/gu, (char) => char >= "0" && char <= "9" ? char : digitValue(char));
|
|
1993
|
+
var digitCount = (text11) => (asciiDigits(String(text11)).match(/\p{N}/gu) ?? []).length;
|
|
1989
1994
|
var NAME_DIGITS = 3;
|
|
1990
1995
|
// src/pay-nl.js
|
|
1991
1996
|
var PAY_NL_PSP = "pay_nl";
|
|
@@ -2139,7 +2144,7 @@ var luhn2 = (digits4) => {
|
|
|
2139
2144
|
return sum % 10 === 0;
|
|
2140
2145
|
};
|
|
2141
2146
|
var ANY_NETWORK = /^[2-6][0-9]{12,18}$/;
|
|
2142
|
-
var holdsCardShape = (
|
|
2147
|
+
var holdsCardShape = (text11, shape = NETWORK) => (text11.match(/[0-9]{13,}/g) ?? []).some((run) => run.length > 19 || shape.test(run) && luhn2(run));
|
|
2143
2148
|
var phone = (value) => typeof value === "string" && PHONE.test(value) && (value.match(/[0-9]/g) ?? []).length >= 6 && (value.match(/[0-9]/g) ?? []).length <= 15;
|
|
2144
2149
|
var refuse16 = (code) => Object.freeze({ verdict: "refuse", code });
|
|
2145
2150
|
var CARD15 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
|
|
@@ -2367,13 +2372,13 @@ var printable = (value) => [...value].every((ch) => ch.charCodeAt(0) >= 32 && ch
|
|
|
2367
2372
|
function typed(value, limit = 256) {
|
|
2368
2373
|
return typeof value === "string" && value.length >= 1 && value.length <= limit && !PAN_LIKE4.test(value) && printable(value);
|
|
2369
2374
|
}
|
|
2370
|
-
function decodeBase64(
|
|
2371
|
-
if (typeof
|
|
2375
|
+
function decodeBase64(text11) {
|
|
2376
|
+
if (typeof text11 !== "string" || !BASE643.test(text11) || text11.length % 4 !== 0)
|
|
2372
2377
|
return null;
|
|
2373
2378
|
let bits = 0;
|
|
2374
2379
|
let value = 0;
|
|
2375
2380
|
let out = "";
|
|
2376
|
-
for (const ch of
|
|
2381
|
+
for (const ch of text11.replace(/=+$/, "")) {
|
|
2377
2382
|
value = (value << 6 | BASE64_ALPHABET.indexOf(ch)) & 16777215;
|
|
2378
2383
|
bits += 6;
|
|
2379
2384
|
if (bits >= 8) {
|
|
@@ -2383,8 +2388,8 @@ function decodeBase64(text10) {
|
|
|
2383
2388
|
}
|
|
2384
2389
|
return out;
|
|
2385
2390
|
}
|
|
2386
|
-
function soundDevice(
|
|
2387
|
-
const json = decodeBase64(
|
|
2391
|
+
function soundDevice(text11) {
|
|
2392
|
+
const json = decodeBase64(text11);
|
|
2388
2393
|
if (json === null)
|
|
2389
2394
|
return false;
|
|
2390
2395
|
let value;
|
|
@@ -2502,17 +2507,17 @@ function sumupBodyVerdict(body, url) {
|
|
|
2502
2507
|
var SALTED = /* @__PURE__ */ Object.freeze([83, 97, 108, 116, 101, 100, 95, 95]);
|
|
2503
2508
|
var B64 = /^[A-Za-z0-9+/]+={0,2}$/;
|
|
2504
2509
|
var FIELD_LIMIT = 1024;
|
|
2505
|
-
function decodeCanonical(
|
|
2506
|
-
if (typeof
|
|
2510
|
+
function decodeCanonical(text11) {
|
|
2511
|
+
if (typeof text11 !== "string" || text11.length === 0 || text11.length % 4 !== 0 || !B64.test(text11))
|
|
2507
2512
|
return null;
|
|
2508
2513
|
let binary;
|
|
2509
2514
|
try {
|
|
2510
|
-
binary = atob(
|
|
2515
|
+
binary = atob(text11);
|
|
2511
2516
|
}
|
|
2512
2517
|
catch {
|
|
2513
2518
|
return null;
|
|
2514
2519
|
}
|
|
2515
|
-
if (btoa(binary) !==
|
|
2520
|
+
if (btoa(binary) !== text11)
|
|
2516
2521
|
return null;
|
|
2517
2522
|
return Uint8Array.from(binary, (char) => char.charCodeAt(0));
|
|
2518
2523
|
}
|
|
@@ -2754,8 +2759,8 @@ var TEXT_LIMIT3 = 256;
|
|
|
2754
2759
|
var CONTROL7 = /[\u0000-\u001f\u007f]/;
|
|
2755
2760
|
var record13 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
2756
2761
|
var sameKeys7 = (value, keys) => {
|
|
2757
|
-
const
|
|
2758
|
-
return
|
|
2762
|
+
const own23 = Object.keys(value);
|
|
2763
|
+
return own23.length === keys.length && own23.every((key, at) => key === keys[at]);
|
|
2759
2764
|
};
|
|
2760
2765
|
var plainText3 = (value) => typeof value === "string" && value.length <= TEXT_LIMIT3 && !CONTROL7.test(value) && (value.match(/[0-9]/g) ?? []).length < 12;
|
|
2761
2766
|
var refuse19 = (code) => Object.freeze({ verdict: "refuse", code });
|
|
@@ -3451,7 +3456,7 @@ var YEAR11 = /^[0-9]{2}$/;
|
|
|
3451
3456
|
var CODE4 = /^[0-9]{3}$/;
|
|
3452
3457
|
var NAME_LIMIT3 = 100;
|
|
3453
3458
|
var NAME_WORD = /[a-z]+/gi;
|
|
3454
|
-
var printable2 = (
|
|
3459
|
+
var printable2 = (text11) => [...text11].every((character) => {
|
|
3455
3460
|
const point = character.codePointAt(0);
|
|
3456
3461
|
return point >= 32 && !(point >= 127 && point <= 159) && point !== 8232 && point !== 8233;
|
|
3457
3462
|
});
|
|
@@ -3460,8 +3465,8 @@ var HOSTNAME = /^(?=.{1,253}$)[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?(?:\.[a-z0-9](
|
|
|
3460
3465
|
var PUBLISHABLE_KEY = /^[A-Za-z0-9]{16,64}$/;
|
|
3461
3466
|
var record18 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
3462
3467
|
var sameKeys8 = (value, keys) => {
|
|
3463
|
-
const
|
|
3464
|
-
return
|
|
3468
|
+
const own23 = Object.keys(value);
|
|
3469
|
+
return own23.length === keys.length && own23.every((key, at) => key === keys[at]);
|
|
3465
3470
|
};
|
|
3466
3471
|
var refuse24 = (code) => Object.freeze({ verdict: "refuse", code });
|
|
3467
3472
|
var CARD23 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
|
|
@@ -3831,7 +3836,7 @@ var POSTAL_CODE3 = /^[A-Za-z0-9_]{0,16}$/;
|
|
|
3831
3836
|
var COUNTRY4 = /^[A-Z]{2}$/;
|
|
3832
3837
|
var TEXT_LIMIT7 = 256;
|
|
3833
3838
|
var CONTROL10 = /[\u0000-\u001f\u007f]/;
|
|
3834
|
-
var cardLike2 = (
|
|
3839
|
+
var cardLike2 = (text11) => (text11.match(/[0-9]/g) ?? []).length >= 12;
|
|
3835
3840
|
var text5 = (value) => typeof value === "string" && value.length <= TEXT_LIMIT7 && !CONTROL10.test(value) && !cardLike2(value);
|
|
3836
3841
|
var record21 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
3837
3842
|
var own5 = (value, key) => Object.prototype.hasOwnProperty.call(value, key);
|
|
@@ -4152,11 +4157,11 @@ var LONG_TEXT_LIMIT = BODY_LIMIT25;
|
|
|
4152
4157
|
var record22 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
4153
4158
|
var owns6 = (value, key) => Object.prototype.hasOwnProperty.call(value, key);
|
|
4154
4159
|
var sameKeys9 = (value, keys) => {
|
|
4155
|
-
const
|
|
4156
|
-
return
|
|
4160
|
+
const own23 = Object.keys(value);
|
|
4161
|
+
return own23.length === keys.length && own23.every((key, at) => key === keys[at]);
|
|
4157
4162
|
};
|
|
4158
4163
|
var exact3 = (pattern, value) => typeof value === "string" && pattern.test(value);
|
|
4159
|
-
var printable3 = (
|
|
4164
|
+
var printable3 = (text11) => [...text11].every((character) => {
|
|
4160
4165
|
const point = character.codePointAt(0);
|
|
4161
4166
|
return point >= 32 && !(point >= 127 && point <= 159) && point !== 8232 && point !== 8233;
|
|
4162
4167
|
});
|
|
@@ -4229,7 +4234,7 @@ function companyStore(value) {
|
|
|
4229
4234
|
return record22(value) && sameKeys9(value, COMPANY_KEYS) && whole(value.CompanyNumber, 1) && COMPANY_KEYS.slice(1).every((key) => key.startsWith("Show") ? flag(value[key]) : pageText(value[key]));
|
|
4230
4235
|
}
|
|
4231
4236
|
var SUM_TEXT = /^(?:0*[1-9][0-9]*(?:\.[0-9]+)?|0+\.[0-9]*[1-9][0-9]*)$/;
|
|
4232
|
-
var sumText = (
|
|
4237
|
+
var sumText = (text11, sum) => text11 === null || typeof text11 === "string" && SUM_TEXT.test(text11) && Number.parseFloat(text11) === sum;
|
|
4233
4238
|
function chosenProduct(value) {
|
|
4234
4239
|
return record22(value) && sameKeys9(value, PRODUCT_KEYS) && whole(value.MinQuantity) && whole(value.MaxQuantity) && whole(value.JumpsInQuantity) && value.SelectedBuyQuantity === 1 && Array.isArray(value.QuantityOptions) && value.QuantityOptions.length === 0 && pageText(value.Comments) && flag(value.IsManualSum) && Array.isArray(value.PaymentsOptions) && flag(value.IsCouponActive) && typeof value.ManualPrice === "number" && sumText(value.ManualPriceTxt, value.ManualPrice) && flag(value.IsVatFree) && Array.isArray(value.SpecialPrices) && (value.PreConfiguredPrice === null || typeof value.PreConfiguredPrice === "number") && flag(value.IsPreSelected) && typeof value.CurrentInventory === "number" && flag(value.CheckInventory) && exact3(PRODUCT_ID, value.uid) && pageText(value.imageUrl) && typeof value.name === "string" && pageText(value.name) && pageText(value.description) && typeof value.BasePrice === "number" && typeof value.PriceBeforeDiscount === "number" && whole(value.BaseISOCurrency) && typeof value.PriceToShow === "number" && typeof value.PriceBeforeDiscountToShow === "number" && flag(value.IsCurrent);
|
|
4235
4240
|
}
|
|
@@ -4460,7 +4465,7 @@ var sameKeys10 = (value, keys) => {
|
|
|
4460
4465
|
};
|
|
4461
4466
|
var refuse28 = (code) => Object.freeze({ verdict: "refuse", code });
|
|
4462
4467
|
var CARD27 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
|
|
4463
|
-
var printable4 = (
|
|
4468
|
+
var printable4 = (text11) => [...text11].every((character) => {
|
|
4464
4469
|
const point = character.codePointAt(0);
|
|
4465
4470
|
return point >= 32 && !(point >= 127 && point <= 159) && point !== 8232 && point !== 8233;
|
|
4466
4471
|
});
|
|
@@ -4552,8 +4557,8 @@ var POSTAL_CODE4 = /^[A-Za-z0-9 -]{0,16}$/;
|
|
|
4552
4557
|
var CIPHERTEXT_B64 = /^[A-Za-z0-9+/]{341}[AQgw]==$/;
|
|
4553
4558
|
var record24 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
4554
4559
|
var sameKeys11 = (value, keys) => {
|
|
4555
|
-
const
|
|
4556
|
-
return
|
|
4560
|
+
const own23 = Object.keys(value);
|
|
4561
|
+
return own23.length === keys.length && own23.every((key, at) => key === keys[at]);
|
|
4557
4562
|
};
|
|
4558
4563
|
var refuse29 = (code) => Object.freeze({ verdict: "refuse", code });
|
|
4559
4564
|
var failed = (code) => (
|
|
@@ -5022,20 +5027,20 @@ function readBody18(body) {
|
|
|
5022
5027
|
function amountValue(value) {
|
|
5023
5028
|
if (typeof value === "number" && !Number.isFinite(value))
|
|
5024
5029
|
return false;
|
|
5025
|
-
const
|
|
5026
|
-
if (typeof
|
|
5030
|
+
const text11 = typeof value === "number" ? String(value) : value;
|
|
5031
|
+
if (typeof text11 !== "string" || !AMOUNT_TEXT.test(text11))
|
|
5027
5032
|
return false;
|
|
5028
|
-
const amount2 = Number(
|
|
5033
|
+
const amount2 = Number(text11);
|
|
5029
5034
|
return amount2 > 0 && amount2 <= AMOUNT_LIMIT3;
|
|
5030
5035
|
}
|
|
5031
5036
|
function billingDetails(value) {
|
|
5032
5037
|
if (!record27(value) || !inOrder5(value, BILLING_KEYS))
|
|
5033
5038
|
return false;
|
|
5034
5039
|
return Object.keys(value).every((key) => {
|
|
5035
|
-
const
|
|
5040
|
+
const field5 = value[key];
|
|
5036
5041
|
if (key !== "address")
|
|
5037
|
-
return key === "mobile_number" || key === "phone_number" ? typeof
|
|
5038
|
-
return record27(
|
|
5042
|
+
return key === "mobile_number" || key === "phone_number" ? typeof field5 === "string" && PHONE4.test(field5) : plainText6(field5);
|
|
5043
|
+
return record27(field5) && inOrder5(field5, ADDRESS_KEYS5) && Object.keys(field5).every((name) => plainText6(field5[name]));
|
|
5039
5044
|
});
|
|
5040
5045
|
}
|
|
5041
5046
|
function cardData(value) {
|
|
@@ -5223,10 +5228,10 @@ function isPaymobPayUrl(url) {
|
|
|
5223
5228
|
var BASE645 = /^[A-Za-z0-9+/]+={0,2}$/;
|
|
5224
5229
|
var BASE64URL = /^[A-Za-z0-9_-]+$/;
|
|
5225
5230
|
var ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
|
5226
|
-
function decodeBase642(
|
|
5227
|
-
if (typeof
|
|
5231
|
+
function decodeBase642(text11, url) {
|
|
5232
|
+
if (typeof text11 !== "string" || text11 === "")
|
|
5228
5233
|
return null;
|
|
5229
|
-
let body =
|
|
5234
|
+
let body = text11;
|
|
5230
5235
|
if (url) {
|
|
5231
5236
|
if (!BASE64URL.test(body) || body.length % 4 === 1)
|
|
5232
5237
|
return null;
|
|
@@ -5259,15 +5264,15 @@ function decodeBase642(text10, url) {
|
|
|
5259
5264
|
function jsonOf(bytes) {
|
|
5260
5265
|
if (!bytes)
|
|
5261
5266
|
return null;
|
|
5262
|
-
let
|
|
5267
|
+
let text11;
|
|
5263
5268
|
try {
|
|
5264
|
-
|
|
5269
|
+
text11 = new TextDecoder("utf-8", { fatal: true }).decode(bytes);
|
|
5265
5270
|
}
|
|
5266
5271
|
catch {
|
|
5267
5272
|
return null;
|
|
5268
5273
|
}
|
|
5269
5274
|
try {
|
|
5270
|
-
const value = JSON.parse(
|
|
5275
|
+
const value = JSON.parse(text11);
|
|
5271
5276
|
return record29(value) ? value : null;
|
|
5272
5277
|
}
|
|
5273
5278
|
catch {
|
|
@@ -5368,7 +5373,7 @@ function namesCardValue3(parsed) {
|
|
|
5368
5373
|
return false;
|
|
5369
5374
|
}
|
|
5370
5375
|
function addressBlock(value) {
|
|
5371
|
-
return record29(value) && Object.keys(value).length <= 32 && Object.entries(value).every(([key,
|
|
5376
|
+
return record29(value) && Object.keys(value).length <= 32 && Object.entries(value).every(([key, text11]) => FIELD.test(key) && !CARD_MEMBER4.test(key) && (text11 === null || typeof text11 === "string" && TEXT3.test(text11)));
|
|
5372
5377
|
}
|
|
5373
5378
|
function judgeCardPayment(parsed) {
|
|
5374
5379
|
const source = parsed.source;
|
|
@@ -5866,8 +5871,8 @@ function cardNamed2(key) {
|
|
|
5866
5871
|
const phrase = words.join(" ");
|
|
5867
5872
|
return words.some((word) => CARD_WORDS.includes(word)) || ["security code", "codigo seguridad", "codigo verificacion"].some((said) => phrase.includes(said));
|
|
5868
5873
|
}
|
|
5869
|
-
function carriesCardNumber(
|
|
5870
|
-
for (const [run] of
|
|
5874
|
+
function carriesCardNumber(text11) {
|
|
5875
|
+
for (const [run] of text11.matchAll(/[0-9]+(?:[ ._/,-][0-9]+)*/g)) {
|
|
5871
5876
|
const groups = run.split(/[ ._/,-]/);
|
|
5872
5877
|
for (let first = 0; first < groups.length; first += 1) {
|
|
5873
5878
|
let digits4 = "";
|
|
@@ -5880,17 +5885,17 @@ function carriesCardNumber(text10) {
|
|
|
5880
5885
|
}
|
|
5881
5886
|
return false;
|
|
5882
5887
|
}
|
|
5883
|
-
var wholeCardNumber = (
|
|
5888
|
+
var wholeCardNumber = (text11) => /^[2-6][0-9]{12,18}$/.test(text11) && luhn7(text11);
|
|
5884
5889
|
function membersRefusal(root) {
|
|
5885
5890
|
const pending = [[root, ""]];
|
|
5886
5891
|
while (pending.length > 0) {
|
|
5887
5892
|
const [node, path] = pending.pop();
|
|
5888
|
-
const
|
|
5893
|
+
const own23 = path === "" ? TRANSACTION_MEMBERS : owns7(RECORD_MEMBERS, path) ? RECORD_MEMBERS[path] : null;
|
|
5889
5894
|
for (const [key, child] of Object.entries(node)) {
|
|
5890
5895
|
const at = Array.isArray(node) ? path : path === "" ? key : `${path}.${key}`;
|
|
5891
5896
|
if (at === "checkoutCreditCard")
|
|
5892
5897
|
continue;
|
|
5893
|
-
if (
|
|
5898
|
+
if (own23 !== null && !own23.includes(key))
|
|
5894
5899
|
return true;
|
|
5895
5900
|
if (TEXT_RECORDS.includes(path) && child !== null && typeof child !== "string")
|
|
5896
5901
|
return true;
|
|
@@ -6171,6 +6176,92 @@ function registered(spec, parts) {
|
|
|
6171
6176
|
function registerProcessor(spec) {
|
|
6172
6177
|
return registered(spec, PARTS);
|
|
6173
6178
|
}
|
|
6179
|
+
// src/processors/aurus.js
|
|
6180
|
+
var AURUS_PSP = "aurus";
|
|
6181
|
+
var AURUS_OPERATION = "aurus.card_request";
|
|
6182
|
+
var AURUS_FRAME_HOST = /^pecst[0-9]{2}\.aurusepay\.com$/;
|
|
6183
|
+
var AURUS_TOKEN_PATH = "/storeservices/ecom/oneTimeToken";
|
|
6184
|
+
var AURUS_PARTS = /* @__PURE__ */ Object.freeze(["Param", "formFactorId", "txnDateTime", "encryptionFlag", "sha256Flag", "hmacAuthData", "payload"]);
|
|
6185
|
+
var URL_LIMIT14 = 256;
|
|
6186
|
+
var BODY_LIMIT35 = 32768;
|
|
6187
|
+
var SERVER = /^es[0-9]{2}\.auruspay\.com$/;
|
|
6188
|
+
var HEX = /^[0-9A-Fa-f]{2,8192}$/;
|
|
6189
|
+
var FORM_FACTOR = /^[0-9]{1,16}$/;
|
|
6190
|
+
var DATE_TIME = /^[0-9]{14}$/;
|
|
6191
|
+
var FRAMED = /^STX[0-9]{1,6}\[FS\][0-9A-Fa-f]{2,16384}\[FS\]7[Bb][0-9A-Fa-f]{0,24576}7[Dd]ETX$/;
|
|
6192
|
+
var refuse37 = (code) => Object.freeze({ verdict: "refuse", code });
|
|
6193
|
+
var CARD36 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
|
|
6194
|
+
function aurusTokenUrl(url) {
|
|
6195
|
+
if (typeof url !== "string" || url.length > URL_LIMIT14 || url.includes("#"))
|
|
6196
|
+
return null;
|
|
6197
|
+
let parsed;
|
|
6198
|
+
try {
|
|
6199
|
+
parsed = new URL(url);
|
|
6200
|
+
}
|
|
6201
|
+
catch {
|
|
6202
|
+
return null;
|
|
6203
|
+
}
|
|
6204
|
+
if (parsed.href !== url || parsed.protocol !== "https:" || parsed.port || parsed.username || parsed.password || !AURUS_FRAME_HOST.test(parsed.hostname) || parsed.pathname !== AURUS_TOKEN_PATH)
|
|
6205
|
+
return null;
|
|
6206
|
+
const query = parsed.search.startsWith("?") ? parsed.search.slice(1).split("&") : [];
|
|
6207
|
+
if (query.length !== 2)
|
|
6208
|
+
return null;
|
|
6209
|
+
const [d1, d2] = query.map((pair) => pair.split("="));
|
|
6210
|
+
if (d1.length !== 2 || d2.length !== 2 || d1[0] !== "d1" || d2[0] !== "d2" || !SERVER.test(d1[1]) || !SERVER.test(d2[1]))
|
|
6211
|
+
return null;
|
|
6212
|
+
return Object.freeze({ host: parsed.hostname });
|
|
6213
|
+
}
|
|
6214
|
+
var isAurusTokenUrl = (url) => aurusTokenUrl(url) !== null;
|
|
6215
|
+
function readBody21(body) {
|
|
6216
|
+
if (typeof body !== "string" || body === "" || body.length > BODY_LIMIT35)
|
|
6217
|
+
return null;
|
|
6218
|
+
const pairs = body.split("&");
|
|
6219
|
+
if (pairs.length !== AURUS_PARTS.length)
|
|
6220
|
+
return null;
|
|
6221
|
+
const value = {};
|
|
6222
|
+
for (const [at, pair] of pairs.entries()) {
|
|
6223
|
+
const cut = pair.indexOf("=");
|
|
6224
|
+
if (cut < 0 || pair.slice(0, cut) !== AURUS_PARTS[at])
|
|
6225
|
+
return null;
|
|
6226
|
+
value[AURUS_PARTS[at]] = pair.slice(cut + 1);
|
|
6227
|
+
}
|
|
6228
|
+
if (!HEX.test(value.Param) || !FORM_FACTOR.test(value.formFactorId) || !DATE_TIME.test(value.txnDateTime) || value.encryptionFlag !== "00" || value.sha256Flag !== "1" || !FRAMED.test(value.hmacAuthData) || !FRAMED.test(value.payload))
|
|
6229
|
+
return null;
|
|
6230
|
+
return value;
|
|
6231
|
+
}
|
|
6232
|
+
function aurusBodyVerdict(body) {
|
|
6233
|
+
return readBody21(body) === null ? refuse37("aurus_body_unsupported") : CARD36;
|
|
6234
|
+
}
|
|
6235
|
+
var aurus_default = /* @__PURE__ */ registerProcessor({
|
|
6236
|
+
psp: AURUS_PSP,
|
|
6237
|
+
definitions: [
|
|
6238
|
+
{
|
|
6239
|
+
psp: "aurus",
|
|
6240
|
+
// The frame's card request, as the header above reads it. No sandbox host is known: Aurus's test instances were
|
|
6241
|
+
// not read, so none is listed and no environment is pinned.
|
|
6242
|
+
// Ships dark: served only to a client that declares `aurus_one_time_token`, and only for a company the backend's
|
|
6243
|
+
// processor gate turns Aurus on for. `(?![\w/.%-])` ends the path for a consumer that tests `match` unanchored.
|
|
6244
|
+
capability: "aurus_one_time_token",
|
|
6245
|
+
match: "pecst[0-9]{2}\\.aurusepay\\.com/storeservices/ecom/oneTimeToken(?![\\w/.%-])",
|
|
6246
|
+
hosts: ["^pecst[0-9]{2}\\.aurusepay\\.com$"],
|
|
6247
|
+
encoding: "form",
|
|
6248
|
+
// The frame's XHR marker. Origin, Referer and cookies never ride.
|
|
6249
|
+
passthroughHeaders: ["^x-requested-with$"]
|
|
6250
|
+
}
|
|
6251
|
+
],
|
|
6252
|
+
// Only the cardholder's device would send this card, after a person approves; no reviewed list names aurus.
|
|
6253
|
+
refusedOperations: [AURUS_OPERATION],
|
|
6254
|
+
// The frame mints a one-time token and reads nothing: the store's server charges it with its own credentials.
|
|
6255
|
+
settlementReadback: {
|
|
6256
|
+
answer: "none",
|
|
6257
|
+
reason: "tokenization_credential_cannot_read_charges",
|
|
6258
|
+
note: "The tokenization credential cannot read a charge; the shop charges the token later with its own credentials.",
|
|
6259
|
+
source: "https://www.oreillyauto.com/checkout (Aurus's ecom iframe, read 2026-10-31)"
|
|
6260
|
+
},
|
|
6261
|
+
exactUrl: isAurusTokenUrl,
|
|
6262
|
+
bodyGate: (url, body) => url !== void 0 && !isAurusTokenUrl(url) ? refuse37("aurus_url_refused") : aurusBodyVerdict(body),
|
|
6263
|
+
limitations: ["The card frame seals the card in the page under a public key its own script carries; the cardholder's device does not seal for Aurus yet, so a held request opens no approval that pays."]
|
|
6264
|
+
});
|
|
6174
6265
|
// src/processors/bluesnap.js
|
|
6175
6266
|
var BLUESNAP_PSP = "bluesnap";
|
|
6176
6267
|
var BLUESNAP_OPERATION = "bluesnap.card_request";
|
|
@@ -6178,7 +6269,7 @@ var BLUESNAP_HOSTS = /* @__PURE__ */ Object.freeze({ 1: "ws1.bluesnap.com", 2: "
|
|
|
6178
6269
|
var BLUESNAP_SANDBOX_HOST = "sandpay.bluesnap.com";
|
|
6179
6270
|
var BLUESNAP_CARD_KEYS = /* @__PURE__ */ Object.freeze(["cvv", "ccNumber", "expDate"]);
|
|
6180
6271
|
var BLUESNAP_LEG_KEYS = /* @__PURE__ */ Object.freeze(["cvv", "expDate"]);
|
|
6181
|
-
var
|
|
6272
|
+
var BODY_LIMIT36 = 1024;
|
|
6182
6273
|
var TOKEN_URL2 = /^https:\/\/(ws1|ws2|sandpay)\.bluesnap\.com\/services\/2\/payment-fields-tokens\/([0-9a-f]{64}_[12]?)$/;
|
|
6183
6274
|
var CARD_NUMBER18 = /^[0-9]{12,19}$/;
|
|
6184
6275
|
var SECURITY_CODE22 = /^[0-9]{3,4}$/;
|
|
@@ -6186,8 +6277,8 @@ var EXPIRY3 = /^(?:0[1-9]|1[0-2])\/20[0-9]{2}$/;
|
|
|
6186
6277
|
var SAVED_CARD_KEYS2 = ["last4Digits", "lastFourDigits", "ccType"];
|
|
6187
6278
|
var record32 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
6188
6279
|
var own12 = (value, key) => Object.prototype.hasOwnProperty.call(value, key);
|
|
6189
|
-
var
|
|
6190
|
-
var
|
|
6280
|
+
var refuse38 = (code) => Object.freeze({ verdict: "refuse", code });
|
|
6281
|
+
var CARD37 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
|
|
6191
6282
|
var LEG = /* @__PURE__ */ Object.freeze({ verdict: "continue" });
|
|
6192
6283
|
function bluesnapTokenUrl(url) {
|
|
6193
6284
|
const match = typeof url === "string" ? TOKEN_URL2.exec(url) : null;
|
|
@@ -6199,8 +6290,8 @@ function bluesnapTokenUrl(url) {
|
|
|
6199
6290
|
function isBluesnapTokenUrl(url) {
|
|
6200
6291
|
return bluesnapTokenUrl(url) !== null;
|
|
6201
6292
|
}
|
|
6202
|
-
function
|
|
6203
|
-
if (typeof body !== "string" || body === "" || body.length >
|
|
6293
|
+
function readBody22(body) {
|
|
6294
|
+
if (typeof body !== "string" || body === "" || body.length > BODY_LIMIT36)
|
|
6204
6295
|
return null;
|
|
6205
6296
|
try {
|
|
6206
6297
|
const value = JSON.parse(body);
|
|
@@ -6211,18 +6302,18 @@ function readBody21(body) {
|
|
|
6211
6302
|
}
|
|
6212
6303
|
}
|
|
6213
6304
|
function bluesnapBodyVerdict(body) {
|
|
6214
|
-
const value =
|
|
6305
|
+
const value = readBody22(body);
|
|
6215
6306
|
if (value === null)
|
|
6216
|
-
return
|
|
6307
|
+
return refuse38("bluesnap_body_unsupported");
|
|
6217
6308
|
const keys = Object.keys(value);
|
|
6218
6309
|
if (keys.some((key) => SAVED_CARD_KEYS2.includes(key)))
|
|
6219
|
-
return
|
|
6310
|
+
return refuse38(own12(value, "ccNumber") ? "bluesnap_body_unsupported" : "bluesnap_saved_card");
|
|
6220
6311
|
if (keys.length === 0 || keys.some((key, i) => !BLUESNAP_CARD_KEYS.includes(key) || i > 0 && BLUESNAP_CARD_KEYS.indexOf(keys[i - 1]) >= BLUESNAP_CARD_KEYS.indexOf(key))) {
|
|
6221
|
-
return
|
|
6312
|
+
return refuse38("bluesnap_body_unsupported");
|
|
6222
6313
|
}
|
|
6223
6314
|
if (own12(value, "ccNumber") && !(typeof value.ccNumber === "string" && CARD_NUMBER18.test(value.ccNumber)) || own12(value, "cvv") && !(typeof value.cvv === "string" && SECURITY_CODE22.test(value.cvv)) || own12(value, "expDate") && !(typeof value.expDate === "string" && EXPIRY3.test(value.expDate)))
|
|
6224
|
-
return
|
|
6225
|
-
return own12(value, "ccNumber") ?
|
|
6315
|
+
return refuse38("bluesnap_body_unsupported");
|
|
6316
|
+
return own12(value, "ccNumber") ? CARD37 : LEG;
|
|
6226
6317
|
}
|
|
6227
6318
|
var bluesnap_default = /* @__PURE__ */ registerProcessor({
|
|
6228
6319
|
psp: BLUESNAP_PSP,
|
|
@@ -6256,104 +6347,1020 @@ var bluesnap_default = /* @__PURE__ */ registerProcessor({
|
|
|
6256
6347
|
exactUrl: isBluesnapTokenUrl,
|
|
6257
6348
|
bodyGate: (url, body) => url !== void 0 && !isBluesnapTokenUrl(url) ? { verdict: "refuse", code: "bluesnap_url_refused" } : bluesnapBodyVerdict(body)
|
|
6258
6349
|
});
|
|
6259
|
-
// src/processors/
|
|
6260
|
-
var
|
|
6261
|
-
var
|
|
6262
|
-
var
|
|
6263
|
-
|
|
6264
|
-
|
|
6265
|
-
"
|
|
6266
|
-
"
|
|
6267
|
-
"
|
|
6268
|
-
"
|
|
6269
|
-
"
|
|
6270
|
-
"
|
|
6271
|
-
"
|
|
6272
|
-
"
|
|
6273
|
-
"
|
|
6350
|
+
// src/processors/ekashu.js
|
|
6351
|
+
var EKASHU_HOSTS = Object.freeze(["live.ekashu.com", "test.ekashu.com"]);
|
|
6352
|
+
var EKASHU_TEST_PANS = Object.freeze(["4100000000000100", "5100000000000107"]);
|
|
6353
|
+
var EKASHU_SIGNED_FIELDS = Object.freeze([
|
|
6354
|
+
"ekashu_3d_secure_verify",
|
|
6355
|
+
"ekashu_amount",
|
|
6356
|
+
"ekashu_amount_format",
|
|
6357
|
+
"ekashu_auto_confirm",
|
|
6358
|
+
"ekashu_callback_failure_url",
|
|
6359
|
+
"ekashu_callback_include_post",
|
|
6360
|
+
"ekashu_callback_success_url",
|
|
6361
|
+
"ekashu_card_address_editable",
|
|
6362
|
+
"ekashu_card_address_required",
|
|
6363
|
+
"ekashu_card_address_verify",
|
|
6364
|
+
"ekashu_card_email_address_mandatory",
|
|
6365
|
+
"ekashu_card_phone_number_mandatory",
|
|
6366
|
+
"ekashu_card_title_mandatory",
|
|
6367
|
+
"ekashu_card_zip_code_verify",
|
|
6368
|
+
"ekashu_currency",
|
|
6369
|
+
"ekashu_delivery_address_editable",
|
|
6370
|
+
"ekashu_delivery_address_required",
|
|
6371
|
+
"ekashu_delivery_email_address_mandatory",
|
|
6372
|
+
"ekashu_delivery_phone_number_mandatory",
|
|
6373
|
+
"ekashu_delivery_title_mandatory",
|
|
6374
|
+
"ekashu_description",
|
|
6375
|
+
"ekashu_device",
|
|
6376
|
+
"ekashu_duplicate_check",
|
|
6377
|
+
"ekashu_duplicate_minutes",
|
|
6378
|
+
"ekashu_failure_return_text",
|
|
6379
|
+
"ekashu_failure_url",
|
|
6380
|
+
"ekashu_hash_code_format",
|
|
6381
|
+
"ekashu_hash_code_type",
|
|
6382
|
+
"ekashu_hash_code_version",
|
|
6383
|
+
"ekashu_include_post",
|
|
6384
|
+
"ekashu_invoice_address_editable",
|
|
6385
|
+
"ekashu_invoice_address_required",
|
|
6386
|
+
"ekashu_invoice_email_address_mandatory",
|
|
6387
|
+
"ekashu_invoice_phone_number_mandatory",
|
|
6388
|
+
"ekashu_invoice_title_mandatory",
|
|
6389
|
+
"ekashu_locale",
|
|
6390
|
+
"ekashu_payment_methods",
|
|
6391
|
+
"ekashu_reference",
|
|
6392
|
+
"ekashu_request_type",
|
|
6393
|
+
"ekashu_return_text",
|
|
6394
|
+
"ekashu_seller_address",
|
|
6395
|
+
"ekashu_seller_email_address",
|
|
6396
|
+
"ekashu_seller_id",
|
|
6397
|
+
"ekashu_seller_key",
|
|
6398
|
+
"ekashu_seller_name",
|
|
6399
|
+
"ekashu_shortcut_icon",
|
|
6400
|
+
"ekashu_style_sheet",
|
|
6401
|
+
"ekashu_success_url",
|
|
6402
|
+
"ekashu_title",
|
|
6403
|
+
"ekashu_verification_value_mask",
|
|
6404
|
+
"ekashu_verification_value_verify",
|
|
6405
|
+
"ekashu_viewport"
|
|
6274
6406
|
]);
|
|
6275
|
-
var
|
|
6276
|
-
"
|
|
6277
|
-
"
|
|
6278
|
-
"
|
|
6279
|
-
"
|
|
6280
|
-
"
|
|
6281
|
-
"
|
|
6282
|
-
"
|
|
6407
|
+
var REQUIRED = Object.freeze([
|
|
6408
|
+
"ekashu_seller_id",
|
|
6409
|
+
"ekashu_seller_key",
|
|
6410
|
+
"ekashu_amount",
|
|
6411
|
+
"ekashu_currency",
|
|
6412
|
+
"ekashu_reference",
|
|
6413
|
+
"ekashu_hash_code",
|
|
6414
|
+
"ekashu_hash_code_type",
|
|
6415
|
+
"ekashu_hash_code_version",
|
|
6416
|
+
"ekashu_success_url",
|
|
6417
|
+
"ekashu_failure_url",
|
|
6418
|
+
"ekashu_callback_success_url"
|
|
6283
6419
|
]);
|
|
6284
|
-
var
|
|
6285
|
-
|
|
6286
|
-
|
|
6287
|
-
|
|
6288
|
-
|
|
6289
|
-
|
|
6290
|
-
|
|
6291
|
-
|
|
6292
|
-
|
|
6293
|
-
var
|
|
6294
|
-
var
|
|
6295
|
-
var
|
|
6296
|
-
var
|
|
6297
|
-
|
|
6298
|
-
|
|
6299
|
-
|
|
6300
|
-
|
|
6301
|
-
|
|
6302
|
-
|
|
6303
|
-
|
|
6420
|
+
var CARD_KEYS16 = Object.freeze([
|
|
6421
|
+
"ekashu_card_number",
|
|
6422
|
+
"ekashu_expires_end_month",
|
|
6423
|
+
"ekashu_expires_end_year",
|
|
6424
|
+
"ekashu_verification_value",
|
|
6425
|
+
"ekashu_valid_from_month",
|
|
6426
|
+
"ekashu_valid_from_year",
|
|
6427
|
+
"ekashu_issue_number"
|
|
6428
|
+
]);
|
|
6429
|
+
var PAGE_KEYS = Object.freeze(["ekashu_stage", "ekashu_context", "ekashu_submission_id"]);
|
|
6430
|
+
var STORED_KEYS = Object.freeze(["ekashu_card_hash", "ekashu_card_reference", "ekashu_cof_initiated_by", "ekashu_cof_reason", "ekashu_cof_id"]);
|
|
6431
|
+
var REDIRECT_KEYS = Object.freeze(["ekashu_success_url", "ekashu_failure_url", "ekashu_return_url"]);
|
|
6432
|
+
var CALLBACK_KEYS = Object.freeze(["ekashu_callback_success_url", "ekashu_callback_failure_url"]);
|
|
6433
|
+
var MAX_ENTRY = 16 * 1024;
|
|
6434
|
+
var MAX_PAGE = 256 * 1024;
|
|
6435
|
+
var EKASHU_SELLERS = Object.freeze([
|
|
6436
|
+
Object.freeze({ sellerId: "25060100", merchant: "Heathrow Drop-off", entryHost: "heathrowdropoff.apcoa.com", callbackHost: "incomingapi.apcoa.co.uk" })
|
|
6437
|
+
]);
|
|
6438
|
+
var CARD_FIELDS = Object.freeze({
|
|
6439
|
+
number: "ekashu_card_number",
|
|
6440
|
+
month: "ekashu_expires_end_month",
|
|
6441
|
+
year: "ekashu_expires_end_year",
|
|
6442
|
+
cvc: "ekashu_verification_value"
|
|
6443
|
+
});
|
|
6444
|
+
var NAME_FIELDS = Object.freeze({ first: "ekashu_card_first_name", last: "ekashu_card_last_name" });
|
|
6445
|
+
var LEFT_EMPTY = Object.freeze(["ekashu_card_title", "ekashu_valid_from_month", "ekashu_valid_from_year", "ekashu_issue_number"]);
|
|
6446
|
+
var VISIBLE = /* @__PURE__ */ new Set([...Object.values(CARD_FIELDS), ...Object.values(NAME_FIELDS), ...LEFT_EMPTY]);
|
|
6447
|
+
// src/processors/redsys.js
|
|
6448
|
+
var REDSYS_HOSTS = Object.freeze(["sis.redsys.es"]);
|
|
6449
|
+
var REDSYS_ENTRY_PATHS = Object.freeze(["/sis/realizarPago", "/sis/realizarPago/utf-8"]);
|
|
6450
|
+
var REDSYS_MERCHANTS = Object.freeze([]);
|
|
6451
|
+
var MAX_ENTRY2 = 16 * 1024;
|
|
6452
|
+
var MAX_PARAMETERS = 8 * 1024;
|
|
6453
|
+
var FORM_KEY = /^[A-Za-z][A-Za-z0-9_-]{0,63}$/;
|
|
6454
|
+
var ENTRY_KEYS = Object.freeze(["Ds_SignatureVersion", "Ds_MerchantParameters", "Ds_Signature"]);
|
|
6455
|
+
var REQUIRED2 = Object.freeze([
|
|
6456
|
+
"DS_MERCHANT_AMOUNT",
|
|
6457
|
+
"DS_MERCHANT_CURRENCY",
|
|
6458
|
+
"DS_MERCHANT_MERCHANTCODE",
|
|
6459
|
+
"DS_MERCHANT_ORDER",
|
|
6460
|
+
"DS_MERCHANT_TERMINAL",
|
|
6461
|
+
"DS_MERCHANT_TRANSACTIONTYPE",
|
|
6462
|
+
"DS_MERCHANT_MERCHANTURL",
|
|
6463
|
+
"DS_MERCHANT_URLOK",
|
|
6464
|
+
"DS_MERCHANT_URLKO"
|
|
6465
|
+
]);
|
|
6466
|
+
var STORED = Object.freeze([
|
|
6467
|
+
"DS_MERCHANT_IDENTIFIER",
|
|
6468
|
+
"DS_MERCHANT_GROUP",
|
|
6469
|
+
"DS_MERCHANT_COF_INI",
|
|
6470
|
+
"DS_MERCHANT_COF_TYPE",
|
|
6471
|
+
"DS_MERCHANT_COF_TXNID"
|
|
6472
|
+
]);
|
|
6473
|
+
var SPECIAL = Object.freeze([
|
|
6474
|
+
"DS_MERCHANT_DIRECTPAYMENT",
|
|
6475
|
+
"DS_MERCHANT_SUMTOTAL",
|
|
6476
|
+
"DS_MERCHANT_DATEFRECUENCY",
|
|
6477
|
+
"DS_MERCHANT_CHARGEEXPIRYDATE",
|
|
6478
|
+
"DS_MERCHANT_IDOPER"
|
|
6479
|
+
]);
|
|
6480
|
+
var CARD_PARAMETERS = Object.freeze(["DS_MERCHANT_PAN", "DS_MERCHANT_EXPIRYDATE", "DS_MERCHANT_CVV2"]);
|
|
6481
|
+
var CURRENCIES = Object.freeze({ 978: "eur", 840: "usd", 826: "gbp", 756: "chf" });
|
|
6482
|
+
function decode(text11) {
|
|
6483
|
+
return decodeURIComponent(text11.replace(/\+/g, " "));
|
|
6484
|
+
}
|
|
6485
|
+
function parseRedsysForm(body) {
|
|
6486
|
+
if (typeof body !== "string" || body.length === 0 || body.length > MAX_ENTRY2 || /[^\x21-\x7e]/.test(body))
|
|
6487
|
+
return null;
|
|
6488
|
+
const pairs = [];
|
|
6489
|
+
const seen = /* @__PURE__ */ new Set();
|
|
6490
|
+
for (const chunk of body.split("&")) {
|
|
6491
|
+
const eq = chunk.indexOf("=");
|
|
6492
|
+
if (eq < 1)
|
|
6493
|
+
return null;
|
|
6494
|
+
let key;
|
|
6495
|
+
let value;
|
|
6496
|
+
try {
|
|
6497
|
+
key = decode(chunk.slice(0, eq));
|
|
6498
|
+
value = decode(chunk.slice(eq + 1));
|
|
6499
|
+
}
|
|
6500
|
+
catch {
|
|
6501
|
+
return null;
|
|
6502
|
+
}
|
|
6503
|
+
if (!FORM_KEY.test(key) || value.length > MAX_PARAMETERS || /[\u0000-\u001f\u007f]/.test(value))
|
|
6504
|
+
return null;
|
|
6505
|
+
const folded = key.toLowerCase();
|
|
6506
|
+
if (seen.has(folded))
|
|
6507
|
+
return null;
|
|
6508
|
+
seen.add(folded);
|
|
6509
|
+
pairs.push({ key, value });
|
|
6304
6510
|
}
|
|
6305
|
-
return
|
|
6306
|
-
};
|
|
6307
|
-
var refuse38 = (code) => Object.freeze({ verdict: "refuse", code });
|
|
6308
|
-
var CARD37 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
|
|
6309
|
-
function isIyzicoCardUrl(url) {
|
|
6310
|
-
return typeof url === "string" && IYZICO_CARD_URLS.includes(url);
|
|
6511
|
+
return pairs;
|
|
6311
6512
|
}
|
|
6312
|
-
|
|
6313
|
-
|
|
6513
|
+
var MAX_PAGE2 = 256 * 1024;
|
|
6514
|
+
var CARD_FIELDS2 = Object.freeze({
|
|
6515
|
+
shown: "Sis_card-number",
|
|
6516
|
+
expiry: "SIS_card-expiration",
|
|
6517
|
+
cvc: "Sis_Tarjeta_CVV2",
|
|
6518
|
+
holder: "cardholderName",
|
|
6519
|
+
number: "Sis_Numero_Tarjeta",
|
|
6520
|
+
month: "Sis_Caducidad_Tarjeta_Mes",
|
|
6521
|
+
year: "Sis_Caducidad_Tarjeta_Anno"
|
|
6522
|
+
});
|
|
6523
|
+
var BROWSER_FIELDS = Object.freeze([
|
|
6524
|
+
"browserJavaEnabled",
|
|
6525
|
+
"browserJavascriptEnabled",
|
|
6526
|
+
"browserLanguage",
|
|
6527
|
+
"browserColorDepth",
|
|
6528
|
+
"browserScreenHeight",
|
|
6529
|
+
"browserScreenWidth",
|
|
6530
|
+
"browserTZ",
|
|
6531
|
+
"browserUserAgent"
|
|
6532
|
+
]);
|
|
6533
|
+
var AS_SERVED = Object.freeze(["cvvObligatorio", "threeDSCompInd", "fuc", "terminal", "merchantOrder", "bcancel"]);
|
|
6534
|
+
var CARD_PAGE = /* @__PURE__ */ new Set([...Object.values(CARD_FIELDS2), ...BROWSER_FIELDS, ...AS_SERVED]);
|
|
6535
|
+
var VISIBLE2 = /* @__PURE__ */ new Set([CARD_FIELDS2.shown, CARD_FIELDS2.expiry, CARD_FIELDS2.cvc, CARD_FIELDS2.holder]);
|
|
6536
|
+
var METHOD_PAGE = /* @__PURE__ */ new Set(["resultadoMethod", ...BROWSER_FIELDS, "threeDSCompInd"]);
|
|
6537
|
+
var REDSYS_REFUSALS = Object.freeze(["redsys_card_page", "redsys_3ds_challenge", "redsys_declined"]);
|
|
6538
|
+
// src/processors/cardlink_vpos.js
|
|
6539
|
+
var CARDLINK_VPOS_PSP = "cardlink_vpos";
|
|
6540
|
+
var CARDLINK_VPOS_HOSTS = Object.freeze({
|
|
6541
|
+
"vpos.eurocommerce.gr": "worldline",
|
|
6542
|
+
"ecommerce.cardlink.gr": "cardlink",
|
|
6543
|
+
"www.alphaecommerce.gr": "nexi"
|
|
6544
|
+
});
|
|
6545
|
+
var CARDLINK_VPOS_TEST_HOSTS = Object.freeze([
|
|
6546
|
+
"eurocommerce-test.cardlink.gr",
|
|
6547
|
+
"ecommerce-test.cardlink.gr",
|
|
6548
|
+
"alphaecommerce-test.cardlink.gr"
|
|
6549
|
+
]);
|
|
6550
|
+
var CARDLINK_VPOS_ENTRY_PATH = "/vpos/shophandlermpi";
|
|
6551
|
+
var CARDLINK_VPOS_MERCHANTS = Object.freeze([
|
|
6552
|
+
Object.freeze({ merchant: "Holy Great Monastery of Vatopedi", mid: "0021713862", vposHost: "vpos.eurocommerce.gr", host: "www.vatopedi.gr" })
|
|
6553
|
+
]);
|
|
6554
|
+
var CARDLINK_VPOS_ENTRY_FIELDS = Object.freeze([
|
|
6555
|
+
"version",
|
|
6556
|
+
"mid",
|
|
6557
|
+
"lang",
|
|
6558
|
+
"deviceCategory",
|
|
6559
|
+
"orderid",
|
|
6560
|
+
"orderDesc",
|
|
6561
|
+
"orderAmount",
|
|
6562
|
+
"currency",
|
|
6563
|
+
"payerEmail",
|
|
6564
|
+
"payerPhone",
|
|
6565
|
+
"billCountry",
|
|
6566
|
+
"billState",
|
|
6567
|
+
"billZip",
|
|
6568
|
+
"billCity",
|
|
6569
|
+
"billAddress",
|
|
6570
|
+
"weight",
|
|
6571
|
+
"dimensions",
|
|
6572
|
+
"shipCountry",
|
|
6573
|
+
"shipState",
|
|
6574
|
+
"shipZip",
|
|
6575
|
+
"shipCity",
|
|
6576
|
+
"shipAddress",
|
|
6577
|
+
"addFraudScore",
|
|
6578
|
+
"maxPayRetries",
|
|
6579
|
+
"reject3dsU",
|
|
6580
|
+
"payMethod",
|
|
6581
|
+
"trType",
|
|
6582
|
+
"extInstallmentoffset",
|
|
6583
|
+
"extInstallmentperiod",
|
|
6584
|
+
"extRecurringfrequency",
|
|
6585
|
+
"extRecurringenddate",
|
|
6586
|
+
"blockScore",
|
|
6587
|
+
"cssUrl",
|
|
6588
|
+
"confirmUrl",
|
|
6589
|
+
"cancelUrl",
|
|
6590
|
+
"extTokenOptions",
|
|
6591
|
+
"extToken",
|
|
6592
|
+
"var1",
|
|
6593
|
+
"var2",
|
|
6594
|
+
"var3",
|
|
6595
|
+
"var4",
|
|
6596
|
+
"var5",
|
|
6597
|
+
"var6",
|
|
6598
|
+
"var7",
|
|
6599
|
+
"var8",
|
|
6600
|
+
"var9",
|
|
6601
|
+
"digest"
|
|
6602
|
+
]);
|
|
6603
|
+
var KNOWN = new Set(CARDLINK_VPOS_ENTRY_FIELDS);
|
|
6604
|
+
var REQUIRED3 = Object.freeze([
|
|
6605
|
+
"version",
|
|
6606
|
+
"mid",
|
|
6607
|
+
"orderid",
|
|
6608
|
+
"orderDesc",
|
|
6609
|
+
"orderAmount",
|
|
6610
|
+
"currency",
|
|
6611
|
+
"payerEmail",
|
|
6612
|
+
"confirmUrl",
|
|
6613
|
+
"cancelUrl",
|
|
6614
|
+
"digest"
|
|
6615
|
+
]);
|
|
6616
|
+
var STORED2 = Object.freeze(["extTokenOptions", "extToken"]);
|
|
6617
|
+
var SPECIAL2 = Object.freeze(["extInstallmentoffset", "extInstallmentperiod", "extRecurringfrequency", "extRecurringenddate"]);
|
|
6618
|
+
var CURRENCIES2 = Object.freeze({ EUR: "eur" });
|
|
6619
|
+
var MAX_URL = 512;
|
|
6620
|
+
var MAX_ENTRY3 = 8 * 1024;
|
|
6621
|
+
var MAX_VALUE = 256;
|
|
6622
|
+
var own13 = (value, key) => Object.prototype.hasOwnProperty.call(value, key);
|
|
6623
|
+
var field2 = (name, reason) => ({ ok: false, code: "hosted_form_field_refused", field: name, reason });
|
|
6624
|
+
function cardlinkVposEntryHost(raw) {
|
|
6625
|
+
if (typeof raw !== "string" || raw.length > MAX_URL || raw.includes("?") || raw.includes("#"))
|
|
6314
6626
|
return null;
|
|
6627
|
+
let url;
|
|
6315
6628
|
try {
|
|
6316
|
-
|
|
6317
|
-
return record33(value) && JSON.stringify(value) === body ? value : null;
|
|
6629
|
+
url = new URL(raw);
|
|
6318
6630
|
}
|
|
6319
6631
|
catch {
|
|
6320
6632
|
return null;
|
|
6321
6633
|
}
|
|
6634
|
+
if (url.href !== raw || url.protocol !== "https:" || url.port || url.username || url.password || !own13(CARDLINK_VPOS_HOSTS, url.hostname) || url.pathname !== CARDLINK_VPOS_ENTRY_PATH)
|
|
6635
|
+
return null;
|
|
6636
|
+
return url.hostname;
|
|
6322
6637
|
}
|
|
6323
|
-
function
|
|
6324
|
-
|
|
6325
|
-
const value = match ? Number(match[1]) * 100 + Number((match[2] ?? "").padEnd(2, "0")) : 0;
|
|
6326
|
-
return value > 0 ? value : null;
|
|
6638
|
+
function isCardlinkVposEntryUrl(raw) {
|
|
6639
|
+
return cardlinkVposEntryHost(raw) !== null;
|
|
6327
6640
|
}
|
|
6328
|
-
|
|
6329
|
-
|
|
6330
|
-
|
|
6331
|
-
const
|
|
6332
|
-
|
|
6333
|
-
|
|
6334
|
-
|
|
6335
|
-
|
|
6336
|
-
|
|
6337
|
-
|
|
6338
|
-
|
|
6339
|
-
|
|
6340
|
-
|
|
6641
|
+
function parseCardlinkVposForm(body) {
|
|
6642
|
+
if (typeof body !== "string" || body.length === 0 || body.length > MAX_ENTRY3 || /[^\x21-\x7e]/.test(body))
|
|
6643
|
+
return null;
|
|
6644
|
+
const pairs = [];
|
|
6645
|
+
const seen = /* @__PURE__ */ new Set();
|
|
6646
|
+
for (const chunk of body.split("&")) {
|
|
6647
|
+
const eq = chunk.indexOf("=");
|
|
6648
|
+
if (eq < 1)
|
|
6649
|
+
return null;
|
|
6650
|
+
let key;
|
|
6651
|
+
let value;
|
|
6652
|
+
try {
|
|
6653
|
+
key = decodeURIComponent(chunk.slice(0, eq).replace(/\+/g, " "));
|
|
6654
|
+
value = decodeURIComponent(chunk.slice(eq + 1).replace(/\+/g, " "));
|
|
6655
|
+
}
|
|
6656
|
+
catch {
|
|
6657
|
+
return null;
|
|
6658
|
+
}
|
|
6659
|
+
if (!/^[A-Za-z_.][A-Za-z0-9_.-]{0,63}$/.test(key) || value.length > MAX_VALUE || /[\u0000-\u001f\u007f]/.test(value))
|
|
6660
|
+
return null;
|
|
6661
|
+
if (seen.has(key))
|
|
6662
|
+
return null;
|
|
6663
|
+
seen.add(key);
|
|
6664
|
+
pairs.push({ key, value });
|
|
6341
6665
|
}
|
|
6342
|
-
|
|
6343
|
-
return refuse38("iyzico_installments_refused");
|
|
6344
|
-
if (!inOrder6(value, IYZICO_BODY_KEYS) || !["installment", "paidPrice", "paymentChannel", "paymentCard"].every((key) => own13(value, key)) || value.installment !== 1 || hundredths(value.paidPrice) === null || !CHANNELS.includes(value.paymentChannel) || own13(value, "pwiMetadata") && !metadata(value.pwiMetadata))
|
|
6345
|
-
return refuse38("iyzico_body_unsupported");
|
|
6346
|
-
if (!record33(card) || Object.keys(card).join() !== IYZICO_CARD_KEYS.join() || typeof card.cardNumber !== "string" || !CARD_NUMBER19.test(card.cardNumber) || !holderName2(card.cardHolderName) || typeof card.expireYear !== "string" || !YEAR20.test(card.expireYear) || typeof card.expireMonth !== "string" || !MONTH19.test(card.expireMonth) || typeof card.cvc !== "string" || !SECURITY_CODE23.test(card.cvc))
|
|
6347
|
-
return refuse38("iyzico_body_unsupported");
|
|
6348
|
-
return CARD37;
|
|
6666
|
+
return pairs;
|
|
6349
6667
|
}
|
|
6350
|
-
|
|
6351
|
-
|
|
6352
|
-
|
|
6353
|
-
|
|
6354
|
-
|
|
6355
|
-
|
|
6356
|
-
|
|
6668
|
+
function cardlinkVposMerchant(mid, vposHost, merchants = CARDLINK_VPOS_MERCHANTS) {
|
|
6669
|
+
if (typeof mid !== "string" || typeof vposHost !== "string" || !Array.isArray(merchants))
|
|
6670
|
+
return null;
|
|
6671
|
+
const found = merchants.filter((row) => !!row && typeof row.merchant === "string" && row.merchant.trim() !== "" && row.mid === mid && row.vposHost === vposHost && typeof row.host === "string" && row.host !== "");
|
|
6672
|
+
return found.length === 1 ? found[0] : null;
|
|
6673
|
+
}
|
|
6674
|
+
function entryAmount(values) {
|
|
6675
|
+
const amount2 = values.get("orderAmount");
|
|
6676
|
+
const code = values.get("currency");
|
|
6677
|
+
const currency = typeof code === "string" && own13(CURRENCIES2, code) ? CURRENCIES2[code] : null;
|
|
6678
|
+
if (!currency || typeof amount2 !== "string" || !/^(?:0|[1-9]\d{0,11})(?:\.\d{1,2})?$/.test(amount2))
|
|
6679
|
+
return null;
|
|
6680
|
+
const [whole2, fraction = ""] = amount2.split(".");
|
|
6681
|
+
const cents2 = Number(whole2) * 100 + Number(fraction.padEnd(2, "0"));
|
|
6682
|
+
return Number.isSafeInteger(cents2) && cents2 > 0 ? { amountCents: cents2, currency } : null;
|
|
6683
|
+
}
|
|
6684
|
+
function httpsUrl(value) {
|
|
6685
|
+
let url;
|
|
6686
|
+
try {
|
|
6687
|
+
url = new URL(value);
|
|
6688
|
+
}
|
|
6689
|
+
catch {
|
|
6690
|
+
return null;
|
|
6691
|
+
}
|
|
6692
|
+
if (url.protocol !== "https:" || url.username || url.password || url.port || url.hash)
|
|
6693
|
+
return null;
|
|
6694
|
+
return url;
|
|
6695
|
+
}
|
|
6696
|
+
function checkCardlinkVposEntry(body, { url = null, merchants = CARDLINK_VPOS_MERCHANTS } = {}) {
|
|
6697
|
+
const vposHost = cardlinkVposEntryHost(url);
|
|
6698
|
+
if (!vposHost)
|
|
6699
|
+
return field2("(url)", "malformed_field");
|
|
6700
|
+
const pairs = parseCardlinkVposForm(body);
|
|
6701
|
+
if (!pairs)
|
|
6702
|
+
return field2("(body)", "malformed");
|
|
6703
|
+
const values = new Map(pairs.map(({ key, value }) => [key, value]));
|
|
6704
|
+
for (const { key } of pairs) {
|
|
6705
|
+
if (KNOWN.has(key))
|
|
6706
|
+
continue;
|
|
6707
|
+
return field2(key, /^(?:card[._]|cvv|cmd$|trid$|st$|paystep$|paymentmethod$)/i.test(key) ? "card_in_entry" : "not_an_entry");
|
|
6708
|
+
}
|
|
6709
|
+
const missing = REQUIRED3.filter((name) => !values.get(name));
|
|
6710
|
+
if (missing.length)
|
|
6711
|
+
return { ok: false, code: "hosted_form_template_incomplete", missing };
|
|
6712
|
+
if (values.get("version") !== "2")
|
|
6713
|
+
return field2("version", "malformed");
|
|
6714
|
+
if (!/^[A-Za-z0-9+/]{43}=$/.test(values.get("digest")))
|
|
6715
|
+
return field2("digest", "unsigned");
|
|
6716
|
+
for (const name of STORED2)
|
|
6717
|
+
if (values.has(name))
|
|
6718
|
+
return field2(name, "stored_credential");
|
|
6719
|
+
for (const name of SPECIAL2)
|
|
6720
|
+
if (values.get(name))
|
|
6721
|
+
return field2(name, "special_flow");
|
|
6722
|
+
for (let i = 1; i <= 9; i += 1)
|
|
6723
|
+
if (/moto\s*=\s*true/i.test(values.get(`var${i}`) ?? ""))
|
|
6724
|
+
return field2(`var${i}`, "moto");
|
|
6725
|
+
if (values.has("trType") && values.get("trType") !== "1")
|
|
6726
|
+
return field2("trType", "not_a_sale");
|
|
6727
|
+
const method = values.get("payMethod");
|
|
6728
|
+
if (method)
|
|
6729
|
+
return field2("payMethod", /^iris$/i.test(method) ? "not_a_card_payment" : "special_flow");
|
|
6730
|
+
const amount2 = entryAmount(values);
|
|
6731
|
+
if (!amount2)
|
|
6732
|
+
return field2(own13(CURRENCIES2, values.get("currency")) ? "orderAmount" : "currency", "malformed");
|
|
6733
|
+
if (!/^\d{1,30}$/.test(values.get("mid")))
|
|
6734
|
+
return field2("mid", "malformed");
|
|
6735
|
+
if (!/^[A-Za-z0-9]{1,50}$/.test(values.get("orderid")))
|
|
6736
|
+
return field2("orderid", "malformed");
|
|
6737
|
+
const seller = cardlinkVposMerchant(values.get("mid"), vposHost, merchants);
|
|
6738
|
+
if (!seller)
|
|
6739
|
+
return field2("mid", "seller_unreviewed");
|
|
6740
|
+
for (const name of ["confirmUrl", "cancelUrl"]) {
|
|
6741
|
+
const target = httpsUrl(values.get(name));
|
|
6742
|
+
if (!target || target.hostname !== seller.host)
|
|
6743
|
+
return field2(name, "callback_host");
|
|
6744
|
+
}
|
|
6745
|
+
return {
|
|
6746
|
+
ok: true,
|
|
6747
|
+
pairs,
|
|
6748
|
+
gated: false,
|
|
6749
|
+
dedupe: [vposHost, values.get("mid"), values.get("orderid"), values.get("orderAmount"), values.get("currency")],
|
|
6750
|
+
seller
|
|
6751
|
+
};
|
|
6752
|
+
}
|
|
6753
|
+
function cardlinkVposEntryAmount(body) {
|
|
6754
|
+
const pairs = parseCardlinkVposForm(body);
|
|
6755
|
+
return pairs ? entryAmount(new Map(pairs.map(({ key, value }) => [key, value]))) : null;
|
|
6756
|
+
}
|
|
6757
|
+
var CARDLINK_VPOS_TDS2_FIELDS = Object.freeze([
|
|
6758
|
+
"TDS2_Navigator_language",
|
|
6759
|
+
"TDS2_Navigator_jsEnabled",
|
|
6760
|
+
"TDS2_Navigator_javaEnabled",
|
|
6761
|
+
"TDS2_Screen_colorDepth",
|
|
6762
|
+
"TDS2_Screen_height",
|
|
6763
|
+
"TDS2_Screen_width",
|
|
6764
|
+
"TDS2_screen_pixelDepth",
|
|
6765
|
+
"TDS2_TimezoneOffset"
|
|
6766
|
+
]);
|
|
6767
|
+
var PAGE_FIELDS = Object.freeze(["trid", "st", "payStep", "cmd", "startbonus", "bonusdata"]);
|
|
6768
|
+
var WALLET_FIELDS2 = Object.freeze(["walletId", "applePayResponse"]);
|
|
6769
|
+
var CARD38 = Object.freeze({ number: "card.pan", holder: "card.holderName", month: "card.expiryMonth", year: "card.expiryYear", cvc: "card.cvv" });
|
|
6770
|
+
var TEXT_CONTROLS = /* @__PURE__ */ new Set([CARD38.number, CARD38.holder, CARD38.cvc]);
|
|
6771
|
+
var SELECT_CONTROLS = /* @__PURE__ */ new Set([CARD38.month, CARD38.year]);
|
|
6772
|
+
var MAX_PAGE3 = 256 * 1024;
|
|
6773
|
+
var COOKIE_DOMAINS = Object.freeze({
|
|
6774
|
+
"vpos.eurocommerce.gr": "eurocommerce.gr",
|
|
6775
|
+
"ecommerce.cardlink.gr": "cardlink.gr",
|
|
6776
|
+
"www.alphaecommerce.gr": "alphaecommerce.gr"
|
|
6777
|
+
});
|
|
6778
|
+
var POST_REQUIRED = Object.freeze(["trid", "st", "cmd", CARD38.number, CARD38.holder, CARD38.month, CARD38.year, CARD38.cvc, "makepayment"]);
|
|
6779
|
+
var POST_EMPTY = Object.freeze(["payStep", "startbonus", "bonusdata", ...WALLET_FIELDS2]);
|
|
6780
|
+
var POST_ALLOWED = /* @__PURE__ */ new Set([...POST_REQUIRED, ...POST_EMPTY, "paymentMethod", ...CARDLINK_VPOS_TDS2_FIELDS]);
|
|
6781
|
+
var CARDLINK_VPOS_REFUSALS = Object.freeze([
|
|
6782
|
+
"cardlink_vpos_card_refused",
|
|
6783
|
+
"cardlink_vpos_card_page",
|
|
6784
|
+
"cardlink_vpos_3ds_challenge",
|
|
6785
|
+
"cardlink_vpos_declined"
|
|
6786
|
+
]);
|
|
6787
|
+
var REFUSAL_FOR = Object.freeze({
|
|
6788
|
+
card_refused: "cardlink_vpos_card_refused",
|
|
6789
|
+
card_page: "cardlink_vpos_card_page",
|
|
6790
|
+
challenge: "cardlink_vpos_3ds_challenge",
|
|
6791
|
+
declined: "cardlink_vpos_declined"
|
|
6792
|
+
});
|
|
6793
|
+
var CARDLINK_VPOS_CAPABILITY = "cardlink_vpos_hosted_payment_page";
|
|
6794
|
+
var CARDLINK_VPOS_OPERATION = "cardlink_vpos.hosted_sale";
|
|
6795
|
+
var cardlink_vpos_default = /* @__PURE__ */ registerProcessor({
|
|
6796
|
+
psp: CARDLINK_VPOS_PSP,
|
|
6797
|
+
definitions: [
|
|
6798
|
+
{
|
|
6799
|
+
psp: "cardlink_vpos",
|
|
6800
|
+
// The merchant's signed entry, as the header above reads it: a Document navigation that carries no card. The
|
|
6801
|
+
// cardholder's device repeats it over the end-to-end TLS relay, fills the card into the page the VPOS returns
|
|
6802
|
+
// and posts it in that same session, and the runtime resolves the paused navigation with the hosted_form notice.
|
|
6803
|
+
// Only the entry path on the three live hosts is matched (isCardlinkVposEntryUrl). The card page posts to the same
|
|
6804
|
+
// path, so the SDK fails every other post to these hosts in the agent's browser, and no placeholder card reaches
|
|
6805
|
+
// the VPOS. The test hosts are listed so a live host classifies as live and the create refuses a test row there;
|
|
6806
|
+
// no entry on them is paused. Ships dark: served only to a client that declares
|
|
6807
|
+
// `cardlink_vpos_hosted_payment_page`, and gated off for every company the operator has not turned it on for.
|
|
6808
|
+
capability: CARDLINK_VPOS_CAPABILITY,
|
|
6809
|
+
match: "(?:vpos\\.eurocommerce\\.gr|ecommerce\\.cardlink\\.gr|www\\.alphaecommerce\\.gr)/vpos/shophandlermpi(?![\\w/.%;=!-])",
|
|
6810
|
+
hosts: [
|
|
6811
|
+
"^vpos\\.eurocommerce\\.gr$",
|
|
6812
|
+
"^ecommerce\\.cardlink\\.gr$",
|
|
6813
|
+
"^www\\.alphaecommerce\\.gr$",
|
|
6814
|
+
"^eurocommerce-test\\.cardlink\\.gr$",
|
|
6815
|
+
"^ecommerce-test\\.cardlink\\.gr$",
|
|
6816
|
+
"^alphaecommerce-test\\.cardlink\\.gr$"
|
|
6817
|
+
],
|
|
6818
|
+
sandboxHosts: ["^eurocommerce-test\\.cardlink\\.gr$", "^ecommerce-test\\.cardlink\\.gr$", "^alphaecommerce-test\\.cardlink\\.gr$"],
|
|
6819
|
+
hostEnvironmentPinned: true,
|
|
6820
|
+
encoding: "form",
|
|
6821
|
+
// A form navigation: no captured header is ever replayed.
|
|
6822
|
+
passthroughHeaders: [],
|
|
6823
|
+
mode: "hosted_form",
|
|
6824
|
+
hostedForm: {
|
|
6825
|
+
// The card goes into the VPOS's own page on the device, never into the entry, which must carry none
|
|
6826
|
+
// (checkCardlinkVposEntry). The entry's rules come with this registration (hostedEntry below), so no policy is
|
|
6827
|
+
// named here.
|
|
6828
|
+
cardIn: "processor_page",
|
|
6829
|
+
required: [...REQUIRED3],
|
|
6830
|
+
// The card page's own fields, which the device fills on that page.
|
|
6831
|
+
card: { number: "card.pan", month: "card.expiryMonth", year: "card.expiryYear", cvc: "card.cvv" },
|
|
6832
|
+
// The host, the mid, the order id and the amount name one payment; the entry's rules read the host from its URL.
|
|
6833
|
+
dedupe: ["(vposHost)", "mid", "orderid", "orderAmount", "currency"]
|
|
6834
|
+
}
|
|
6835
|
+
}
|
|
6836
|
+
],
|
|
6837
|
+
// Only the cardholder's device repeats an entry, after a person approves; no reviewed list names cardlink_vpos.
|
|
6838
|
+
refusedOperations: [CARDLINK_VPOS_OPERATION],
|
|
6839
|
+
// Not surveyed: the VPOS tells the merchant the result through the browser's return and a copy to its server, both
|
|
6840
|
+
// signed under the merchant's secret, which Agentcard never holds.
|
|
6841
|
+
settlementReadback: "not_surveyed",
|
|
6842
|
+
exactUrl: isCardlinkVposEntryUrl,
|
|
6843
|
+
hostedEntry: (body, { url }) => checkCardlinkVposEntry(body, { url }),
|
|
6844
|
+
amount: (template) => template && isCardlinkVposEntryUrl(template.url) ? cardlinkVposEntryAmount(template.body) : null,
|
|
6845
|
+
limitations: [
|
|
6846
|
+
"The paused request is the merchant's signed entry form, which carries no card; the cardholder's device sends it to Cardlink's VPOS over the end-to-end TLS relay and fills the card into the page the VPOS returns.",
|
|
6847
|
+
"Agentcard takes only a reviewed merchant's entry: its mid and the host it posts to name the merchant the cardholder is shown, and its confirm and cancel URLs must sit on that merchant's own host.",
|
|
6848
|
+
"Agentcard takes one plain payment only and refuses an entry that asks for a stored card, installments, a recurring schedule, a pre-authorization, MOTO or a preselected payment method.",
|
|
6849
|
+
"The VPOS runs EMV 3-D Secure on the card. A frictionless answer pays; a challenge ends the payment on the device with nothing charged.",
|
|
6850
|
+
"The browser receives a submission notice, not the processor result."
|
|
6851
|
+
]
|
|
6852
|
+
});
|
|
6853
|
+
// src/processors/eghl.js
|
|
6854
|
+
var EGHL_PSP = "eghl";
|
|
6855
|
+
var EGHL_OPERATION = "eghl.hosted_sale";
|
|
6856
|
+
var EGHL_HOST = "securepay.e-ghl.com";
|
|
6857
|
+
var EGHL_SANDBOX_HOST = "test2pay.ghl.com";
|
|
6858
|
+
var LIVE_PATH = "/ipg/payment.aspx";
|
|
6859
|
+
var SANDBOX_PATH = "/ipgsg/payment.aspx";
|
|
6860
|
+
var MAX_URL2 = 8192;
|
|
6861
|
+
var field3 = (name, reason) => ({ ok: false, code: "hosted_form_field_refused", field: name, reason });
|
|
6862
|
+
function eghlEntry(raw) {
|
|
6863
|
+
if (typeof raw !== "string" || raw.length > MAX_URL2 || raw.includes("#"))
|
|
6864
|
+
return null;
|
|
6865
|
+
let url;
|
|
6866
|
+
try {
|
|
6867
|
+
url = new URL(raw);
|
|
6868
|
+
}
|
|
6869
|
+
catch {
|
|
6870
|
+
return null;
|
|
6871
|
+
}
|
|
6872
|
+
if (url.href !== raw || url.protocol !== "https:" || url.port || url.username || url.password || url.search.length < 2)
|
|
6873
|
+
return null;
|
|
6874
|
+
const path = url.pathname.toLowerCase();
|
|
6875
|
+
const query = url.search.slice(1);
|
|
6876
|
+
if (url.hostname === EGHL_HOST && path === LIVE_PATH)
|
|
6877
|
+
return Object.freeze({ test: false, query });
|
|
6878
|
+
if (url.hostname === EGHL_SANDBOX_HOST && path === SANDBOX_PATH)
|
|
6879
|
+
return Object.freeze({ test: true, query });
|
|
6880
|
+
return null;
|
|
6881
|
+
}
|
|
6882
|
+
function isEghlEntryUrl(raw) {
|
|
6883
|
+
return eghlEntry(raw) !== null;
|
|
6884
|
+
}
|
|
6885
|
+
var EGHL_MERCHANTS = Object.freeze([
|
|
6886
|
+
Object.freeze({ merchant: "BookXcess", serviceId: "BXS", payee: "BookXcess Sdn Bhd", returnHosts: Object.freeze(["shopify.ghl.com:11443"]), test: false })
|
|
6887
|
+
]);
|
|
6888
|
+
var SERVICE_ID2 = /^[A-Za-z0-9]{3}$/;
|
|
6889
|
+
var HOST = /^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?(?:\.[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)+(?::[1-9]\d{0,4})?$/;
|
|
6890
|
+
function eghlMerchant(serviceId, { test = false, merchants = EGHL_MERCHANTS } = {}) {
|
|
6891
|
+
if (typeof serviceId !== "string" || !SERVICE_ID2.test(serviceId) || !Array.isArray(merchants))
|
|
6892
|
+
return null;
|
|
6893
|
+
const found = merchants.filter((row) => !!row && typeof row.merchant === "string" && row.merchant.trim() !== "" && typeof row.payee === "string" && row.payee.trim() !== "" && row.serviceId === serviceId && row.test === test && Array.isArray(row.returnHosts) && row.returnHosts.length > 0 && row.returnHosts.every((host) => typeof host === "string" && HOST.test(host)));
|
|
6894
|
+
return found.length === 1 ? found[0] : null;
|
|
6895
|
+
}
|
|
6896
|
+
var REQUIRED4 = Object.freeze([
|
|
6897
|
+
"TransactionType",
|
|
6898
|
+
"PymtMethod",
|
|
6899
|
+
"ServiceID",
|
|
6900
|
+
"PaymentID",
|
|
6901
|
+
"OrderNumber",
|
|
6902
|
+
"MerchantReturnURL",
|
|
6903
|
+
"MerchantCallBackURL",
|
|
6904
|
+
"Amount",
|
|
6905
|
+
"CurrencyCode",
|
|
6906
|
+
"HashValue"
|
|
6907
|
+
]);
|
|
6908
|
+
var CARD_KEYS17 = /* @__PURE__ */ new Set(["cardno", "cardexp", "cardcvv2", "cardholder", "param2", "param4", "cvv2", "epmonth2", "epyear2", "custocp"]);
|
|
6909
|
+
var SECRET_KEYS = /* @__PURE__ */ new Set(["password"]);
|
|
6910
|
+
var STORED_KEYS2 = /* @__PURE__ */ new Set([
|
|
6911
|
+
"tokentype",
|
|
6912
|
+
"token",
|
|
6913
|
+
"cardid",
|
|
6914
|
+
"precheckoutid",
|
|
6915
|
+
"reqtoken",
|
|
6916
|
+
"pairingtoken",
|
|
6917
|
+
"reqverifier",
|
|
6918
|
+
"pairingverifier",
|
|
6919
|
+
"checkoutresourceurl"
|
|
6920
|
+
]);
|
|
6921
|
+
var SPECIAL_KEYS = /* @__PURE__ */ new Set(["eppmonth", "promocode"]);
|
|
6922
|
+
var RESULT_KEYS = Object.freeze(["MerchantReturnURL", "MerchantCallBackURL", "MerchantApprovalURL", "MerchantUnApprovalURL"]);
|
|
6923
|
+
var CURRENCIES3 = /* @__PURE__ */ new Set(["MYR", "SGD", "USD", "PHP", "THB"]);
|
|
6924
|
+
var AMOUNT3 = /^(0|[1-9]\d{0,8})\.(\d{2})$/;
|
|
6925
|
+
function httpsUrl2(value) {
|
|
6926
|
+
let url;
|
|
6927
|
+
try {
|
|
6928
|
+
url = new URL(value);
|
|
6929
|
+
}
|
|
6930
|
+
catch {
|
|
6931
|
+
return null;
|
|
6932
|
+
}
|
|
6933
|
+
if (url.protocol !== "https:" || url.username || url.password || url.hash)
|
|
6934
|
+
return null;
|
|
6935
|
+
return url;
|
|
6936
|
+
}
|
|
6937
|
+
function entryFields(text11) {
|
|
6938
|
+
const pairs = parseRedsysForm(text11);
|
|
6939
|
+
if (!pairs)
|
|
6940
|
+
return null;
|
|
6941
|
+
return { pairs, values: new Map(pairs.map(({ key, value }) => [key.toLowerCase(), value])) };
|
|
6942
|
+
}
|
|
6943
|
+
function entryAmount2(values) {
|
|
6944
|
+
const currency = values.get("currencycode");
|
|
6945
|
+
const amount2 = AMOUNT3.exec(values.get("amount") ?? "");
|
|
6946
|
+
if (!amount2 || typeof currency !== "string" || !CURRENCIES3.has(currency))
|
|
6947
|
+
return null;
|
|
6948
|
+
const cents2 = Number(amount2[1]) * 100 + Number(amount2[2]);
|
|
6949
|
+
return cents2 > 0 && Number.isSafeInteger(cents2) ? { amountCents: cents2, currency: currency.toLowerCase() } : null;
|
|
6950
|
+
}
|
|
6951
|
+
function checkEghlEntry(body, { url = null, merchants = EGHL_MERCHANTS } = {}) {
|
|
6952
|
+
if (body !== void 0 && body !== null && body !== "")
|
|
6953
|
+
return field3("(body)", "not_an_entry");
|
|
6954
|
+
const entry = eghlEntry(url);
|
|
6955
|
+
if (!entry)
|
|
6956
|
+
return field3("(url)", "malformed_field");
|
|
6957
|
+
const fields = entryFields(entry.query);
|
|
6958
|
+
if (!fields)
|
|
6959
|
+
return field3("(query)", "malformed");
|
|
6960
|
+
const { pairs, values } = fields;
|
|
6961
|
+
for (const { key, value } of pairs) {
|
|
6962
|
+
if (value === "")
|
|
6963
|
+
continue;
|
|
6964
|
+
const folded = key.toLowerCase();
|
|
6965
|
+
if (CARD_KEYS17.has(folded))
|
|
6966
|
+
return field3(key, "card_in_entry");
|
|
6967
|
+
if (SECRET_KEYS.has(folded))
|
|
6968
|
+
return field3(key, "not_an_entry");
|
|
6969
|
+
if (STORED_KEYS2.has(folded))
|
|
6970
|
+
return field3(key, "stored_credential");
|
|
6971
|
+
if (SPECIAL_KEYS.has(folded))
|
|
6972
|
+
return field3(key, "special_flow");
|
|
6973
|
+
}
|
|
6974
|
+
const missing = REQUIRED4.filter((name) => !values.get(name.toLowerCase()));
|
|
6975
|
+
if (missing.length)
|
|
6976
|
+
return { ok: false, code: "hosted_form_template_incomplete", missing };
|
|
6977
|
+
if (values.get("transactiontype") !== "SALE")
|
|
6978
|
+
return field3("TransactionType", "not_a_sale");
|
|
6979
|
+
if (!["ANY", "CC"].includes(values.get("pymtmethod")))
|
|
6980
|
+
return field3("PymtMethod", "special_flow");
|
|
6981
|
+
if (!/^[0-9A-Fa-f]{64}$/.test(values.get("hashvalue")))
|
|
6982
|
+
return field3("HashValue", "unsigned");
|
|
6983
|
+
if (!entryAmount2(values))
|
|
6984
|
+
return field3(CURRENCIES3.has(values.get("currencycode")) ? "Amount" : "CurrencyCode", "malformed");
|
|
6985
|
+
if (!SERVICE_ID2.test(values.get("serviceid")))
|
|
6986
|
+
return field3("ServiceID", "malformed");
|
|
6987
|
+
if (!/^[A-Za-z0-9._-]{1,20}$/.test(values.get("paymentid")))
|
|
6988
|
+
return field3("PaymentID", "malformed");
|
|
6989
|
+
if (values.get("ordernumber").length > 20)
|
|
6990
|
+
return field3("OrderNumber", "malformed");
|
|
6991
|
+
const pageTimeout = values.get("pagetimeout");
|
|
6992
|
+
if (pageTimeout !== void 0 && !/^[1-9]\d{1,4}$/.test(pageTimeout))
|
|
6993
|
+
return field3("PageTimeout", "malformed");
|
|
6994
|
+
const seller = eghlMerchant(values.get("serviceid"), { test: entry.test, merchants });
|
|
6995
|
+
if (!seller)
|
|
6996
|
+
return field3("ServiceID", "seller_unreviewed");
|
|
6997
|
+
for (const name of RESULT_KEYS) {
|
|
6998
|
+
const value = values.get(name.toLowerCase());
|
|
6999
|
+
if (!value)
|
|
7000
|
+
continue;
|
|
7001
|
+
const target = httpsUrl2(value);
|
|
7002
|
+
if (!target || !seller.returnHosts.includes(target.host) || [EGHL_HOST, EGHL_SANDBOX_HOST].includes(target.hostname))
|
|
7003
|
+
return field3(name, "callback_host");
|
|
7004
|
+
}
|
|
7005
|
+
return { ok: true, pairs, gated: false, dedupe: [values.get("serviceid"), values.get("paymentid")], sandbox: entry.test, seller };
|
|
7006
|
+
}
|
|
7007
|
+
function eghlEntryAmount(body, url) {
|
|
7008
|
+
if (body !== void 0 && body !== null && body !== "")
|
|
7009
|
+
return null;
|
|
7010
|
+
const entry = eghlEntry(url);
|
|
7011
|
+
const fields = entry ? entryFields(entry.query) : null;
|
|
7012
|
+
return fields ? entryAmount2(fields.values) : null;
|
|
7013
|
+
}
|
|
7014
|
+
var MAX_PAGE4 = 1024 * 1024;
|
|
7015
|
+
var NEVER_SENT = new Set(["expressCheckoutType", "c2pRememberMeBrowser", "CustOCP", "CustRecurr", "CustAddress"].map((name) => name.toLowerCase()));
|
|
7016
|
+
var PAGE_REQUIRED = Object.freeze([
|
|
7017
|
+
"TransactionType",
|
|
7018
|
+
"ServiceID",
|
|
7019
|
+
"MerchantName",
|
|
7020
|
+
"PaymentID",
|
|
7021
|
+
"Amount",
|
|
7022
|
+
"BaseTxnAmount",
|
|
7023
|
+
"CurrencyCode",
|
|
7024
|
+
"BaseCurrencyCode",
|
|
7025
|
+
"HashValue",
|
|
7026
|
+
"Param2",
|
|
7027
|
+
"Param4",
|
|
7028
|
+
"CardExp",
|
|
7029
|
+
"CVV2",
|
|
7030
|
+
"PymtMethod"
|
|
7031
|
+
]);
|
|
7032
|
+
var EGHL_REFUSALS = Object.freeze(["eghl_failed", "eghl_cancelled"]);
|
|
7033
|
+
var MAX_ANSWER = 256 * 1024;
|
|
7034
|
+
var RESULT_FIELDS = Object.freeze(["TxnStatus", "ServiceID", "PaymentID", "Amount", "CurrencyCode"]);
|
|
7035
|
+
var eghl_default = /* @__PURE__ */ registerProcessor({
|
|
7036
|
+
psp: EGHL_PSP,
|
|
7037
|
+
definitions: [
|
|
7038
|
+
{
|
|
7039
|
+
psp: "eghl",
|
|
7040
|
+
// The merchant's entry to eGHL's payment page, as the header above reads it: a GET Document navigation whose
|
|
7041
|
+
// query names the payment and which carries no card. The cardholder's device repeats it over the end-to-end TLS
|
|
7042
|
+
// relay and pays on the page eGHL returns to it, and the runtime resolves the paused navigation with the
|
|
7043
|
+
// hosted_form notice. Only the entry is matched (isEghlEntryUrl): the card page's own card post goes to the same
|
|
7044
|
+
// path as a POST. The path is matched in any letter case, as IIS reads it; `(?![\\w/.%-])` ends it for a consumer
|
|
7045
|
+
// that tests `match` unanchored. Ships dark: served only to a client that declares `eghl_hosted_payment_page`, and
|
|
7046
|
+
// gated off for every company the operator has not allowlisted.
|
|
7047
|
+
capability: "eghl_hosted_payment_page",
|
|
7048
|
+
match: "securepay\\.e-ghl\\.com/[Ii][Pp][Gg]/[Pp][Aa][Yy][Mm][Ee][Nn][Tt]\\.[Aa][Ss][Pp][Xx](?![\\w/.%-])|test2pay\\.ghl\\.com/[Ii][Pp][Gg][Ss][Gg]/[Pp][Aa][Yy][Mm][Ee][Nn][Tt]\\.[Aa][Ss][Pp][Xx](?![\\w/.%-])",
|
|
7049
|
+
hosts: ["^securepay\\.e-ghl\\.com$", "^test2pay\\.ghl\\.com$"],
|
|
7050
|
+
sandboxHosts: ["^test2pay\\.ghl\\.com$"],
|
|
7051
|
+
hostEnvironmentPinned: true,
|
|
7052
|
+
// `encoding` describes the card page's own card post, which the device makes as the page does, since the entry
|
|
7053
|
+
// has no body. No captured header is ever replayed.
|
|
7054
|
+
encoding: "form",
|
|
7055
|
+
passthroughHeaders: [],
|
|
7056
|
+
// The paused request is the navigation itself, a GET with the payment in its query.
|
|
7057
|
+
request: { method: "GET", cardIn: "processor_page", response: "document" },
|
|
7058
|
+
mode: "hosted_form",
|
|
7059
|
+
hostedForm: {
|
|
7060
|
+
// The card goes into eGHL's page on the device, never into the entry (checkEghlEntry refuses one there). The
|
|
7061
|
+
// entry's own rules come with this registration (hostedEntry below), so no policy is named here.
|
|
7062
|
+
cardIn: "processor_page",
|
|
7063
|
+
required: ["TransactionType", "PymtMethod", "ServiceID", "PaymentID", "OrderNumber", "MerchantReturnURL", "MerchantCallBackURL", "Amount", "CurrencyCode", "HashValue"],
|
|
7064
|
+
// The card page's own inputs in its card form (frmProcessPayment, read card free on 2026-11-05): the number in
|
|
7065
|
+
// Param2, the expiry in CardExp as YYYYMM, which the page builds from its month and year selects, the code in
|
|
7066
|
+
// CVV2. The cardholder's name goes in Param4.
|
|
7067
|
+
card: { number: "Param2", expiry: "CardExp", cvc: "CVV2" },
|
|
7068
|
+
// eGHL takes one PaymentID once per merchant.
|
|
7069
|
+
dedupe: ["ServiceID", "PaymentID"]
|
|
7070
|
+
}
|
|
7071
|
+
}
|
|
7072
|
+
],
|
|
7073
|
+
// Only the cardholder's device repeats an entry, after a person approves; no reviewed list names eghl.
|
|
7074
|
+
refusedOperations: [EGHL_OPERATION],
|
|
7075
|
+
// Not surveyed: eGHL tells the merchant's server the result (MerchantCallBackURL), and its return carries a hash only
|
|
7076
|
+
// the merchant can check.
|
|
7077
|
+
settlementReadback: "not_surveyed",
|
|
7078
|
+
exactUrl: isEghlEntryUrl,
|
|
7079
|
+
amount: (template) => template && typeof template === "object" ? eghlEntryAmount(template.body, template.url) : null,
|
|
7080
|
+
hostedEntry: (body, { url = null } = {}) => checkEghlEntry(body, { url }),
|
|
7081
|
+
limitations: [
|
|
7082
|
+
"The paused request is the merchant's redirect to eGHL's payment page, a GET whose query names the payment and carries no card; the cardholder's device repeats it over the end-to-end TLS relay and pays on the page eGHL returns.",
|
|
7083
|
+
"Agentcard takes an entry only for a merchant it reviewed, by the ServiceID inside the merchant's signed entry, and the approval names that merchant and the amount the entry names.",
|
|
7084
|
+
"eGHL runs 3-D Secure on the card. A challenge ends the payment on the device with nothing charged.",
|
|
7085
|
+
"eGHL sends the buyer to the merchant's return page with a result only the merchant can verify, so the browser receives a submission notice, not the processor result."
|
|
7086
|
+
]
|
|
7087
|
+
});
|
|
7088
|
+
// src/processors/frisbii.js
|
|
7089
|
+
var FRISBII_PSP = "frisbii";
|
|
7090
|
+
var FRISBII_OPERATION = "frisbii.card_request";
|
|
7091
|
+
var FRISBII_HOSTS = /* @__PURE__ */ Object.freeze({ "card.reepay.com": "reepay", "card.frisbii.com": "frisbii" });
|
|
7092
|
+
var FRISBII_TOKEN_PATH = "/v1/token/";
|
|
7093
|
+
var FRISBII_REFUSED_PATHS = /* @__PURE__ */ Object.freeze({
|
|
7094
|
+
"/v1/token/cof/": "frisbii_stored_card_unsupported",
|
|
7095
|
+
"/v1/token/create_click_to_pay": "frisbii_click_to_pay_unsupported"
|
|
7096
|
+
});
|
|
7097
|
+
var BODY_LIMIT37 = 8192;
|
|
7098
|
+
var URL_LIMIT15 = 256;
|
|
7099
|
+
var CARD_NUMBER19 = /^[0-9]{12,19}$/;
|
|
7100
|
+
var MONTH19 = /^(?:0[1-9]|1[0-2])$/;
|
|
7101
|
+
var YEAR20 = /^[0-9]{2}$/;
|
|
7102
|
+
var SECURITY_CODE23 = /^(?:[0-9]{3,4})?$/;
|
|
7103
|
+
var IDENTIFIER2 = /^[A-Za-z0-9_-]{8,128}$/;
|
|
7104
|
+
var SCA_RULES = /* @__PURE__ */ Object.freeze([
|
|
7105
|
+
"DO_NOT_USE_SCA",
|
|
7106
|
+
"MUST_USE_SCA_AUTH",
|
|
7107
|
+
"MUST_USE_SCA_PREAUTH",
|
|
7108
|
+
"USE_SCA_IF_AVAILABLE_AUTH",
|
|
7109
|
+
"USE_SCA_IF_AVAILABLE_PREAUTH"
|
|
7110
|
+
]);
|
|
7111
|
+
var BODY_ORDER = /* @__PURE__ */ Object.freeze([
|
|
7112
|
+
"number",
|
|
7113
|
+
"month",
|
|
7114
|
+
"year",
|
|
7115
|
+
"cvv",
|
|
7116
|
+
"cardTypeOverride",
|
|
7117
|
+
"click_to_pay_encrypt",
|
|
7118
|
+
"billing_address",
|
|
7119
|
+
"pkey",
|
|
7120
|
+
"recurring",
|
|
7121
|
+
"cardholder_name",
|
|
7122
|
+
"intent",
|
|
7123
|
+
"recurringAverageAmount",
|
|
7124
|
+
"agreementFilter",
|
|
7125
|
+
"strongAuthenticationRule",
|
|
7126
|
+
"tokenStrongAuthenticationRequest"
|
|
7127
|
+
]);
|
|
7128
|
+
var BODY_REQUIRED = /* @__PURE__ */ Object.freeze(["number", "month", "year", "cvv", "pkey", "recurring", "strongAuthenticationRule"]);
|
|
7129
|
+
var BODY_REFUSED = /* @__PURE__ */ Object.freeze(["cardTypeOverride", "click_to_pay_encrypt", "billing_address"]);
|
|
7130
|
+
var SCA_ORDER = /* @__PURE__ */ Object.freeze(["amount", "currency", "orderId", "orderText", "merchantScaData", "returnUrl", "tokenBrowserInfo"]);
|
|
7131
|
+
var BROWSER_ORDER = /* @__PURE__ */ Object.freeze([
|
|
7132
|
+
"javascriptEnabled",
|
|
7133
|
+
"challengeWindowSize",
|
|
7134
|
+
"colorDepth",
|
|
7135
|
+
"javaEnabled",
|
|
7136
|
+
"screenHeight",
|
|
7137
|
+
"screenWidth",
|
|
7138
|
+
"tz"
|
|
7139
|
+
]);
|
|
7140
|
+
var LABEL = /^[A-Za-z0-9_-]{1,64}$/;
|
|
7141
|
+
var record33 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
7142
|
+
var own14 = (value, key) => Object.prototype.hasOwnProperty.call(value, key);
|
|
7143
|
+
var refuse39 = (code) => Object.freeze({ verdict: "refuse", code });
|
|
7144
|
+
var CARD39 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
|
|
7145
|
+
var text9 = (value, max) => typeof value === "string" && value.length <= max;
|
|
7146
|
+
var absentOrNull = (value) => value === void 0 || value === null;
|
|
7147
|
+
var inOrder6 = (value, order) => Object.keys(value).every((key) => order.includes(key)) && Object.keys(value).join() === order.filter((key) => own14(value, key)).join();
|
|
7148
|
+
function frisbiiTokenUrl(url) {
|
|
7149
|
+
if (typeof url !== "string" || url.length > URL_LIMIT15 || url.includes("#"))
|
|
7150
|
+
return null;
|
|
7151
|
+
let parsed;
|
|
7152
|
+
try {
|
|
7153
|
+
parsed = new URL(url);
|
|
7154
|
+
}
|
|
7155
|
+
catch {
|
|
7156
|
+
return null;
|
|
7157
|
+
}
|
|
7158
|
+
if (parsed.href !== url || parsed.protocol !== "https:" || parsed.port || parsed.username || parsed.password || !own14(FRISBII_HOSTS, parsed.hostname) || parsed.pathname !== FRISBII_TOKEN_PATH)
|
|
7159
|
+
return null;
|
|
7160
|
+
const match = /^\?session=([A-Za-z0-9_-]{8,128})$/.exec(parsed.search);
|
|
7161
|
+
return match ? Object.freeze({ host: parsed.hostname, brand: FRISBII_HOSTS[parsed.hostname], session: match[1] }) : null;
|
|
7162
|
+
}
|
|
7163
|
+
var isFrisbiiTokenUrl = (url) => frisbiiTokenUrl(url) !== null;
|
|
7164
|
+
function frisbiiRefusedFlowUrl(url) {
|
|
7165
|
+
if (typeof url !== "string" || url.length > URL_LIMIT15 || url.includes("#"))
|
|
7166
|
+
return null;
|
|
7167
|
+
let parsed;
|
|
7168
|
+
try {
|
|
7169
|
+
parsed = new URL(url);
|
|
7170
|
+
}
|
|
7171
|
+
catch {
|
|
7172
|
+
return null;
|
|
7173
|
+
}
|
|
7174
|
+
if (parsed.href !== url || parsed.protocol !== "https:" || parsed.port || parsed.username || parsed.password || !own14(FRISBII_HOSTS, parsed.hostname) || !own14(FRISBII_REFUSED_PATHS, parsed.pathname))
|
|
7175
|
+
return null;
|
|
7176
|
+
return FRISBII_REFUSED_PATHS[parsed.pathname];
|
|
7177
|
+
}
|
|
7178
|
+
function luhn9(digits4) {
|
|
7179
|
+
let sum = 0;
|
|
7180
|
+
for (let at = digits4.length - 1, double = false; at >= 0; at -= 1, double = !double) {
|
|
7181
|
+
let digit = digits4.charCodeAt(at) - 48;
|
|
7182
|
+
if (double)
|
|
7183
|
+
digit = digit * 2 > 9 ? digit * 2 - 9 : digit * 2;
|
|
7184
|
+
sum += digit;
|
|
7185
|
+
}
|
|
7186
|
+
return sum % 10 === 0;
|
|
7187
|
+
}
|
|
7188
|
+
function readBody23(body) {
|
|
7189
|
+
if (typeof body !== "string" || body === "" || body.length > BODY_LIMIT37)
|
|
7190
|
+
return null;
|
|
7191
|
+
try {
|
|
7192
|
+
const value = JSON.parse(body);
|
|
7193
|
+
return record33(value) && JSON.stringify(value) === body ? value : null;
|
|
7194
|
+
}
|
|
7195
|
+
catch {
|
|
7196
|
+
return null;
|
|
7197
|
+
}
|
|
7198
|
+
}
|
|
7199
|
+
function browserInfo(info) {
|
|
7200
|
+
return record33(info) && Object.keys(info).join() === BROWSER_ORDER.join() && info.javascriptEnabled === true && typeof info.javaEnabled === "boolean" && /^size_[0-9]{3}x[0-9]{3}$/.test(info.challengeWindowSize) && [info.colorDepth, info.screenHeight, info.screenWidth].every((n) => Number.isSafeInteger(n) && n >= 0 && n <= 1e5) && Number.isSafeInteger(info.tz) && Math.abs(info.tz) <= 1440;
|
|
7201
|
+
}
|
|
7202
|
+
function scaBlock(block, target) {
|
|
7203
|
+
if (!record33(block) || !inOrder6(block, SCA_ORDER) || !own14(block, "returnUrl") || !own14(block, "tokenBrowserInfo"))
|
|
7204
|
+
return false;
|
|
7205
|
+
if (!Number.isSafeInteger(block.amount) || block.amount < 0 || typeof block.currency !== "string" || !/^[A-Z]{3}$/.test(block.currency))
|
|
7206
|
+
return false;
|
|
7207
|
+
if (!(absentOrNull(block.orderId) || text9(block.orderId, 128)) || !(absentOrNull(block.orderText) || text9(block.orderText, 512)))
|
|
7208
|
+
return false;
|
|
7209
|
+
if (!(absentOrNull(block.merchantScaData) || record33(block.merchantScaData)))
|
|
7210
|
+
return false;
|
|
7211
|
+
if (!text9(block.returnUrl, 2048) || !browserInfo(block.tokenBrowserInfo))
|
|
7212
|
+
return false;
|
|
7213
|
+
const back = /^https:\/\/checkout\.(reepay|frisbii)\.com\/return\.001\.html\?id=([A-Za-z0-9_-]{8,128})(?:&[A-Za-z0-9_.~%=+/-]*)*$/.exec(block.returnUrl);
|
|
7214
|
+
return back !== null && (target === null || back[1] === target.brand && back[2] === target.session);
|
|
7215
|
+
}
|
|
7216
|
+
function frisbiiBodyVerdict(body, url) {
|
|
7217
|
+
const value = readBody23(body);
|
|
7218
|
+
if (value === null || !inOrder6(value, BODY_ORDER) || !BODY_REQUIRED.every((key) => own14(value, key)) || BODY_REFUSED.some((key) => own14(value, key)))
|
|
7219
|
+
return refuse39("frisbii_body_unsupported");
|
|
7220
|
+
if (value.recurring === true || value.intent === "CHARGE_AND_STORE")
|
|
7221
|
+
return refuse39("frisbii_card_on_file");
|
|
7222
|
+
const target = url === void 0 ? null : frisbiiTokenUrl(url);
|
|
7223
|
+
if (url !== void 0 && target === null)
|
|
7224
|
+
return refuse39("frisbii_body_unsupported");
|
|
7225
|
+
const sound = typeof value.number === "string" && CARD_NUMBER19.test(value.number) && luhn9(value.number) && typeof value.month === "string" && MONTH19.test(value.month) && typeof value.year === "string" && YEAR20.test(value.year) && typeof value.cvv === "string" && SECURITY_CODE23.test(value.cvv) && typeof value.pkey === "string" && IDENTIFIER2.test(value.pkey) && value.recurring === false && (value.cardholder_name === void 0 || text9(value.cardholder_name, 64)) && (value.intent === void 0 || value.intent === "CHARGE") && (absentOrNull(value.recurringAverageAmount) || Number.isSafeInteger(value.recurringAverageAmount) && value.recurringAverageAmount >= 0) && (absentOrNull(value.agreementFilter) || typeof value.agreementFilter === "string" && LABEL.test(value.agreementFilter) || Array.isArray(value.agreementFilter) && value.agreementFilter.length <= 16 && value.agreementFilter.every((entry) => typeof entry === "string" && LABEL.test(entry))) && SCA_RULES.includes(value.strongAuthenticationRule) && (value.tokenStrongAuthenticationRequest === void 0 || scaBlock(value.tokenStrongAuthenticationRequest, target));
|
|
7226
|
+
return sound ? CARD39 : refuse39("frisbii_body_unsupported");
|
|
7227
|
+
}
|
|
7228
|
+
var frisbii_default = /* @__PURE__ */ registerProcessor({
|
|
7229
|
+
psp: FRISBII_PSP,
|
|
7230
|
+
definitions: [
|
|
7231
|
+
{
|
|
7232
|
+
psp: "frisbii",
|
|
7233
|
+
// The hosted page's card request, as the header above reads it, on both brands' card hosts. A test account
|
|
7234
|
+
// shares the live hosts, so no sandbox host is marked. The match reads the host and the path and ends with it. It
|
|
7235
|
+
// also takes the page's two other card paths, /v1/token/cof/ and /v1/token/create_click_to_pay, so the pause
|
|
7236
|
+
// decision holds them, and the body gate refuses every body there; the exact-URL rule below holds the session
|
|
7237
|
+
// query of the card request. Ships dark: served only to a client that declares `frisbii_card_token`, and only for a company
|
|
7238
|
+
// the backend's processor gate turns Frisbii on for.
|
|
7239
|
+
capability: "frisbii_card_token",
|
|
7240
|
+
match: "card\\.(?:reepay|frisbii)\\.com/v1/token/(?:cof/|create_click_to_pay)?",
|
|
7241
|
+
hosts: ["^card\\.reepay\\.com$", "^card\\.frisbii\\.com$"],
|
|
7242
|
+
encoding: "json",
|
|
7243
|
+
// The page sends no header but its content type. Origin, Referer and cookies never ride.
|
|
7244
|
+
passthroughHeaders: [],
|
|
7245
|
+
jsonCardFields: [["number"]]
|
|
7246
|
+
}
|
|
7247
|
+
],
|
|
7248
|
+
// Only the cardholder's device would send this card, after a person approves; no reviewed list names frisbii.
|
|
7249
|
+
refusedOperations: [FRISBII_OPERATION],
|
|
7250
|
+
// Not surveyed: the card request mints a token and moves no money, and the page then charges the session with it
|
|
7251
|
+
// in a card-free request. Whether the session's own read (checkout-api /v1/checkout/<session>) can confirm that
|
|
7252
|
+
// charge was not read.
|
|
7253
|
+
settlementReadback: "not_surveyed",
|
|
7254
|
+
exactUrl: (url) => isFrisbiiTokenUrl(url) || frisbiiRefusedFlowUrl(url) !== null,
|
|
7255
|
+
// A stored card's token and Click to Pay are refused whatever their body; the card request is judged by its body.
|
|
7256
|
+
bodyGate: (url, body) => {
|
|
7257
|
+
if (url === void 0)
|
|
7258
|
+
return frisbiiBodyVerdict(body);
|
|
7259
|
+
const flow = frisbiiRefusedFlowUrl(url);
|
|
7260
|
+
if (flow !== null)
|
|
7261
|
+
return refuse39(flow);
|
|
7262
|
+
return isFrisbiiTokenUrl(url) ? frisbiiBodyVerdict(body, url) : refuse39("frisbii_url_refused");
|
|
7263
|
+
},
|
|
7264
|
+
limitations: ["A live Frisbii card goes only to a merchant account a reviewed pin lists, and none is pinned yet."]
|
|
7265
|
+
});
|
|
7266
|
+
// src/processors/iyzico.js
|
|
7267
|
+
var IYZICO_PSP = "iyzico";
|
|
7268
|
+
var IYZICO_OPERATION = "iyzico.card_request";
|
|
7269
|
+
var PATHS = ["/payment/iyzipos/checkoutform/auth/ecom", "/payment/iyzipos/checkoutform/initialize3ds/ecom"];
|
|
7270
|
+
var IYZICO_CARD_URLS = /* @__PURE__ */ Object.freeze(["https://api.iyzipay.com", "https://sandbox-api.iyzipay.com"].flatMap((origin) => PATHS.map((path) => `${origin}${path}`)));
|
|
7271
|
+
var IYZICO_BODY_KEYS = /* @__PURE__ */ Object.freeze([
|
|
7272
|
+
"installment",
|
|
7273
|
+
"paidPrice",
|
|
7274
|
+
"paymentChannel",
|
|
7275
|
+
"paymentCard",
|
|
7276
|
+
"buyerProtected",
|
|
7277
|
+
"gsmNumber",
|
|
7278
|
+
"dccPayment",
|
|
7279
|
+
"dccQueryRrn",
|
|
7280
|
+
"pwiMetadata"
|
|
7281
|
+
]);
|
|
7282
|
+
var IYZICO_CARD_KEYS = /* @__PURE__ */ Object.freeze([
|
|
7283
|
+
"cardNumber",
|
|
7284
|
+
"cardHolderName",
|
|
7285
|
+
"expireYear",
|
|
7286
|
+
"expireMonth",
|
|
7287
|
+
"cvc",
|
|
7288
|
+
"registerConsumerCard",
|
|
7289
|
+
"registerCard"
|
|
7290
|
+
]);
|
|
7291
|
+
var BODY_LIMIT38 = 4096;
|
|
7292
|
+
var CARD_NUMBER20 = /^[0-9]{12,19}$/;
|
|
7293
|
+
var SECURITY_CODE24 = /^[0-9]{3,4}$/;
|
|
7294
|
+
var MONTH20 = /^(?:0?[1-9]|1[0-2])$/;
|
|
7295
|
+
var YEAR21 = /^(?:[0-9]{2}|20[0-9]{2})$/;
|
|
7296
|
+
var PRICE = /^([1-9][0-9]{0,8}|0)(?:\.([0-9]{1,2}))?$/;
|
|
7297
|
+
var CHANNELS = /* @__PURE__ */ Object.freeze(["WEB", "MOBILE_WEB", "MOBILE_IOS", "MOBILE_ANDROID", "MOBILE_WINDOWS"]);
|
|
7298
|
+
var METADATA_KEYS3 = /* @__PURE__ */ Object.freeze(["lightRedesign", "pwiGrowthActionDisabled"]);
|
|
7299
|
+
var FLAG = /^[A-Za-z_]{1,16}$/;
|
|
7300
|
+
var HOLDER5 = /^[^\x00-\x1f\x7f0-9]{3,100}$/u;
|
|
7301
|
+
var record34 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
7302
|
+
var own15 = (value, key) => Object.prototype.hasOwnProperty.call(value, key);
|
|
7303
|
+
var inOrder7 = (value, keys) => {
|
|
7304
|
+
let at = 0;
|
|
7305
|
+
for (const name of Object.keys(value)) {
|
|
7306
|
+
while (at < keys.length && keys[at] !== name)
|
|
7307
|
+
at += 1;
|
|
7308
|
+
if (at === keys.length)
|
|
7309
|
+
return false;
|
|
7310
|
+
at += 1;
|
|
7311
|
+
}
|
|
7312
|
+
return true;
|
|
7313
|
+
};
|
|
7314
|
+
var refuse40 = (code) => Object.freeze({ verdict: "refuse", code });
|
|
7315
|
+
var CARD40 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
|
|
7316
|
+
function isIyzicoCardUrl(url) {
|
|
7317
|
+
return typeof url === "string" && IYZICO_CARD_URLS.includes(url);
|
|
7318
|
+
}
|
|
7319
|
+
function readBody24(body) {
|
|
7320
|
+
if (typeof body !== "string" || body === "" || body.length > BODY_LIMIT38)
|
|
7321
|
+
return null;
|
|
7322
|
+
try {
|
|
7323
|
+
const value = JSON.parse(body);
|
|
7324
|
+
return record34(value) && JSON.stringify(value) === body ? value : null;
|
|
7325
|
+
}
|
|
7326
|
+
catch {
|
|
7327
|
+
return null;
|
|
7328
|
+
}
|
|
7329
|
+
}
|
|
7330
|
+
function hundredths(price) {
|
|
7331
|
+
const match = typeof price === "number" && Number.isFinite(price) ? PRICE.exec(String(price)) : null;
|
|
7332
|
+
const value = match ? Number(match[1]) * 100 + Number((match[2] ?? "").padEnd(2, "0")) : 0;
|
|
7333
|
+
return value > 0 ? value : null;
|
|
7334
|
+
}
|
|
7335
|
+
var holderName2 = (name) => typeof name === "string" && HOLDER5.test(name) && name.trim().split(/\s+/).filter((word) => word.length > 1).length > 1;
|
|
7336
|
+
var metadata = (value) => record34(value) && inOrder7(value, METADATA_KEYS3) && Object.values(value).every((flag3) => Array.isArray(flag3) && flag3.length === 1 && typeof flag3[0] === "string" && FLAG.test(flag3[0]));
|
|
7337
|
+
function iyzicoBodyVerdict(body) {
|
|
7338
|
+
const value = readBody24(body);
|
|
7339
|
+
if (value === null)
|
|
7340
|
+
return refuse40("iyzico_body_unsupported");
|
|
7341
|
+
const card = value.paymentCard;
|
|
7342
|
+
if (record34(card) && (own15(card, "cardToken") || own15(card, "ucsToken") || own15(card, "consumerToken")) && !own15(card, "cardNumber"))
|
|
7343
|
+
return refuse40("iyzico_saved_card");
|
|
7344
|
+
if (own15(value, "dccPayment") || own15(value, "dccQueryRrn"))
|
|
7345
|
+
return refuse40("iyzico_dcc_refused");
|
|
7346
|
+
if (own15(value, "gsmNumber") || own15(value, "buyerProtected") && value.buyerProtected !== false || record34(card) && (own15(card, "registerCard") && card.registerCard !== 0 || own15(card, "registerConsumerCard") && card.registerConsumerCard !== false)) {
|
|
7347
|
+
return refuse40("iyzico_keeps_card");
|
|
7348
|
+
}
|
|
7349
|
+
if (Number.isSafeInteger(value.installment) && value.installment > 1)
|
|
7350
|
+
return refuse40("iyzico_installments_refused");
|
|
7351
|
+
if (!inOrder7(value, IYZICO_BODY_KEYS) || !["installment", "paidPrice", "paymentChannel", "paymentCard"].every((key) => own15(value, key)) || value.installment !== 1 || hundredths(value.paidPrice) === null || !CHANNELS.includes(value.paymentChannel) || own15(value, "pwiMetadata") && !metadata(value.pwiMetadata))
|
|
7352
|
+
return refuse40("iyzico_body_unsupported");
|
|
7353
|
+
if (!record34(card) || Object.keys(card).join() !== IYZICO_CARD_KEYS.join() || typeof card.cardNumber !== "string" || !CARD_NUMBER20.test(card.cardNumber) || !holderName2(card.cardHolderName) || typeof card.expireYear !== "string" || !YEAR21.test(card.expireYear) || typeof card.expireMonth !== "string" || !MONTH20.test(card.expireMonth) || typeof card.cvc !== "string" || !SECURITY_CODE24.test(card.cvc))
|
|
7354
|
+
return refuse40("iyzico_body_unsupported");
|
|
7355
|
+
return CARD40;
|
|
7356
|
+
}
|
|
7357
|
+
var iyzico_default = /* @__PURE__ */ registerProcessor({
|
|
7358
|
+
psp: IYZICO_PSP,
|
|
7359
|
+
definitions: [
|
|
7360
|
+
{
|
|
7361
|
+
psp: "iyzico",
|
|
7362
|
+
// The Checkout Form's card payment, as the header above reads it. Sandbox has its own host, so the device sends
|
|
7363
|
+
// a test-mode payment only iyzico's documented test cards (hostEnvironmentPinned, device-replay.js S7). Ships dark:
|
|
6357
7364
|
// served only to a client that declares `iyzico_checkout_form`, for a company the backend's gate turns iyzico on
|
|
6358
7365
|
// for, and autopilot never sends it.
|
|
6359
7366
|
capability: "iyzico_checkout_form",
|
|
@@ -6378,7 +7385,7 @@ var iyzico_default = /* @__PURE__ */ registerProcessor({
|
|
|
6378
7385
|
source: "https://docs.iyzico.com/en/payment-methods/checkoutform/cf-implementation/cf-retrieve"
|
|
6379
7386
|
},
|
|
6380
7387
|
exactUrl: isIyzicoCardUrl,
|
|
6381
|
-
bodyGate: (url, body) => url !== void 0 && !isIyzicoCardUrl(url) ?
|
|
7388
|
+
bodyGate: (url, body) => url !== void 0 && !isIyzicoCardUrl(url) ? refuse40("iyzico_url_refused") : iyzicoBodyVerdict(body)
|
|
6382
7389
|
});
|
|
6383
7390
|
// src/processors/midtrans.js
|
|
6384
7391
|
var MIDTRANS_PSP = "midtrans";
|
|
@@ -6386,15 +7393,15 @@ var MIDTRANS_OPERATION = "midtrans.card_request";
|
|
|
6386
7393
|
var MIDTRANS_TOKEN_URL = "https://api.midtrans.com/v2/token";
|
|
6387
7394
|
var MIDTRANS_SANDBOX_TOKEN_URL = "https://api.sandbox.midtrans.com/v2/token";
|
|
6388
7395
|
var MIDTRANS_TOKEN_KEYS = /* @__PURE__ */ Object.freeze(["card_cvv", "card_number", "card_exp_month", "card_exp_year", "installment_term"]);
|
|
6389
|
-
var
|
|
6390
|
-
var
|
|
6391
|
-
var
|
|
6392
|
-
var
|
|
6393
|
-
var
|
|
7396
|
+
var BODY_LIMIT39 = 4096;
|
|
7397
|
+
var CARD_NUMBER21 = /^[0-9]{12,19}$/;
|
|
7398
|
+
var SECURITY_CODE25 = /^[0-9]{3,4}$/;
|
|
7399
|
+
var MONTH21 = /^(?:0[1-9]|1[0-2])$/;
|
|
7400
|
+
var YEAR22 = /^20[0-9]{2}$/;
|
|
6394
7401
|
var TERM = /^[0-9]{1,3}$/;
|
|
6395
|
-
var
|
|
6396
|
-
var
|
|
6397
|
-
var
|
|
7402
|
+
var record35 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
7403
|
+
var own16 = (value, key) => Object.prototype.hasOwnProperty.call(value, key);
|
|
7404
|
+
var inOrder8 = (value, keys) => {
|
|
6398
7405
|
let at = 0;
|
|
6399
7406
|
for (const name of Object.keys(value)) {
|
|
6400
7407
|
while (at < keys.length && keys[at] !== name)
|
|
@@ -6405,18 +7412,18 @@ var inOrder7 = (value, keys) => {
|
|
|
6405
7412
|
}
|
|
6406
7413
|
return true;
|
|
6407
7414
|
};
|
|
6408
|
-
var
|
|
6409
|
-
var
|
|
7415
|
+
var refuse41 = (code) => Object.freeze({ verdict: "refuse", code });
|
|
7416
|
+
var CARD41 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
|
|
6410
7417
|
function isMidtransTokenUrl(url) {
|
|
6411
7418
|
return url === MIDTRANS_TOKEN_URL || url === MIDTRANS_SANDBOX_TOKEN_URL;
|
|
6412
7419
|
}
|
|
6413
|
-
function
|
|
6414
|
-
if (typeof body !== "string" || body === "" || body.length >
|
|
7420
|
+
function readBody25(body) {
|
|
7421
|
+
if (typeof body !== "string" || body === "" || body.length > BODY_LIMIT39)
|
|
6415
7422
|
return null;
|
|
6416
7423
|
let value;
|
|
6417
7424
|
try {
|
|
6418
7425
|
value = JSON.parse(body);
|
|
6419
|
-
if (!
|
|
7426
|
+
if (!record35(value) || JSON.stringify(value) !== body)
|
|
6420
7427
|
return null;
|
|
6421
7428
|
}
|
|
6422
7429
|
catch {
|
|
@@ -6425,20 +7432,20 @@ function readBody23(body) {
|
|
|
6425
7432
|
return value;
|
|
6426
7433
|
}
|
|
6427
7434
|
function midtransBodyVerdict(body) {
|
|
6428
|
-
const value =
|
|
6429
|
-
if (value === null || !
|
|
6430
|
-
if (
|
|
6431
|
-
return
|
|
6432
|
-
return
|
|
6433
|
-
}
|
|
6434
|
-
if (!
|
|
6435
|
-
return
|
|
6436
|
-
}
|
|
6437
|
-
if (typeof value.card_cvv !== "string" || !
|
|
6438
|
-
return
|
|
6439
|
-
if (
|
|
6440
|
-
return
|
|
6441
|
-
return
|
|
7435
|
+
const value = readBody25(body);
|
|
7436
|
+
if (value === null || !inOrder8(value, MIDTRANS_TOKEN_KEYS)) {
|
|
7437
|
+
if (record35(value) && (own16(value, "token_id") || own16(value, "two_click")) && !own16(value, "card_number"))
|
|
7438
|
+
return refuse41("midtrans_saved_card");
|
|
7439
|
+
return refuse41("midtrans_body_unsupported");
|
|
7440
|
+
}
|
|
7441
|
+
if (!own16(value, "card_cvv") || !own16(value, "card_number") || !own16(value, "card_exp_month") || !own16(value, "card_exp_year")) {
|
|
7442
|
+
return refuse41("midtrans_body_unsupported");
|
|
7443
|
+
}
|
|
7444
|
+
if (typeof value.card_cvv !== "string" || !SECURITY_CODE25.test(value.card_cvv) || typeof value.card_number !== "string" || !CARD_NUMBER21.test(value.card_number) || typeof value.card_exp_month !== "string" || !MONTH21.test(value.card_exp_month) || typeof value.card_exp_year !== "string" || !YEAR22.test(value.card_exp_year))
|
|
7445
|
+
return refuse41("midtrans_body_unsupported");
|
|
7446
|
+
if (own16(value, "installment_term") && (typeof value.installment_term !== "string" || !TERM.test(value.installment_term)))
|
|
7447
|
+
return refuse41("midtrans_body_unsupported");
|
|
7448
|
+
return CARD41;
|
|
6442
7449
|
}
|
|
6443
7450
|
var midtrans_default = /* @__PURE__ */ registerProcessor({
|
|
6444
7451
|
psp: MIDTRANS_PSP,
|
|
@@ -6456,18 +7463,111 @@ var midtrans_default = /* @__PURE__ */ registerProcessor({
|
|
|
6456
7463
|
sandboxHosts: ["^api\\.sandbox\\.midtrans\\.com$"],
|
|
6457
7464
|
hostEnvironmentPinned: true,
|
|
6458
7465
|
encoding: "json",
|
|
6459
|
-
// Snap's own headers: the publishable client key (Authorization Basic) and X-Service. Origin, Referer and
|
|
6460
|
-
// cookies never ride.
|
|
6461
|
-
passthroughHeaders: ["^authorization$", "^x-service$"],
|
|
6462
|
-
jsonCardFields: [["card_number"]]
|
|
7466
|
+
// Snap's own headers: the publishable client key (Authorization Basic) and X-Service. Origin, Referer and
|
|
7467
|
+
// cookies never ride.
|
|
7468
|
+
passthroughHeaders: ["^authorization$", "^x-service$"],
|
|
7469
|
+
jsonCardFields: [["card_number"]]
|
|
7470
|
+
}
|
|
7471
|
+
],
|
|
7472
|
+
// Only the cardholder's device sends a token, after a person approves; no reviewed list names midtrans.
|
|
7473
|
+
refusedOperations: [MIDTRANS_OPERATION],
|
|
7474
|
+
// Not surveyed: the token moves no money, and the merchant's own charge names its status by the order id alone.
|
|
7475
|
+
settlementReadback: "not_surveyed",
|
|
7476
|
+
exactUrl: isMidtransTokenUrl,
|
|
7477
|
+
bodyGate: (url, body) => url !== void 0 && !isMidtransTokenUrl(url) ? { verdict: "refuse", code: "midtrans_url_refused" } : midtransBodyVerdict(body)
|
|
7478
|
+
});
|
|
7479
|
+
// src/processors/monei.js
|
|
7480
|
+
var MONEI_PSP = "monei";
|
|
7481
|
+
var MONEI_OPERATION = "monei.card_request";
|
|
7482
|
+
var MONEI_TOKENS_URL = "https://api.monei.com/v1/tokens";
|
|
7483
|
+
var BODY_LIMIT40 = 1024;
|
|
7484
|
+
var PAYMENT_ID = /^(?:[0-9a-f]{32}|[0-9a-f]{40})$/;
|
|
7485
|
+
var MONEI_CARD_KEYS = /* @__PURE__ */ Object.freeze(["number", "expMonth", "expYear", "cvc"]);
|
|
7486
|
+
var NUMBER8 = /^[0-9]{12,19}$/;
|
|
7487
|
+
var MONTH22 = /^(?:0[1-9]|1[0-2])$/;
|
|
7488
|
+
var YEAR23 = /^[0-9]{2}$/;
|
|
7489
|
+
var CODE8 = /^[0-9]{3,4}$/;
|
|
7490
|
+
var record36 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
7491
|
+
var keysAre2 = (value, keys) => {
|
|
7492
|
+
const found = Object.keys(value);
|
|
7493
|
+
return found.length === keys.length && found.every((key, at) => key === keys[at]);
|
|
7494
|
+
};
|
|
7495
|
+
var refuse42 = (code) => Object.freeze({ verdict: "refuse", code });
|
|
7496
|
+
var CARD42 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
|
|
7497
|
+
function luhn10(digits4) {
|
|
7498
|
+
let sum = 0;
|
|
7499
|
+
for (let at = 0; at < digits4.length; at += 1) {
|
|
7500
|
+
let digit = Number(digits4[digits4.length - 1 - at]);
|
|
7501
|
+
if (at % 2 === 1) {
|
|
7502
|
+
digit *= 2;
|
|
7503
|
+
if (digit > 9)
|
|
7504
|
+
digit -= 9;
|
|
7505
|
+
}
|
|
7506
|
+
sum += digit;
|
|
7507
|
+
}
|
|
7508
|
+
return sum % 10 === 0;
|
|
7509
|
+
}
|
|
7510
|
+
function isMoneiTokensUrl(url) {
|
|
7511
|
+
return url === MONEI_TOKENS_URL;
|
|
7512
|
+
}
|
|
7513
|
+
function readBody26(body) {
|
|
7514
|
+
if (typeof body !== "string" || body === "" || body.length > BODY_LIMIT40)
|
|
7515
|
+
return null;
|
|
7516
|
+
try {
|
|
7517
|
+
const value = JSON.parse(body);
|
|
7518
|
+
return record36(value) && JSON.stringify(value) === body ? value : null;
|
|
7519
|
+
}
|
|
7520
|
+
catch {
|
|
7521
|
+
return null;
|
|
7522
|
+
}
|
|
7523
|
+
}
|
|
7524
|
+
function moneiBodyVerdict(body, url) {
|
|
7525
|
+
if (url !== void 0 && !isMoneiTokensUrl(url))
|
|
7526
|
+
return refuse42("monei_url_refused");
|
|
7527
|
+
const value = readBody26(body);
|
|
7528
|
+
if (value === null || !keysAre2(value, ["paymentId", "paymentMethod"]) || typeof value.paymentId !== "string" || !PAYMENT_ID.test(value.paymentId))
|
|
7529
|
+
return refuse42("monei_body_unsupported");
|
|
7530
|
+
const method = value.paymentMethod;
|
|
7531
|
+
if (!record36(method) || !keysAre2(method, ["card"]) || !record36(method.card) || !keysAre2(method.card, MONEI_CARD_KEYS))
|
|
7532
|
+
return refuse42("monei_body_unsupported");
|
|
7533
|
+
const { number, expMonth, expYear, cvc } = method.card;
|
|
7534
|
+
if (![number, expMonth, expYear, cvc].every((part) => typeof part === "string"))
|
|
7535
|
+
return refuse42("monei_body_unsupported");
|
|
7536
|
+
if (!NUMBER8.test(number) || !luhn10(number) || !MONTH22.test(expMonth) || !YEAR23.test(expYear) || !CODE8.test(cvc))
|
|
7537
|
+
return refuse42("monei_body_unsupported");
|
|
7538
|
+
return CARD42;
|
|
7539
|
+
}
|
|
7540
|
+
var MONEI_MERCHANT_PINS = /* @__PURE__ */ Object.freeze([
|
|
7541
|
+
Object.freeze({ merchant: "Genuins", accountIds: Object.freeze(["8d58ab4c-4ad0-4053-b18f-79d80e9ee158"]), merchantUrls: Object.freeze(["https://genuins.com/"]) })
|
|
7542
|
+
]);
|
|
7543
|
+
var monei_default = /* @__PURE__ */ registerProcessor({
|
|
7544
|
+
psp: MONEI_PSP,
|
|
7545
|
+
definitions: [
|
|
7546
|
+
{
|
|
7547
|
+
psp: "monei",
|
|
7548
|
+
// The card frame's token request, as the header above reads it. One host serves test and live payments alike,
|
|
7549
|
+
// so no sandbox host is marked: MONEI's record of the payment names its mode, and the device sends a test payment
|
|
7550
|
+
// only MONEI's documented test cards (moneiDeviceRefusal). The frame sets no deadline on the fetch, so the
|
|
7551
|
+
// cardholder approves at the shopper's Pay. `(?![\w/.%-])` ends the path for a consumer that tests `match`
|
|
7552
|
+
// unanchored, and the exact-URL rule below holds the rest. Ships dark: served only to a client that declares
|
|
7553
|
+
// `monei_card_token`, and gated off for every company until the backend's gate names one.
|
|
7554
|
+
capability: "monei_card_token",
|
|
7555
|
+
match: "api\\.monei\\.com/v1/tokens(?![\\w/.%-])",
|
|
7556
|
+
hosts: ["^api\\.monei\\.com$"],
|
|
7557
|
+
encoding: "json",
|
|
7558
|
+
// The frame's two device headers. Origin, Referer and cookies never ride.
|
|
7559
|
+
passthroughHeaders: ["^x-client-env$", "^x-client-fingerprint$"],
|
|
7560
|
+
jsonCardFields: [["paymentMethod", "card", "number"]]
|
|
6463
7561
|
}
|
|
6464
7562
|
],
|
|
6465
|
-
// Only the cardholder's device sends a
|
|
6466
|
-
refusedOperations: [
|
|
6467
|
-
// Not surveyed: the token moves no money
|
|
7563
|
+
// Only the cardholder's device sends a card, after a person approves; no reviewed list names monei.
|
|
7564
|
+
refusedOperations: [MONEI_OPERATION],
|
|
7565
|
+
// Not surveyed: the card request mints a token and moves no money; MONEI's confirm, which the page sends, charges it.
|
|
6468
7566
|
settlementReadback: "not_surveyed",
|
|
6469
|
-
exactUrl:
|
|
6470
|
-
bodyGate: (url, body) =>
|
|
7567
|
+
exactUrl: isMoneiTokensUrl,
|
|
7568
|
+
bodyGate: (url, body) => moneiBodyVerdict(body, url)
|
|
7569
|
+
// No amount reader: the request names none. MONEI's record of the payment names it, and the device holds that record
|
|
7570
|
+
// to the approved amount before it writes any card.
|
|
6471
7571
|
});
|
|
6472
7572
|
// src/processors/oceanpayment.js
|
|
6473
7573
|
var OCEANPAYMENT_PSP = "oceanpayment";
|
|
@@ -6498,10 +7598,10 @@ var OCEANPAYMENT_FORM_FIELDS = /* @__PURE__ */ Object.freeze([
|
|
|
6498
7598
|
"methods",
|
|
6499
7599
|
"reference"
|
|
6500
7600
|
]);
|
|
6501
|
-
var
|
|
6502
|
-
var
|
|
7601
|
+
var URL_LIMIT16 = 2048;
|
|
7602
|
+
var BODY_LIMIT41 = 8192;
|
|
6503
7603
|
var SEND_PAY = /^\/gateway\/sendPay;jsessionid=[A-Za-z0-9._!-]{16,128}$/;
|
|
6504
|
-
var
|
|
7604
|
+
var own17 = (value, key) => Object.prototype.hasOwnProperty.call(value, key);
|
|
6505
7605
|
var exact4 = (pattern, value) => typeof value === "string" && pattern.test(value);
|
|
6506
7606
|
var CARD_RUN = /[0-9]{12}/;
|
|
6507
7607
|
var printable5 = (max) => (value) => typeof value === "string" && value.length <= max && /^[\x20-\x7e]*$/.test(value) && !CARD_RUN.test(value);
|
|
@@ -6539,7 +7639,7 @@ var SHAPES2 = /* @__PURE__ */ new Map([
|
|
|
6539
7639
|
["button", (v) => v === ""]
|
|
6540
7640
|
]);
|
|
6541
7641
|
function oceanpaymentSendPayUrl(url) {
|
|
6542
|
-
if (typeof url !== "string" || url.length >
|
|
7642
|
+
if (typeof url !== "string" || url.length > URL_LIMIT16 || url.includes("?") || url.includes("#"))
|
|
6543
7643
|
return null;
|
|
6544
7644
|
let parsed;
|
|
6545
7645
|
try {
|
|
@@ -6548,7 +7648,7 @@ function oceanpaymentSendPayUrl(url) {
|
|
|
6548
7648
|
catch {
|
|
6549
7649
|
return null;
|
|
6550
7650
|
}
|
|
6551
|
-
if (parsed.href !== url || parsed.protocol !== "https:" || parsed.port || parsed.username || parsed.password || !
|
|
7651
|
+
if (parsed.href !== url || parsed.protocol !== "https:" || parsed.port || parsed.username || parsed.password || !own17(OCEANPAYMENT_HOSTS, parsed.hostname) || !SEND_PAY.test(parsed.pathname))
|
|
6552
7652
|
return null;
|
|
6553
7653
|
return Object.freeze({ host: parsed.hostname, environment: OCEANPAYMENT_HOSTS[parsed.hostname] });
|
|
6554
7654
|
}
|
|
@@ -6576,7 +7676,7 @@ function formDecode2(raw) {
|
|
|
6576
7676
|
return formEncode3(value) === raw ? value : null;
|
|
6577
7677
|
}
|
|
6578
7678
|
function readPairs2(body) {
|
|
6579
|
-
if (typeof body !== "string" || body === "" || body.length >
|
|
7679
|
+
if (typeof body !== "string" || body === "" || body.length > BODY_LIMIT41)
|
|
6580
7680
|
return null;
|
|
6581
7681
|
const pairs = [];
|
|
6582
7682
|
for (const chunk of body.split("&")) {
|
|
@@ -6661,7 +7761,7 @@ var PAYMENTWALL_PSP = "paymentwall";
|
|
|
6661
7761
|
var PAYMENTWALL_OPERATION = "paymentwall.card_request";
|
|
6662
7762
|
var PAYMENTWALL_TOKEN_URL = "https://pwgateway.com/api/token";
|
|
6663
7763
|
var PAYMENTWALL_SANDBOX_TOKEN_URL = "https://api.paymentwall.com/api/brick/token";
|
|
6664
|
-
var
|
|
7764
|
+
var BODY_LIMIT42 = 2048;
|
|
6665
7765
|
var KEY3 = "public_key";
|
|
6666
7766
|
var PUBLIC_KEY2 = /^(?:t_)?[A-Za-z0-9]{16,64}$/;
|
|
6667
7767
|
var SHAPES3 = /* @__PURE__ */ Object.freeze({
|
|
@@ -6671,9 +7771,9 @@ var SHAPES3 = /* @__PURE__ */ Object.freeze({
|
|
|
6671
7771
|
"card[exp_year]": /^(?:[0-9]{2}|20[0-9]{2})$/,
|
|
6672
7772
|
"card[cvv]": /^[0-9]{3,4}$/
|
|
6673
7773
|
});
|
|
6674
|
-
var
|
|
6675
|
-
var
|
|
6676
|
-
function
|
|
7774
|
+
var refuse43 = (code) => Object.freeze({ verdict: "refuse", code });
|
|
7775
|
+
var CARD43 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
|
|
7776
|
+
function luhn11(digits4) {
|
|
6677
7777
|
let sum = 0;
|
|
6678
7778
|
for (let at = 0; at < digits4.length; at += 1) {
|
|
6679
7779
|
let digit = Number(digits4[digits4.length - 1 - at]);
|
|
@@ -6700,7 +7800,7 @@ function paymentwallKeyEnvironment(publicKey) {
|
|
|
6700
7800
|
return publicKey.startsWith("t_") ? "sandbox" : "production";
|
|
6701
7801
|
}
|
|
6702
7802
|
function readPairs3(body) {
|
|
6703
|
-
if (typeof body !== "string" || body === "" || body.length >
|
|
7803
|
+
if (typeof body !== "string" || body === "" || body.length > BODY_LIMIT42 || !/^[A-Za-z0-9_[\]=&]+$/.test(body))
|
|
6704
7804
|
return null;
|
|
6705
7805
|
const pairs = /* @__PURE__ */ new Map();
|
|
6706
7806
|
for (const chunk of body.split("&")) {
|
|
@@ -6716,21 +7816,21 @@ function readPairs3(body) {
|
|
|
6716
7816
|
}
|
|
6717
7817
|
function paymentwallBodyVerdict(body, url) {
|
|
6718
7818
|
if (url !== void 0 && !isPaymentwallTokenUrl(url))
|
|
6719
|
-
return
|
|
7819
|
+
return refuse43("paymentwall_url_refused");
|
|
6720
7820
|
const pairs = readPairs3(body);
|
|
6721
7821
|
if (pairs === null)
|
|
6722
|
-
return
|
|
7822
|
+
return refuse43("paymentwall_body_unsupported");
|
|
6723
7823
|
if (pairs.has("card[token]") && !pairs.has("card[number]"))
|
|
6724
|
-
return
|
|
7824
|
+
return refuse43("paymentwall_saved_card");
|
|
6725
7825
|
const keys = Object.keys(SHAPES3);
|
|
6726
7826
|
if (pairs.size !== keys.length || !keys.every((key) => pairs.has(key) && SHAPES3[key].test(pairs.get(key)))) {
|
|
6727
|
-
return
|
|
7827
|
+
return refuse43("paymentwall_body_unsupported");
|
|
6728
7828
|
}
|
|
6729
|
-
if (!
|
|
6730
|
-
return
|
|
7829
|
+
if (!luhn11(pairs.get("card[number]")))
|
|
7830
|
+
return refuse43("paymentwall_body_unsupported");
|
|
6731
7831
|
if (url !== void 0 && paymentwallKeyEnvironment(pairs.get(KEY3)) !== paymentwallUrlEnvironment(url))
|
|
6732
|
-
return
|
|
6733
|
-
return
|
|
7832
|
+
return refuse43("paymentwall_key_refused");
|
|
7833
|
+
return CARD43;
|
|
6734
7834
|
}
|
|
6735
7835
|
var paymentwall_default = /* @__PURE__ */ registerProcessor({
|
|
6736
7836
|
psp: PAYMENTWALL_PSP,
|
|
@@ -6759,112 +7859,15 @@ var paymentwall_default = /* @__PURE__ */ registerProcessor({
|
|
|
6759
7859
|
exactUrl: isPaymentwallTokenUrl,
|
|
6760
7860
|
bodyGate: (url, body) => paymentwallBodyVerdict(body, url)
|
|
6761
7861
|
});
|
|
6762
|
-
// src/processors/ekashu.js
|
|
6763
|
-
var EKASHU_HOSTS = Object.freeze(["live.ekashu.com", "test.ekashu.com"]);
|
|
6764
|
-
var EKASHU_TEST_PANS = Object.freeze(["4100000000000100", "5100000000000107"]);
|
|
6765
|
-
var EKASHU_SIGNED_FIELDS = Object.freeze([
|
|
6766
|
-
"ekashu_3d_secure_verify",
|
|
6767
|
-
"ekashu_amount",
|
|
6768
|
-
"ekashu_amount_format",
|
|
6769
|
-
"ekashu_auto_confirm",
|
|
6770
|
-
"ekashu_callback_failure_url",
|
|
6771
|
-
"ekashu_callback_include_post",
|
|
6772
|
-
"ekashu_callback_success_url",
|
|
6773
|
-
"ekashu_card_address_editable",
|
|
6774
|
-
"ekashu_card_address_required",
|
|
6775
|
-
"ekashu_card_address_verify",
|
|
6776
|
-
"ekashu_card_email_address_mandatory",
|
|
6777
|
-
"ekashu_card_phone_number_mandatory",
|
|
6778
|
-
"ekashu_card_title_mandatory",
|
|
6779
|
-
"ekashu_card_zip_code_verify",
|
|
6780
|
-
"ekashu_currency",
|
|
6781
|
-
"ekashu_delivery_address_editable",
|
|
6782
|
-
"ekashu_delivery_address_required",
|
|
6783
|
-
"ekashu_delivery_email_address_mandatory",
|
|
6784
|
-
"ekashu_delivery_phone_number_mandatory",
|
|
6785
|
-
"ekashu_delivery_title_mandatory",
|
|
6786
|
-
"ekashu_description",
|
|
6787
|
-
"ekashu_device",
|
|
6788
|
-
"ekashu_duplicate_check",
|
|
6789
|
-
"ekashu_duplicate_minutes",
|
|
6790
|
-
"ekashu_failure_return_text",
|
|
6791
|
-
"ekashu_failure_url",
|
|
6792
|
-
"ekashu_hash_code_format",
|
|
6793
|
-
"ekashu_hash_code_type",
|
|
6794
|
-
"ekashu_hash_code_version",
|
|
6795
|
-
"ekashu_include_post",
|
|
6796
|
-
"ekashu_invoice_address_editable",
|
|
6797
|
-
"ekashu_invoice_address_required",
|
|
6798
|
-
"ekashu_invoice_email_address_mandatory",
|
|
6799
|
-
"ekashu_invoice_phone_number_mandatory",
|
|
6800
|
-
"ekashu_invoice_title_mandatory",
|
|
6801
|
-
"ekashu_locale",
|
|
6802
|
-
"ekashu_payment_methods",
|
|
6803
|
-
"ekashu_reference",
|
|
6804
|
-
"ekashu_request_type",
|
|
6805
|
-
"ekashu_return_text",
|
|
6806
|
-
"ekashu_seller_address",
|
|
6807
|
-
"ekashu_seller_email_address",
|
|
6808
|
-
"ekashu_seller_id",
|
|
6809
|
-
"ekashu_seller_key",
|
|
6810
|
-
"ekashu_seller_name",
|
|
6811
|
-
"ekashu_shortcut_icon",
|
|
6812
|
-
"ekashu_style_sheet",
|
|
6813
|
-
"ekashu_success_url",
|
|
6814
|
-
"ekashu_title",
|
|
6815
|
-
"ekashu_verification_value_mask",
|
|
6816
|
-
"ekashu_verification_value_verify",
|
|
6817
|
-
"ekashu_viewport"
|
|
6818
|
-
]);
|
|
6819
|
-
var REQUIRED = Object.freeze([
|
|
6820
|
-
"ekashu_seller_id",
|
|
6821
|
-
"ekashu_seller_key",
|
|
6822
|
-
"ekashu_amount",
|
|
6823
|
-
"ekashu_currency",
|
|
6824
|
-
"ekashu_reference",
|
|
6825
|
-
"ekashu_hash_code",
|
|
6826
|
-
"ekashu_hash_code_type",
|
|
6827
|
-
"ekashu_hash_code_version",
|
|
6828
|
-
"ekashu_success_url",
|
|
6829
|
-
"ekashu_failure_url",
|
|
6830
|
-
"ekashu_callback_success_url"
|
|
6831
|
-
]);
|
|
6832
|
-
var CARD_KEYS16 = Object.freeze([
|
|
6833
|
-
"ekashu_card_number",
|
|
6834
|
-
"ekashu_expires_end_month",
|
|
6835
|
-
"ekashu_expires_end_year",
|
|
6836
|
-
"ekashu_verification_value",
|
|
6837
|
-
"ekashu_valid_from_month",
|
|
6838
|
-
"ekashu_valid_from_year",
|
|
6839
|
-
"ekashu_issue_number"
|
|
6840
|
-
]);
|
|
6841
|
-
var PAGE_KEYS = Object.freeze(["ekashu_stage", "ekashu_context", "ekashu_submission_id"]);
|
|
6842
|
-
var STORED_KEYS = Object.freeze(["ekashu_card_hash", "ekashu_card_reference", "ekashu_cof_initiated_by", "ekashu_cof_reason", "ekashu_cof_id"]);
|
|
6843
|
-
var REDIRECT_KEYS = Object.freeze(["ekashu_success_url", "ekashu_failure_url", "ekashu_return_url"]);
|
|
6844
|
-
var CALLBACK_KEYS = Object.freeze(["ekashu_callback_success_url", "ekashu_callback_failure_url"]);
|
|
6845
|
-
var MAX_ENTRY = 16 * 1024;
|
|
6846
|
-
var MAX_PAGE = 256 * 1024;
|
|
6847
|
-
var EKASHU_SELLERS = Object.freeze([
|
|
6848
|
-
Object.freeze({ sellerId: "25060100", merchant: "Heathrow Drop-off", entryHost: "heathrowdropoff.apcoa.com", callbackHost: "incomingapi.apcoa.co.uk" })
|
|
6849
|
-
]);
|
|
6850
|
-
var CARD_FIELDS = Object.freeze({
|
|
6851
|
-
number: "ekashu_card_number",
|
|
6852
|
-
month: "ekashu_expires_end_month",
|
|
6853
|
-
year: "ekashu_expires_end_year",
|
|
6854
|
-
cvc: "ekashu_verification_value"
|
|
6855
|
-
});
|
|
6856
|
-
var NAME_FIELDS = Object.freeze({ first: "ekashu_card_first_name", last: "ekashu_card_last_name" });
|
|
6857
|
-
var LEFT_EMPTY = Object.freeze(["ekashu_card_title", "ekashu_valid_from_month", "ekashu_valid_from_year", "ekashu_issue_number"]);
|
|
6858
|
-
var VISIBLE = /* @__PURE__ */ new Set([...Object.values(CARD_FIELDS), ...Object.values(NAME_FIELDS), ...LEFT_EMPTY]);
|
|
6859
7862
|
// src/processors/payplug.js
|
|
6860
7863
|
var PAYPLUG_PSP = "payplug";
|
|
6861
7864
|
var PAYPLUG_OPERATION = "payplug.hosted_sale";
|
|
6862
7865
|
var PAYPLUG_HOST = "secure.payplug.com";
|
|
6863
7866
|
var ENTRY_PATH = /^\/pay\/(?:(test)\/)?([A-Za-z0-9]{22})$/;
|
|
6864
|
-
var
|
|
6865
|
-
var
|
|
7867
|
+
var MAX_URL3 = 256;
|
|
7868
|
+
var field4 = (name, reason) => ({ ok: false, code: "hosted_form_field_refused", field: name, reason });
|
|
6866
7869
|
function payplugEntry(raw) {
|
|
6867
|
-
if (typeof raw !== "string" || raw.length >
|
|
7870
|
+
if (typeof raw !== "string" || raw.length > MAX_URL3 || raw.includes("?") || raw.includes("#"))
|
|
6868
7871
|
return null;
|
|
6869
7872
|
let url;
|
|
6870
7873
|
try {
|
|
@@ -6886,7 +7889,7 @@ var PAYPLUG_MERCHANTS = Object.freeze([
|
|
|
6886
7889
|
]);
|
|
6887
7890
|
var ACCOUNT_ID = /^[A-Za-z0-9-]{1,64}$/;
|
|
6888
7891
|
function payplugMerchant(checkoutOrigin, merchants = PAYPLUG_MERCHANTS) {
|
|
6889
|
-
if (typeof checkoutOrigin !== "string" || checkoutOrigin.length >
|
|
7892
|
+
if (typeof checkoutOrigin !== "string" || checkoutOrigin.length > MAX_URL3 || !Array.isArray(merchants))
|
|
6890
7893
|
return null;
|
|
6891
7894
|
let url;
|
|
6892
7895
|
try {
|
|
@@ -6902,16 +7905,16 @@ function payplugMerchant(checkoutOrigin, merchants = PAYPLUG_MERCHANTS) {
|
|
|
6902
7905
|
}
|
|
6903
7906
|
function checkPayplugEntry(body, { url = null, checkoutOrigin = null, merchants = PAYPLUG_MERCHANTS } = {}) {
|
|
6904
7907
|
if (body !== void 0 && body !== null && body !== "")
|
|
6905
|
-
return
|
|
7908
|
+
return field4("(body)", "not_an_entry");
|
|
6906
7909
|
const entry = payplugEntry(url);
|
|
6907
7910
|
if (!entry)
|
|
6908
|
-
return
|
|
7911
|
+
return field4("(url)", "malformed_field");
|
|
6909
7912
|
const seller = payplugMerchant(checkoutOrigin, merchants);
|
|
6910
7913
|
if (!seller)
|
|
6911
|
-
return
|
|
7914
|
+
return field4("(checkout_origin)", "seller_unreviewed");
|
|
6912
7915
|
return { ok: true, pairs: [], gated: false, dedupe: [entry.id], paymentId: entry.id, sandbox: entry.test, seller };
|
|
6913
7916
|
}
|
|
6914
|
-
var
|
|
7917
|
+
var MAX_PAGE5 = 512 * 1024;
|
|
6915
7918
|
var PAYPLUG_REFUSALS = Object.freeze(["payplug_failed", "payplug_expired", "payplug_cancelled"]);
|
|
6916
7919
|
var payplug_default = /* @__PURE__ */ registerProcessor({
|
|
6917
7920
|
psp: PAYPLUG_PSP,
|
|
@@ -6961,11 +7964,129 @@ var payplug_default = /* @__PURE__ */ registerProcessor({
|
|
|
6961
7964
|
"PayPlug sends the buyer to the merchant's return page whether the payment succeeded or not, so the browser receives a submission notice, not the processor result."
|
|
6962
7965
|
]
|
|
6963
7966
|
});
|
|
7967
|
+
// src/processors/paystack.js
|
|
7968
|
+
var PAYSTACK_PSP = "paystack";
|
|
7969
|
+
var PAYSTACK_OPERATION = "paystack.card_request";
|
|
7970
|
+
var PAYSTACK_CHARGE_URL = "https://standard.paystack.co/charge/";
|
|
7971
|
+
var PAYSTACK_BODY_KEYS = /* @__PURE__ */ Object.freeze([
|
|
7972
|
+
"clientdata",
|
|
7973
|
+
"last4",
|
|
7974
|
+
"trans",
|
|
7975
|
+
"access_code",
|
|
7976
|
+
"device",
|
|
7977
|
+
"offset",
|
|
7978
|
+
"remember_card",
|
|
7979
|
+
"card_holder_name",
|
|
7980
|
+
"transaction_type"
|
|
7981
|
+
]);
|
|
7982
|
+
var OPTIONAL = /* @__PURE__ */ new Set(["access_code", "card_holder_name", "transaction_type"]);
|
|
7983
|
+
var BODY_LIMIT43 = 4096;
|
|
7984
|
+
var CIPHERTEXT_BYTES2 = [62, 63, 64];
|
|
7985
|
+
var BASE646 = /^[A-Za-z0-9+/]+={0,2}$/;
|
|
7986
|
+
var SHAPES4 = /* @__PURE__ */ Object.freeze({
|
|
7987
|
+
last4: /^[0-9]{4}$/,
|
|
7988
|
+
trans: /^[0-9]{1,20}$/,
|
|
7989
|
+
access_code: /^[A-Za-z0-9]{1,64}$/,
|
|
7990
|
+
device: /^[\x21-\x7e]{1,512}$/,
|
|
7991
|
+
offset: /^-?[0-9]{1,3}$/,
|
|
7992
|
+
remember_card: /^false$/,
|
|
7993
|
+
// A name carries no digit, so no card number can ride in it.
|
|
7994
|
+
card_holder_name: /^[^\x00-\x1f\x7f0-9]{1,128}$/u,
|
|
7995
|
+
transaction_type: /^[a-z_]{1,32}$/
|
|
7996
|
+
});
|
|
7997
|
+
var own18 = (value, key) => Object.prototype.hasOwnProperty.call(value, key);
|
|
7998
|
+
var refuse44 = (code) => Object.freeze({ verdict: "refuse", code });
|
|
7999
|
+
function paystackFormValue(value) {
|
|
8000
|
+
return encodeURIComponent(String(value)).replace(/%20/g, "+").replace(/[!'()*~]/g, (c) => `%${c.charCodeAt(0).toString(16).toUpperCase()}`);
|
|
8001
|
+
}
|
|
8002
|
+
function paystackFormBody(entries) {
|
|
8003
|
+
return entries.map(([key, value]) => `${paystackFormValue(key)}=${paystackFormValue(value)}`).join("&");
|
|
8004
|
+
}
|
|
8005
|
+
function isPaystackChargeUrl(url) {
|
|
8006
|
+
return url === PAYSTACK_CHARGE_URL;
|
|
8007
|
+
}
|
|
8008
|
+
function isCiphertext2(value) {
|
|
8009
|
+
if (value.length % 4 !== 0 || !BASE646.test(value))
|
|
8010
|
+
return false;
|
|
8011
|
+
let binary;
|
|
8012
|
+
try {
|
|
8013
|
+
binary = atob(value);
|
|
8014
|
+
}
|
|
8015
|
+
catch {
|
|
8016
|
+
return false;
|
|
8017
|
+
}
|
|
8018
|
+
return btoa(binary) === value && CIPHERTEXT_BYTES2.includes(binary.length);
|
|
8019
|
+
}
|
|
8020
|
+
function readForm3(body) {
|
|
8021
|
+
if (typeof body !== "string" || body === "" || body.length > BODY_LIMIT43)
|
|
8022
|
+
return null;
|
|
8023
|
+
const entries = [];
|
|
8024
|
+
for (const part of body.split("&")) {
|
|
8025
|
+
const at = part.indexOf("=");
|
|
8026
|
+
if (at <= 0)
|
|
8027
|
+
return null;
|
|
8028
|
+
try {
|
|
8029
|
+
entries.push([decodeURIComponent(part.slice(0, at).replace(/\+/g, " ")), decodeURIComponent(part.slice(at + 1).replace(/\+/g, " "))]);
|
|
8030
|
+
}
|
|
8031
|
+
catch {
|
|
8032
|
+
return null;
|
|
8033
|
+
}
|
|
8034
|
+
}
|
|
8035
|
+
return paystackFormBody(entries) === body ? entries : null;
|
|
8036
|
+
}
|
|
8037
|
+
function paystackBodyVerdict(body) {
|
|
8038
|
+
const entries = readForm3(body);
|
|
8039
|
+
if (entries === null)
|
|
8040
|
+
return refuse44("paystack_body_unsupported");
|
|
8041
|
+
const keys = entries.map(([key]) => key);
|
|
8042
|
+
if (keys.includes("subscription"))
|
|
8043
|
+
return refuse44("paystack_subscription");
|
|
8044
|
+
if (keys.includes("remember_card") && entries.find(([key]) => key === "remember_card")[1] !== "false")
|
|
8045
|
+
return refuse44("paystack_saved_card");
|
|
8046
|
+
const expected = PAYSTACK_BODY_KEYS.filter((key) => !OPTIONAL.has(key) || keys.includes(key));
|
|
8047
|
+
if (keys.length !== expected.length || keys.some((key, i) => key !== expected[i]))
|
|
8048
|
+
return refuse44("paystack_body_unsupported");
|
|
8049
|
+
const fields = Object.fromEntries(entries);
|
|
8050
|
+
if (!isCiphertext2(fields.clientdata))
|
|
8051
|
+
return refuse44("paystack_body_unsupported");
|
|
8052
|
+
for (const [key, shape] of Object.entries(SHAPES4)) {
|
|
8053
|
+
if (own18(fields, key) && !shape.test(fields[key]))
|
|
8054
|
+
return refuse44("paystack_body_unsupported");
|
|
8055
|
+
}
|
|
8056
|
+
return Object.freeze({ verdict: "card", fields: Object.freeze(fields) });
|
|
8057
|
+
}
|
|
8058
|
+
var paystack_default = /* @__PURE__ */ registerProcessor({
|
|
8059
|
+
psp: PAYSTACK_PSP,
|
|
8060
|
+
definitions: [
|
|
8061
|
+
{
|
|
8062
|
+
psp: "paystack",
|
|
8063
|
+
// The card page's charge, as the header above reads it. Live and test transactions share standard.paystack.co,
|
|
8064
|
+
// so no sandbox host is listed and no environment is pinned. Ships dark: served only to a client that declares
|
|
8065
|
+
// `paystack_pinned_key`, and only for a company the backend's processor gate turns Paystack on for.
|
|
8066
|
+
// `(?![\w/.%?#-])` ends the path for a consumer that tests `match` unanchored; the exact-URL rule takes no query.
|
|
8067
|
+
capability: "paystack_pinned_key",
|
|
8068
|
+
match: "standard\\.paystack\\.co/charge/(?![\\w/.%?#-])",
|
|
8069
|
+
hosts: ["^standard\\.paystack\\.co$"],
|
|
8070
|
+
encoding: "form",
|
|
8071
|
+
// The browser's language rides as the page sent it; Origin, Referer and cookies never do (the page sends no cookie).
|
|
8072
|
+
passthroughHeaders: ["^accept-language$"],
|
|
8073
|
+
cardFields: ["clientdata"]
|
|
8074
|
+
}
|
|
8075
|
+
],
|
|
8076
|
+
// Only the cardholder's device sends this charge, after a person approves; no reviewed list names paystack.
|
|
8077
|
+
refusedOperations: [PAYSTACK_OPERATION],
|
|
8078
|
+
// Not surveyed: reading a charge back takes the merchant's secret key, which Agentcard never holds.
|
|
8079
|
+
settlementReadback: "not_surveyed",
|
|
8080
|
+
exactUrl: isPaystackChargeUrl,
|
|
8081
|
+
bodyGate: (url, body) => url !== void 0 && !isPaystackChargeUrl(url) ? refuse44("paystack_url_refused") : paystackBodyVerdict(body),
|
|
8082
|
+
// No amount reader: the charge names none, so the agent's pair is the figure the cardholder approves.
|
|
8083
|
+
limitations: ["The charge names no merchant and no amount: Paystack's transaction binds both, so the cardholder approves the agent's figure for whichever Paystack merchant opened the checkout."]
|
|
8084
|
+
});
|
|
6964
8085
|
// src/processors/processout.js
|
|
6965
8086
|
var PROCESSOUT_PSP = "processout";
|
|
6966
8087
|
var PROCESSOUT_OPERATION = "processout.card_request";
|
|
6967
|
-
var
|
|
6968
|
-
var
|
|
8088
|
+
var URL_LIMIT17 = 512;
|
|
8089
|
+
var BODY_LIMIT44 = 4096;
|
|
6969
8090
|
var CARD_URL2 = /^https:\/\/api\.processout\.com\/cards\?legacyrequest=true&project_id=((?:test-)?proj_[A-Za-z0-9]{16,64})&x-Content-Type=application\/json&x-API-Version=1\.3\.0\.0&x-Authorization=Basic%20([A-Za-z0-9+/]{4,256}={0,2})$/;
|
|
6970
8091
|
var PAGE_KEYS2 = /* @__PURE__ */ Object.freeze(["name", "contact", "preferred_scheme"]);
|
|
6971
8092
|
var CONTACT_KEYS = /* @__PURE__ */ Object.freeze(["address1", "address2", "city", "state", "country_code", "zip"]);
|
|
@@ -6980,31 +8101,31 @@ var DEVICE_KEYS4 = /* @__PURE__ */ Object.freeze([
|
|
|
6980
8101
|
]);
|
|
6981
8102
|
var PROCESSOUT_CARD_KEYS = /* @__PURE__ */ Object.freeze(["number", "exp_month", "exp_year", "cvc2"]);
|
|
6982
8103
|
var BODY_KEYS3 = /* @__PURE__ */ new Set([...PAGE_KEYS2, "device", ...DEVICE_KEYS4, ...PROCESSOUT_CARD_KEYS]);
|
|
6983
|
-
var
|
|
6984
|
-
var
|
|
6985
|
-
var
|
|
6986
|
-
var
|
|
8104
|
+
var NUMBER9 = /^[0-9]{12,19}$/;
|
|
8105
|
+
var MONTH23 = /^(?:[1-9]|1[0-2])$/;
|
|
8106
|
+
var YEAR24 = /^20[0-9]{2}$/;
|
|
8107
|
+
var CODE9 = /^[0-9]{3,4}$/;
|
|
6987
8108
|
var TEXT_LIMIT14 = 256;
|
|
6988
8109
|
var SCHEME = /^[A-Za-z][A-Za-z0-9 _-]{0,31}$/;
|
|
6989
8110
|
var LANGUAGE5 = /^[A-Za-z]{1,8}(?:-[A-Za-z0-9]{1,8}){0,4}$/;
|
|
6990
8111
|
var PAN_LIKE7 = /(?:[0-9][^0-9A-Za-z]*){12,}/;
|
|
6991
|
-
var
|
|
6992
|
-
var
|
|
6993
|
-
var
|
|
6994
|
-
var
|
|
6995
|
-
var
|
|
6996
|
-
function base64Of(
|
|
8112
|
+
var record37 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
8113
|
+
var own19 = (value, key) => Object.prototype.hasOwnProperty.call(value, key);
|
|
8114
|
+
var refuse45 = (code) => Object.freeze({ verdict: "refuse", code });
|
|
8115
|
+
var CARD44 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
|
|
8116
|
+
var BASE647 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
8117
|
+
function base64Of(text11) {
|
|
6997
8118
|
let out = "";
|
|
6998
|
-
for (let at = 0; at <
|
|
6999
|
-
const a =
|
|
7000
|
-
const b = at + 1 <
|
|
7001
|
-
const c = at + 2 <
|
|
7002
|
-
out +=
|
|
8119
|
+
for (let at = 0; at < text11.length; at += 3) {
|
|
8120
|
+
const a = text11.charCodeAt(at);
|
|
8121
|
+
const b = at + 1 < text11.length ? text11.charCodeAt(at + 1) : NaN;
|
|
8122
|
+
const c = at + 2 < text11.length ? text11.charCodeAt(at + 2) : NaN;
|
|
8123
|
+
out += BASE647[a >> 2] + BASE647[(a & 3) << 4 | (Number.isNaN(b) ? 0 : b >> 4)] + (Number.isNaN(b) ? "=" : BASE647[(b & 15) << 2 | (Number.isNaN(c) ? 0 : c >> 6)]) + (Number.isNaN(c) ? "=" : BASE647[c & 63]);
|
|
7003
8124
|
}
|
|
7004
8125
|
return out;
|
|
7005
8126
|
}
|
|
7006
8127
|
var basicOf = (projectId) => base64Of(`${projectId}:`);
|
|
7007
|
-
function
|
|
8128
|
+
function luhn12(digits4) {
|
|
7008
8129
|
let sum = 0;
|
|
7009
8130
|
for (let at = 0; at < digits4.length; at += 1) {
|
|
7010
8131
|
let digit = Number(digits4[digits4.length - 1 - at]);
|
|
@@ -7018,7 +8139,7 @@ function luhn10(digits4) {
|
|
|
7018
8139
|
return sum % 10 === 0;
|
|
7019
8140
|
}
|
|
7020
8141
|
function processoutCardTarget(url) {
|
|
7021
|
-
if (typeof url !== "string" || url.length >
|
|
8142
|
+
if (typeof url !== "string" || url.length > URL_LIMIT17)
|
|
7022
8143
|
return null;
|
|
7023
8144
|
const match = CARD_URL2.exec(url);
|
|
7024
8145
|
if (!match || match[2] !== basicOf(match[1]))
|
|
@@ -7028,12 +8149,12 @@ function processoutCardTarget(url) {
|
|
|
7028
8149
|
function isProcessoutCardUrl(url) {
|
|
7029
8150
|
return processoutCardTarget(url) !== null;
|
|
7030
8151
|
}
|
|
7031
|
-
function
|
|
7032
|
-
if (typeof body !== "string" || body === "" || body.length >
|
|
8152
|
+
function readBody27(body) {
|
|
8153
|
+
if (typeof body !== "string" || body === "" || body.length > BODY_LIMIT44)
|
|
7033
8154
|
return null;
|
|
7034
8155
|
try {
|
|
7035
8156
|
const value = JSON.parse(body);
|
|
7036
|
-
return
|
|
8157
|
+
return record37(value) && JSON.stringify(value) === body ? value : null;
|
|
7037
8158
|
}
|
|
7038
8159
|
catch {
|
|
7039
8160
|
return null;
|
|
@@ -7051,31 +8172,31 @@ var DEVICE_RULES = /* @__PURE__ */ Object.freeze({
|
|
|
7051
8172
|
});
|
|
7052
8173
|
function soundDevice3(value) {
|
|
7053
8174
|
const device = value.device;
|
|
7054
|
-
if (!
|
|
8175
|
+
if (!record37(device) || !own19(device, "request_origin") || !own19(device, "app_timezone_offset"))
|
|
7055
8176
|
return false;
|
|
7056
|
-
return DEVICE_KEYS4.every((key) =>
|
|
8177
|
+
return DEVICE_KEYS4.every((key) => own19(device, key) ? DEVICE_RULES[key](device[key]) && own19(value, key) && value[key] === device[key] : !own19(value, key)) && Object.keys(device).every((key) => DEVICE_KEYS4.includes(key));
|
|
7057
8178
|
}
|
|
7058
8179
|
function soundPageData(value) {
|
|
7059
|
-
if (
|
|
8180
|
+
if (own19(value, "name") && !pageText2(value.name))
|
|
7060
8181
|
return false;
|
|
7061
|
-
if (
|
|
8182
|
+
if (own19(value, "preferred_scheme") && !(value.preferred_scheme === null || typeof value.preferred_scheme === "string" && SCHEME.test(value.preferred_scheme)))
|
|
7062
8183
|
return false;
|
|
7063
8184
|
const contact = value.contact;
|
|
7064
|
-
return
|
|
8185
|
+
return record37(contact) && Object.keys(contact).every((key) => CONTACT_KEYS.includes(key) && pageText2(contact[key]));
|
|
7065
8186
|
}
|
|
7066
8187
|
function processoutBodyVerdict(body, url) {
|
|
7067
8188
|
if (url !== void 0 && processoutCardTarget(url) === null)
|
|
7068
|
-
return
|
|
7069
|
-
const value =
|
|
8189
|
+
return refuse45("processout_url_refused");
|
|
8190
|
+
const value = readBody27(body);
|
|
7070
8191
|
if (value === null || !Object.keys(value).every((key) => BODY_KEYS3.has(key)))
|
|
7071
|
-
return
|
|
8192
|
+
return refuse45("processout_body_unsupported");
|
|
7072
8193
|
if (!PROCESSOUT_CARD_KEYS.every((key) => typeof value[key] === "string"))
|
|
7073
|
-
return
|
|
7074
|
-
if (!
|
|
7075
|
-
return
|
|
8194
|
+
return refuse45("processout_body_unsupported");
|
|
8195
|
+
if (!NUMBER9.test(value.number) || !luhn12(value.number) || !MONTH23.test(value.exp_month) || !YEAR24.test(value.exp_year) || !CODE9.test(value.cvc2))
|
|
8196
|
+
return refuse45("processout_body_unsupported");
|
|
7076
8197
|
if (!soundPageData(value) || !soundDevice3(value))
|
|
7077
|
-
return
|
|
7078
|
-
return
|
|
8198
|
+
return refuse45("processout_body_unsupported");
|
|
8199
|
+
return CARD44;
|
|
7079
8200
|
}
|
|
7080
8201
|
var processout_default = /* @__PURE__ */ registerProcessor({
|
|
7081
8202
|
psp: PROCESSOUT_PSP,
|
|
@@ -7118,17 +8239,17 @@ var USAEPAY_HOSTS = /* @__PURE__ */ Object.freeze({
|
|
|
7118
8239
|
"sandbox.usaepay.com": "sandbox"
|
|
7119
8240
|
});
|
|
7120
8241
|
var USAEPAY_PAYMENT_KEYS_PATH = "/api/v2/pub/payment_keys";
|
|
7121
|
-
var
|
|
7122
|
-
var
|
|
7123
|
-
var
|
|
8242
|
+
var BODY_LIMIT45 = 512;
|
|
8243
|
+
var URL_LIMIT18 = 256;
|
|
8244
|
+
var CARD_NUMBER22 = /^[0-9]{13,19}$/;
|
|
7124
8245
|
var EXPIRATION2 = /^(?:0[1-9]|1[0-2])[0-9]{2}$/;
|
|
7125
|
-
var
|
|
7126
|
-
var
|
|
7127
|
-
var
|
|
7128
|
-
var
|
|
7129
|
-
var
|
|
8246
|
+
var SECURITY_CODE26 = /^(?:[0-9]{3,4})?$/;
|
|
8247
|
+
var record38 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
8248
|
+
var own20 = (value, key) => Object.prototype.hasOwnProperty.call(value, key);
|
|
8249
|
+
var refuse46 = (code) => Object.freeze({ verdict: "refuse", code });
|
|
8250
|
+
var CARD45 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
|
|
7130
8251
|
function usaepayPaymentKeysUrl(url) {
|
|
7131
|
-
if (typeof url !== "string" || url.length >
|
|
8252
|
+
if (typeof url !== "string" || url.length > URL_LIMIT18 || url.includes("?") || url.includes("#"))
|
|
7132
8253
|
return null;
|
|
7133
8254
|
let parsed;
|
|
7134
8255
|
try {
|
|
@@ -7137,12 +8258,12 @@ function usaepayPaymentKeysUrl(url) {
|
|
|
7137
8258
|
catch {
|
|
7138
8259
|
return null;
|
|
7139
8260
|
}
|
|
7140
|
-
if (parsed.href !== url || parsed.protocol !== "https:" || parsed.port || parsed.username || parsed.password || !
|
|
8261
|
+
if (parsed.href !== url || parsed.protocol !== "https:" || parsed.port || parsed.username || parsed.password || !own20(USAEPAY_HOSTS, parsed.hostname) || parsed.pathname !== USAEPAY_PAYMENT_KEYS_PATH)
|
|
7141
8262
|
return null;
|
|
7142
8263
|
return Object.freeze({ host: parsed.hostname, environment: USAEPAY_HOSTS[parsed.hostname] });
|
|
7143
8264
|
}
|
|
7144
8265
|
var isUsaepayPaymentKeysUrl = (url) => usaepayPaymentKeysUrl(url) !== null;
|
|
7145
|
-
function
|
|
8266
|
+
function luhn13(digits4) {
|
|
7146
8267
|
let sum = 0;
|
|
7147
8268
|
for (let at = digits4.length - 1, double = false; at >= 0; at -= 1, double = !double) {
|
|
7148
8269
|
let digit = digits4.charCodeAt(at) - 48;
|
|
@@ -7152,23 +8273,23 @@ function luhn11(digits4) {
|
|
|
7152
8273
|
}
|
|
7153
8274
|
return sum % 10 === 0;
|
|
7154
8275
|
}
|
|
7155
|
-
function
|
|
7156
|
-
if (typeof body !== "string" || body === "" || body.length >
|
|
8276
|
+
function readBody28(body) {
|
|
8277
|
+
if (typeof body !== "string" || body === "" || body.length > BODY_LIMIT45)
|
|
7157
8278
|
return null;
|
|
7158
8279
|
try {
|
|
7159
8280
|
const value = JSON.parse(body);
|
|
7160
|
-
return
|
|
8281
|
+
return record38(value) && JSON.stringify(value) === body ? value : null;
|
|
7161
8282
|
}
|
|
7162
8283
|
catch {
|
|
7163
8284
|
return null;
|
|
7164
8285
|
}
|
|
7165
8286
|
}
|
|
7166
8287
|
function usaepayBodyVerdict(body) {
|
|
7167
|
-
const value =
|
|
8288
|
+
const value = readBody28(body);
|
|
7168
8289
|
const card = value === null ? null : value.creditcard;
|
|
7169
|
-
if (value === null || Object.keys(value).join() !== "creditcard" || !
|
|
7170
|
-
return
|
|
7171
|
-
return
|
|
8290
|
+
if (value === null || Object.keys(value).join() !== "creditcard" || !record38(card) || Object.keys(card).join() !== "number,expiration,cvc" || typeof card.number !== "string" || !CARD_NUMBER22.test(card.number) || !luhn13(card.number) || typeof card.expiration !== "string" || !EXPIRATION2.test(card.expiration) || typeof card.cvc !== "string" || !SECURITY_CODE26.test(card.cvc))
|
|
8291
|
+
return refuse46("usaepay_body_unsupported");
|
|
8292
|
+
return CARD45;
|
|
7172
8293
|
}
|
|
7173
8294
|
var usaepay_default = /* @__PURE__ */ registerProcessor({
|
|
7174
8295
|
psp: USAEPAY_PSP,
|
|
@@ -7200,9 +8321,204 @@ var usaepay_default = /* @__PURE__ */ registerProcessor({
|
|
|
7200
8321
|
source: "https://help.usaepay.info/developer/payjs-v2/ , https://help.usaepay.info/api/rest/"
|
|
7201
8322
|
},
|
|
7202
8323
|
exactUrl: isUsaepayPaymentKeysUrl,
|
|
7203
|
-
bodyGate: (url, body) => url !== void 0 && !isUsaepayPaymentKeysUrl(url) ?
|
|
8324
|
+
bodyGate: (url, body) => url !== void 0 && !isUsaepayPaymentKeysUrl(url) ? refuse46("usaepay_url_refused") : usaepayBodyVerdict(body)
|
|
7204
8325
|
// No amount reader: the request names none, so the agent's pair is the figure the cardholder approves.
|
|
7205
8326
|
});
|
|
8327
|
+
// src/processors/viva_wallet.js
|
|
8328
|
+
var VIVA_WALLET_PSP = "viva_wallet";
|
|
8329
|
+
var VIVA_WALLET_OPERATION = "viva_wallet.card_request";
|
|
8330
|
+
var VIVA_WALLET_HOSTS = /* @__PURE__ */ Object.freeze({ "www.vivapayments.com": "production", "demo.vivapayments.com": "sandbox" });
|
|
8331
|
+
var VIVA_WALLET_CHARGE_TOKENS_PATH = "/web2/checkout/v2/chargetokens";
|
|
8332
|
+
var VIVA_WALLET_BODY_KEYS = /* @__PURE__ */ Object.freeze([
|
|
8333
|
+
"orderCode",
|
|
8334
|
+
"amount",
|
|
8335
|
+
"currencyCode",
|
|
8336
|
+
"holderName",
|
|
8337
|
+
"holderMail",
|
|
8338
|
+
"cvc",
|
|
8339
|
+
"number",
|
|
8340
|
+
"expirationMonth",
|
|
8341
|
+
"expirationYear",
|
|
8342
|
+
"installments",
|
|
8343
|
+
"customer",
|
|
8344
|
+
"rememberCard",
|
|
8345
|
+
"friendlyName",
|
|
8346
|
+
"maskedNumber",
|
|
8347
|
+
"bankId",
|
|
8348
|
+
"selectedBrand",
|
|
8349
|
+
"cardholderBrandSelection",
|
|
8350
|
+
"dccOptions",
|
|
8351
|
+
"dccAccepted",
|
|
8352
|
+
"offerCodes",
|
|
8353
|
+
"loyaltySupported",
|
|
8354
|
+
"redeemedAmount",
|
|
8355
|
+
"retrievalReferenceNumber",
|
|
8356
|
+
"scaRequestedTransactionId",
|
|
8357
|
+
"merchantTrns",
|
|
8358
|
+
"captchaToken"
|
|
8359
|
+
]);
|
|
8360
|
+
var BODY_LIMIT46 = 16384;
|
|
8361
|
+
var URL_LIMIT19 = 256;
|
|
8362
|
+
var ORDER_CODE = /^[0-9]{16}$/;
|
|
8363
|
+
var CARD_NUMBER23 = /^[0-9]{13,19}$/;
|
|
8364
|
+
var MONTH24 = /^(?:0[1-9]|1[0-2])$/;
|
|
8365
|
+
var YEAR25 = /^[0-9]{2}$/;
|
|
8366
|
+
var SECURITY_CODE27 = /^[0-9]{3,4}$/;
|
|
8367
|
+
var CAPTCHA_TOKEN = /^[A-Za-z0-9_.-]{20,8192}$/;
|
|
8368
|
+
var MEMBER_NAME = /^[A-Za-z][A-Za-z0-9]{0,31}$/;
|
|
8369
|
+
var SHORT_ID = /^[A-Za-z0-9_-]{1,64}$/;
|
|
8370
|
+
var TEXT4 = /^[^\u0000-\u001f\u007f]{0,200}$/;
|
|
8371
|
+
var CARD_DIGITS2 = /[0-9]{12,}/;
|
|
8372
|
+
var record39 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
8373
|
+
var own21 = (value, key) => Object.prototype.hasOwnProperty.call(value, key);
|
|
8374
|
+
var refuse47 = (code) => Object.freeze({ verdict: "refuse", code });
|
|
8375
|
+
var CARD46 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
|
|
8376
|
+
var inOrder9 = (value, keys) => {
|
|
8377
|
+
let at = 0;
|
|
8378
|
+
for (const name of Object.keys(value)) {
|
|
8379
|
+
while (at < keys.length && keys[at] !== name)
|
|
8380
|
+
at += 1;
|
|
8381
|
+
if (at === keys.length)
|
|
8382
|
+
return false;
|
|
8383
|
+
at += 1;
|
|
8384
|
+
}
|
|
8385
|
+
return true;
|
|
8386
|
+
};
|
|
8387
|
+
var cardDigits2 = (text11) => CARD_DIGITS2.test(text11.replace(/[^0-9A-Za-z]/g, ""));
|
|
8388
|
+
var plainText8 = (value) => typeof value === "string" && TEXT4.test(value) && !cardDigits2(value);
|
|
8389
|
+
var scalar = (value) => value === null || typeof value === "boolean" || Number.isSafeInteger(value) && Math.abs(value) < 1e9 || plainText8(value);
|
|
8390
|
+
var flatRecord = (value, limit) => record39(value) && Object.keys(value).length <= limit && Object.entries(value).every(([key, item]) => MEMBER_NAME.test(key) && scalar(item));
|
|
8391
|
+
function vivaWalletChargeTokensUrl(url) {
|
|
8392
|
+
if (typeof url !== "string" || url.length > URL_LIMIT19 || url.includes("?") || url.includes("#"))
|
|
8393
|
+
return null;
|
|
8394
|
+
let parsed;
|
|
8395
|
+
try {
|
|
8396
|
+
parsed = new URL(url);
|
|
8397
|
+
}
|
|
8398
|
+
catch {
|
|
8399
|
+
return null;
|
|
8400
|
+
}
|
|
8401
|
+
if (parsed.href !== url || parsed.protocol !== "https:" || parsed.port || parsed.username || parsed.password || !own21(VIVA_WALLET_HOSTS, parsed.hostname) || parsed.pathname !== VIVA_WALLET_CHARGE_TOKENS_PATH)
|
|
8402
|
+
return null;
|
|
8403
|
+
return Object.freeze({ host: parsed.hostname, environment: VIVA_WALLET_HOSTS[parsed.hostname] });
|
|
8404
|
+
}
|
|
8405
|
+
var isVivaWalletChargeTokensUrl = (url) => vivaWalletChargeTokensUrl(url) !== null;
|
|
8406
|
+
function luhn14(digits4) {
|
|
8407
|
+
let sum = 0;
|
|
8408
|
+
for (let at = digits4.length - 1, double = false; at >= 0; at -= 1, double = !double) {
|
|
8409
|
+
let digit = digits4.charCodeAt(at) - 48;
|
|
8410
|
+
if (double)
|
|
8411
|
+
digit = digit * 2 > 9 ? digit * 2 - 9 : digit * 2;
|
|
8412
|
+
sum += digit;
|
|
8413
|
+
}
|
|
8414
|
+
return sum % 10 === 0;
|
|
8415
|
+
}
|
|
8416
|
+
function vivaWalletMaskedNumber(number) {
|
|
8417
|
+
return `${number.slice(0, 6)}${"X".repeat(Math.max(0, number.length - 10))}${number.slice(-4)}`;
|
|
8418
|
+
}
|
|
8419
|
+
function readBody29(body) {
|
|
8420
|
+
if (typeof body !== "string" || body === "" || body.length > BODY_LIMIT46)
|
|
8421
|
+
return null;
|
|
8422
|
+
try {
|
|
8423
|
+
const value = JSON.parse(body);
|
|
8424
|
+
return record39(value) && JSON.stringify(value) === body ? value : null;
|
|
8425
|
+
}
|
|
8426
|
+
catch {
|
|
8427
|
+
return null;
|
|
8428
|
+
}
|
|
8429
|
+
}
|
|
8430
|
+
function currencyNumber(value) {
|
|
8431
|
+
if (Number.isSafeInteger(value) && value > 0 && value < 1e3)
|
|
8432
|
+
return value;
|
|
8433
|
+
return typeof value === "string" && /^[0-9]{3}$/.test(value) ? Number(value) : null;
|
|
8434
|
+
}
|
|
8435
|
+
function vivaWalletBodyVerdict(body) {
|
|
8436
|
+
const value = readBody29(body);
|
|
8437
|
+
if (value === null || !Object.keys(value).every((key) => VIVA_WALLET_BODY_KEYS.includes(key))) {
|
|
8438
|
+
return value !== null && (own21(value, "creditCardId") || own21(value, "token")) ? refuse47("viva_wallet_stored_card") : refuse47("viva_wallet_body_unsupported");
|
|
8439
|
+
}
|
|
8440
|
+
if (value.rememberCard !== false)
|
|
8441
|
+
return refuse47(value.rememberCard === true ? "viva_wallet_keep_on_file" : "viva_wallet_body_unsupported");
|
|
8442
|
+
if (value.dccAccepted === true)
|
|
8443
|
+
return refuse47("viva_wallet_currency_conversion");
|
|
8444
|
+
if (own21(value, "dccAccepted") && value.dccAccepted !== false)
|
|
8445
|
+
return refuse47("viva_wallet_body_unsupported");
|
|
8446
|
+
if (own21(value, "scaRequestedTransactionId"))
|
|
8447
|
+
return refuse47("viva_wallet_retry_refused");
|
|
8448
|
+
if (!(value.installments === 0 || value.installments === 1)) {
|
|
8449
|
+
return refuse47(Number.isSafeInteger(value.installments) && value.installments > 1 ? "viva_wallet_installments" : "viva_wallet_body_unsupported");
|
|
8450
|
+
}
|
|
8451
|
+
if (!inOrder9(value, VIVA_WALLET_BODY_KEYS) || ["offerCodes", "loyaltySupported", "redeemedAmount", "retrievalReferenceNumber", "merchantTrns"].some((key) => own21(value, key)))
|
|
8452
|
+
return refuse47("viva_wallet_body_unsupported");
|
|
8453
|
+
const number = value.number;
|
|
8454
|
+
const sound = typeof value.orderCode === "string" && ORDER_CODE.test(value.orderCode) && Number.isSafeInteger(value.amount) && value.amount > 0 && currencyNumber(value.currencyCode) !== null && plainText8(value.holderName) && value.holderName.trim() !== "" && plainText8(value.holderMail) && (value.cvc === null || typeof value.cvc === "string" && SECURITY_CODE27.test(value.cvc)) && typeof number === "string" && CARD_NUMBER23.test(number) && luhn14(number) && typeof value.expirationMonth === "string" && MONTH24.test(value.expirationMonth) && typeof value.expirationYear === "string" && YEAR25.test(value.expirationYear) && flatRecord(value.customer, 12) && (!own21(value, "friendlyName") || plainText8(value.friendlyName)) && value.maskedNumber === vivaWalletMaskedNumber(number) && (!own21(value, "bankId") || typeof value.bankId === "string" && SHORT_ID.test(value.bankId) || Number.isSafeInteger(value.bankId) && value.bankId >= 0) && (!own21(value, "selectedBrand") || value.selectedBrand === null || flatRecord(value.selectedBrand, 16)) && (!own21(value, "cardholderBrandSelection") || typeof value.cardholderBrandSelection === "boolean") && (!own21(value, "dccOptions") || flatRecord(value.dccOptions, 16)) && (!own21(value, "captchaToken") || typeof value.captchaToken === "string" && CAPTCHA_TOKEN.test(value.captchaToken));
|
|
8455
|
+
return sound ? CARD46 : refuse47("viva_wallet_body_unsupported");
|
|
8456
|
+
}
|
|
8457
|
+
var VIVA_WALLET_CURRENCIES = /* @__PURE__ */ Object.freeze({
|
|
8458
|
+
978: "eur",
|
|
8459
|
+
826: "gbp",
|
|
8460
|
+
946: "ron",
|
|
8461
|
+
985: "pln",
|
|
8462
|
+
203: "czk",
|
|
8463
|
+
348: "huf",
|
|
8464
|
+
752: "sek",
|
|
8465
|
+
208: "dkk"
|
|
8466
|
+
});
|
|
8467
|
+
function vivaWalletAmount(body) {
|
|
8468
|
+
if (vivaWalletBodyVerdict(body).verdict !== "card")
|
|
8469
|
+
return null;
|
|
8470
|
+
const value = JSON.parse(body);
|
|
8471
|
+
const currency = VIVA_WALLET_CURRENCIES[currencyNumber(value.currencyCode)];
|
|
8472
|
+
return currency ? { amountCents: value.amount, currency } : null;
|
|
8473
|
+
}
|
|
8474
|
+
var VIVA_WALLET_MERCHANT_PINS = /* @__PURE__ */ Object.freeze([
|
|
8475
|
+
Object.freeze({
|
|
8476
|
+
id: "klimaka_donation",
|
|
8477
|
+
merchant: "Klimaka",
|
|
8478
|
+
tradeName: "ΚΛΙΜΑΚΑ ΑΜΚΕ",
|
|
8479
|
+
orderCodes: Object.freeze(["7871752880772607"]),
|
|
8480
|
+
origin: "https://www.vivapayments.com",
|
|
8481
|
+
currencyCode: 978
|
|
8482
|
+
}),
|
|
8483
|
+
Object.freeze({
|
|
8484
|
+
id: "desmos_donation",
|
|
8485
|
+
merchant: "Desmos",
|
|
8486
|
+
tradeName: "DESMOS",
|
|
8487
|
+
orderCodes: Object.freeze(["8156257435672606"]),
|
|
8488
|
+
origin: "https://www.vivapayments.com",
|
|
8489
|
+
currencyCode: 978
|
|
8490
|
+
})
|
|
8491
|
+
]);
|
|
8492
|
+
var CARD_MEMBERS = Object.freeze(["cvc", "number", "expirationMonth", "expirationYear", "maskedNumber"]);
|
|
8493
|
+
var viva_wallet_default = /* @__PURE__ */ registerProcessor({
|
|
8494
|
+
psp: VIVA_WALLET_PSP,
|
|
8495
|
+
definitions: [
|
|
8496
|
+
{
|
|
8497
|
+
psp: "viva_wallet",
|
|
8498
|
+
// The page's card request, as the header above reads it. demo.vivapayments.com is Viva's sandbox, pinned to test
|
|
8499
|
+
// rows, which send only Viva's documented test cards (hostEnvironmentPinned, device-replay.js S7).
|
|
8500
|
+
// Ships dark: served only to a client that declares `viva_smart_checkout_chargetoken`, and only for a company the
|
|
8501
|
+
// backend's processor gate turns Viva Wallet on for. `(?![\w/.%-])` ends the path for a consumer that tests `match`
|
|
8502
|
+
// unanchored.
|
|
8503
|
+
capability: "viva_smart_checkout_chargetoken",
|
|
8504
|
+
match: "(?:www|demo)\\.vivapayments\\.com/web2/checkout/v2/chargetokens(?![\\w/.%-])",
|
|
8505
|
+
hosts: ["^www\\.vivapayments\\.com$", "^demo\\.vivapayments\\.com$"],
|
|
8506
|
+
sandboxHosts: ["^demo\\.vivapayments\\.com$"],
|
|
8507
|
+
hostEnvironmentPinned: true,
|
|
8508
|
+
encoding: "json",
|
|
8509
|
+
// The page sends no Authorization; Origin, Referer, cookies and the reCAPTCHA state never ride.
|
|
8510
|
+
passthroughHeaders: [],
|
|
8511
|
+
jsonCardFields: [["number"]]
|
|
8512
|
+
}
|
|
8513
|
+
],
|
|
8514
|
+
// Only the cardholder's device sends this card, after a person approves; no reviewed list names viva_wallet.
|
|
8515
|
+
refusedOperations: [VIVA_WALLET_OPERATION],
|
|
8516
|
+
settlementReadback: "not_surveyed",
|
|
8517
|
+
exactUrl: isVivaWalletChargeTokensUrl,
|
|
8518
|
+
bodyGate: (url, body) => url !== void 0 && !isVivaWalletChargeTokensUrl(url) ? refuse47("viva_wallet_url_refused") : vivaWalletBodyVerdict(body),
|
|
8519
|
+
// The body names the order's amount in cents and its numeric currency, which the page's card-free charge repeats.
|
|
8520
|
+
amount: (template) => record39(template) && isVivaWalletChargeTokensUrl(template.url) ? vivaWalletAmount(template.body) : null
|
|
8521
|
+
});
|
|
7206
8522
|
// src/processors/vtex_payments.js
|
|
7207
8523
|
var VTEX_PAYMENTS_PSP = "vtex_payments";
|
|
7208
8524
|
var VTEX_PAYMENTS_OPERATION = "vtex_payments.card_request";
|
|
@@ -7251,27 +8567,27 @@ var VTEX_PAYMENTS_MERCHANT_PINS = /* @__PURE__ */ Object.freeze([
|
|
|
7251
8567
|
Object.freeze({ account: "alssports", origin: "https://www.als.com", merchant: "Al's Sporting Goods", currency: "USD" }),
|
|
7252
8568
|
Object.freeze({ account: "roadrunnersports", origin: "https://www.roadrunnersports.com", merchant: "Road Runner Sports", currency: "USD" })
|
|
7253
8569
|
]);
|
|
7254
|
-
var
|
|
8570
|
+
var BODY_LIMIT47 = 16384;
|
|
7255
8571
|
var ACCOUNT_HOST = /^([a-z0-9]{1,63})\.vtexvault\.com$/;
|
|
7256
8572
|
var PATH = /^\/api\/payments\/transactions\/([0-9A-Fa-f]{32})\/payments$/;
|
|
7257
8573
|
var ORDER_GROUP = /^[0-9]{6,24}$/;
|
|
7258
|
-
var
|
|
7259
|
-
var
|
|
7260
|
-
var
|
|
8574
|
+
var BASE648 = /^[A-Za-z0-9+/]{4,1020}={0,2}$/;
|
|
8575
|
+
var CARD_NUMBER24 = /^[0-9]{12,19}$/;
|
|
8576
|
+
var SECURITY_CODE28 = /^[0-9]{3,4}$/;
|
|
7261
8577
|
var DUE_DATE = /^(?:0[1-9]|1[0-2])\/[0-9]{2}$/;
|
|
7262
8578
|
var CURRENCY6 = /^[A-Z]{3}$/;
|
|
7263
8579
|
var TRANSACTION_ID = /^[0-9A-Fa-f]{32}$/;
|
|
7264
8580
|
var MERCHANT_NAME = /^[A-Za-z0-9_.-]{1,64}$/;
|
|
7265
|
-
var
|
|
8581
|
+
var SHORT_ID2 = /^[A-Za-z0-9_-]{1,64}$/;
|
|
7266
8582
|
var FINGERPRINT4 = /^[A-Za-z0-9_.:=+/-]{1,256}$/;
|
|
7267
|
-
var
|
|
7268
|
-
var
|
|
8583
|
+
var TEXT5 = /^[^\u0000-\u001f\u007f]{1,200}$/;
|
|
8584
|
+
var CARD_DIGITS3 = /[0-9]{12,}/;
|
|
7269
8585
|
var DEVICE_INFO_KEYS = Object.freeze(["sw", "sh", "cd", "tz", "lang", "java", "sourceApplication"]);
|
|
7270
|
-
var
|
|
7271
|
-
var
|
|
7272
|
-
var
|
|
7273
|
-
var
|
|
7274
|
-
var
|
|
8586
|
+
var record40 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
8587
|
+
var own22 = (value, key) => Object.prototype.hasOwnProperty.call(value, key);
|
|
8588
|
+
var refuse48 = (code) => Object.freeze({ verdict: "refuse", code });
|
|
8589
|
+
var CARD47 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
|
|
8590
|
+
var inOrder10 = (value, keys) => {
|
|
7275
8591
|
let at = 0;
|
|
7276
8592
|
for (const name of Object.keys(value)) {
|
|
7277
8593
|
while (at < keys.length && keys[at] !== name)
|
|
@@ -7282,8 +8598,8 @@ var inOrder8 = (value, keys) => {
|
|
|
7282
8598
|
}
|
|
7283
8599
|
return true;
|
|
7284
8600
|
};
|
|
7285
|
-
var
|
|
7286
|
-
var
|
|
8601
|
+
var cardDigits3 = (text11) => CARD_DIGITS3.test(text11.replace(/[^0-9A-Za-z]/g, ""));
|
|
8602
|
+
var plainText9 = (value) => typeof value === "string" && TEXT5.test(value) && !cardDigits3(value);
|
|
7287
8603
|
var count = (value) => Number.isSafeInteger(value) && value >= 0;
|
|
7288
8604
|
var BASE64_ALPHABET2 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
7289
8605
|
function base64Text2(input) {
|
|
@@ -7307,10 +8623,10 @@ function base64Text2(input) {
|
|
|
7307
8623
|
}
|
|
7308
8624
|
return out;
|
|
7309
8625
|
}
|
|
7310
|
-
function deviceInfoSound(
|
|
7311
|
-
if (typeof
|
|
8626
|
+
function deviceInfoSound(text11) {
|
|
8627
|
+
if (typeof text11 !== "string" || !BASE648.test(text11))
|
|
7312
8628
|
return false;
|
|
7313
|
-
const decoded = base64Text2(
|
|
8629
|
+
const decoded = base64Text2(text11);
|
|
7314
8630
|
if (decoded === null)
|
|
7315
8631
|
return false;
|
|
7316
8632
|
let info;
|
|
@@ -7320,18 +8636,18 @@ function deviceInfoSound(text10) {
|
|
|
7320
8636
|
catch {
|
|
7321
8637
|
return false;
|
|
7322
8638
|
}
|
|
7323
|
-
if (!
|
|
8639
|
+
if (!record40(info) || !Object.keys(info).every((key) => DEVICE_INFO_KEYS.includes(key)))
|
|
7324
8640
|
return false;
|
|
7325
8641
|
for (const key of ["sw", "sh", "cd"])
|
|
7326
|
-
if (
|
|
8642
|
+
if (own22(info, key) && !(count(info[key]) && info[key] <= 1e5))
|
|
7327
8643
|
return false;
|
|
7328
|
-
if (
|
|
8644
|
+
if (own22(info, "tz") && !(Number.isSafeInteger(info.tz) && Math.abs(info.tz) <= 1440))
|
|
7329
8645
|
return false;
|
|
7330
|
-
if (
|
|
8646
|
+
if (own22(info, "lang") && !(typeof info.lang === "string" && /^[A-Za-z]{0,8}$/.test(info.lang)))
|
|
7331
8647
|
return false;
|
|
7332
|
-
if (
|
|
8648
|
+
if (own22(info, "java") && typeof info.java !== "boolean")
|
|
7333
8649
|
return false;
|
|
7334
|
-
return !
|
|
8650
|
+
return !own22(info, "sourceApplication") || typeof info.sourceApplication === "string" && /^[A-Za-z0-9_.-]{1,32}$/.test(info.sourceApplication);
|
|
7335
8651
|
}
|
|
7336
8652
|
function vtexPaymentsCardTarget(url) {
|
|
7337
8653
|
if (typeof url !== "string" || url.length > 8192)
|
|
@@ -7377,8 +8693,8 @@ function isVtexPaymentsCardUrl(url) {
|
|
|
7377
8693
|
const target = vtexPaymentsCardTarget(url);
|
|
7378
8694
|
return target !== null && !target.fallback;
|
|
7379
8695
|
}
|
|
7380
|
-
function
|
|
7381
|
-
if (typeof body !== "string" || body === "" || body.length >
|
|
8696
|
+
function readBody30(body) {
|
|
8697
|
+
if (typeof body !== "string" || body === "" || body.length > BODY_LIMIT47)
|
|
7382
8698
|
return null;
|
|
7383
8699
|
let value;
|
|
7384
8700
|
try {
|
|
@@ -7392,13 +8708,13 @@ function readBody26(body) {
|
|
|
7392
8708
|
return value;
|
|
7393
8709
|
}
|
|
7394
8710
|
function cardLine(line) {
|
|
7395
|
-
if (!
|
|
8711
|
+
if (!record40(line))
|
|
7396
8712
|
return false;
|
|
7397
|
-
const fields =
|
|
7398
|
-
return line.groupName === "creditCardPaymentGroup" || line.groupName === "debitCardPaymentGroup" ||
|
|
8713
|
+
const fields = record40(line.fields) ? line.fields : {};
|
|
8714
|
+
return line.groupName === "creditCardPaymentGroup" || line.groupName === "debitCardPaymentGroup" || own22(line, "accountId") || own22(fields, "accountId") || own22(fields, "cardNumber") || own22(fields, "validationCode") || own22(fields, "dueDate");
|
|
7399
8715
|
}
|
|
7400
8716
|
function addressSound(address2) {
|
|
7401
|
-
if (!
|
|
8717
|
+
if (!record40(address2) || !inOrder10(address2, VTEX_PAYMENTS_ADDRESS_KEYS))
|
|
7402
8718
|
return false;
|
|
7403
8719
|
for (const [key, value] of Object.entries(address2)) {
|
|
7404
8720
|
if (key === "addressType") {
|
|
@@ -7407,60 +8723,60 @@ function addressSound(address2) {
|
|
|
7407
8723
|
continue;
|
|
7408
8724
|
}
|
|
7409
8725
|
if (key === "addressId") {
|
|
7410
|
-
if (!(typeof value === "string" &&
|
|
8726
|
+
if (!(typeof value === "string" && SHORT_ID2.test(value)))
|
|
7411
8727
|
return false;
|
|
7412
8728
|
continue;
|
|
7413
8729
|
}
|
|
7414
8730
|
if (value === null && (key === "complement" || key === "reference"))
|
|
7415
8731
|
continue;
|
|
7416
|
-
if (!(value === "" ||
|
|
8732
|
+
if (!(value === "" || plainText9(value)))
|
|
7417
8733
|
return false;
|
|
7418
8734
|
}
|
|
7419
8735
|
return true;
|
|
7420
8736
|
}
|
|
7421
8737
|
function fieldsSound(fields) {
|
|
7422
|
-
if (!
|
|
8738
|
+
if (!record40(fields) || !inOrder10(fields, VTEX_PAYMENTS_FIELD_KEYS) || own22(fields, "metadata"))
|
|
7423
8739
|
return false;
|
|
7424
|
-
if (!(typeof fields.cardNumber === "string" &&
|
|
8740
|
+
if (!(typeof fields.cardNumber === "string" && CARD_NUMBER24.test(fields.cardNumber)))
|
|
7425
8741
|
return false;
|
|
7426
|
-
if (!(typeof fields.validationCode === "string" &&
|
|
8742
|
+
if (!(typeof fields.validationCode === "string" && SECURITY_CODE28.test(fields.validationCode)))
|
|
7427
8743
|
return false;
|
|
7428
8744
|
if (!(typeof fields.dueDate === "string" && DUE_DATE.test(fields.dueDate)))
|
|
7429
8745
|
return false;
|
|
7430
|
-
if (!
|
|
8746
|
+
if (!plainText9(fields.holderName))
|
|
7431
8747
|
return false;
|
|
7432
|
-
if (
|
|
8748
|
+
if (own22(fields, "document") && !(fields.document === "" || plainText9(fields.document) && fields.document.length <= 32))
|
|
7433
8749
|
return false;
|
|
7434
|
-
if (
|
|
8750
|
+
if (own22(fields, "address") && !addressSound(fields.address))
|
|
7435
8751
|
return false;
|
|
7436
|
-
if (
|
|
8752
|
+
if (own22(fields, "deviceFingerprint") && !(typeof fields.deviceFingerprint === "string" && FINGERPRINT4.test(fields.deviceFingerprint)))
|
|
7437
8753
|
return false;
|
|
7438
|
-
return !
|
|
8754
|
+
return !own22(fields, "addressId") || typeof fields.addressId === "string" && SHORT_ID2.test(fields.addressId);
|
|
7439
8755
|
}
|
|
7440
8756
|
function vtexPaymentsBodyVerdict(body, target) {
|
|
7441
|
-
const lines =
|
|
7442
|
-
if (lines === null || lines.length === 0 || !lines.every(
|
|
7443
|
-
return
|
|
8757
|
+
const lines = readBody30(body);
|
|
8758
|
+
if (lines === null || lines.length === 0 || !lines.every(record40))
|
|
8759
|
+
return refuse48("vtex_payments_body_unsupported");
|
|
7444
8760
|
const cards = lines.filter(cardLine);
|
|
7445
|
-
if (cards.some((line2) =>
|
|
7446
|
-
return
|
|
8761
|
+
if (cards.some((line2) => own22(line2, "accountId") || own22(line2.fields ?? {}, "accountId")))
|
|
8762
|
+
return refuse48("vtex_payments_saved_card");
|
|
7447
8763
|
if (cards.length === 0)
|
|
7448
|
-
return
|
|
7449
|
-
if (lines.length !== 1 ||
|
|
7450
|
-
return
|
|
8764
|
+
return refuse48("vtex_payments_body_unsupported");
|
|
8765
|
+
if (lines.length !== 1 || own22(lines[0], "id"))
|
|
8766
|
+
return refuse48("vtex_payments_split_payment");
|
|
7451
8767
|
const line = lines[0];
|
|
7452
|
-
if (!
|
|
7453
|
-
return
|
|
7454
|
-
if (!(typeof line.currencyCode === "string" && CURRENCY6.test(line.currencyCode)) || !
|
|
7455
|
-
return
|
|
7456
|
-
if (line.installments !== 1 || line.referenceValue !== line.value ||
|
|
7457
|
-
return
|
|
8768
|
+
if (!inOrder10(line, VTEX_PAYMENTS_LINE_KEYS) || line.groupName !== "creditCardPaymentGroup")
|
|
8769
|
+
return refuse48("vtex_payments_body_unsupported");
|
|
8770
|
+
if (!(typeof line.currencyCode === "string" && CURRENCY6.test(line.currencyCode)) || !own22(VTEX_PAYMENTS_NETWORKS, line.paymentSystem) || !Number.isSafeInteger(line.paymentSystem) || !(count(line.value) && line.value > 0))
|
|
8771
|
+
return refuse48("vtex_payments_body_unsupported");
|
|
8772
|
+
if (line.installments !== 1 || line.referenceValue !== line.value || own22(line, "installmentsInterestRate") && line.installmentsInterestRate !== 0 || own22(line, "installmentsValue") && line.installmentsValue !== line.value)
|
|
8773
|
+
return refuse48("vtex_payments_installments");
|
|
7458
8774
|
const transaction = line.transaction;
|
|
7459
|
-
if (!
|
|
7460
|
-
return
|
|
8775
|
+
if (!record40(transaction) || Object.keys(transaction).join() !== "id,merchantName" || !(typeof transaction.id === "string" && TRANSACTION_ID.test(transaction.id)) || !(typeof transaction.merchantName === "string" && MERCHANT_NAME.test(transaction.merchantName)))
|
|
8776
|
+
return refuse48("vtex_payments_body_unsupported");
|
|
7461
8777
|
if (target && transaction.id.toUpperCase() !== target.transactionId.toUpperCase())
|
|
7462
|
-
return
|
|
7463
|
-
return fieldsSound(line.fields) ?
|
|
8778
|
+
return refuse48("vtex_payments_split_payment");
|
|
8779
|
+
return fieldsSound(line.fields) ? CARD47 : refuse48("vtex_payments_body_unsupported");
|
|
7464
8780
|
}
|
|
7465
8781
|
function vtexPaymentsAmount(body) {
|
|
7466
8782
|
if (vtexPaymentsBodyVerdict(body).verdict !== "card")
|
|
@@ -7505,21 +8821,28 @@ var vtex_payments_default = /* @__PURE__ */ registerProcessor({
|
|
|
7505
8821
|
return vtexPaymentsBodyVerdict(body);
|
|
7506
8822
|
const target = vtexPaymentsCardTarget(url);
|
|
7507
8823
|
if (target === null)
|
|
7508
|
-
return
|
|
7509
|
-
return target.fallback ?
|
|
8824
|
+
return refuse48("vtex_payments_url_refused");
|
|
8825
|
+
return target.fallback ? refuse48("vtex_payments_fallback_refused") : vtexPaymentsBodyVerdict(body, target);
|
|
7510
8826
|
},
|
|
7511
|
-
amount: (template) =>
|
|
8827
|
+
amount: (template) => record40(template) && isVtexPaymentsCardUrl(template.url) ? vtexPaymentsAmount(template.body) : null
|
|
7512
8828
|
});
|
|
7513
8829
|
// src/processors/index.generated.js
|
|
7514
8830
|
var REGISTERED_MODULES = Object.freeze({
|
|
8831
|
+
aurus: aurus_default,
|
|
7515
8832
|
bluesnap: bluesnap_default,
|
|
8833
|
+
cardlink_vpos: cardlink_vpos_default,
|
|
8834
|
+
eghl: eghl_default,
|
|
8835
|
+
frisbii: frisbii_default,
|
|
7516
8836
|
iyzico: iyzico_default,
|
|
7517
8837
|
midtrans: midtrans_default,
|
|
8838
|
+
monei: monei_default,
|
|
7518
8839
|
oceanpayment: oceanpayment_default,
|
|
7519
8840
|
paymentwall: paymentwall_default,
|
|
7520
8841
|
payplug: payplug_default,
|
|
8842
|
+
paystack: paystack_default,
|
|
7521
8843
|
processout: processout_default,
|
|
7522
8844
|
usaepay: usaepay_default,
|
|
8845
|
+
viva_wallet: viva_wallet_default,
|
|
7523
8846
|
vtex_payments: vtex_payments_default
|
|
7524
8847
|
});
|
|
7525
8848
|
// src/registry.js
|
|
@@ -7708,7 +9031,7 @@ function carriesCardFields(recognizer, body) {
|
|
|
7708
9031
|
if (typeof body !== "string" || body === "")
|
|
7709
9032
|
return false;
|
|
7710
9033
|
const anyCase = recognizer.caseInsensitiveFormKeys === true;
|
|
7711
|
-
const wanted = anyCase ? fields.map((
|
|
9034
|
+
const wanted = anyCase ? fields.map((field5) => String(field5).toLowerCase()) : fields;
|
|
7712
9035
|
for (const chunk of body.split("&")) {
|
|
7713
9036
|
const eq = chunk.indexOf("=");
|
|
7714
9037
|
if (eq <= 0 || eq === chunk.length - 1)
|
|
@@ -7799,20 +9122,20 @@ var KEEP_ON_FILE_REFUSAL = "Refusing to pay: this Primer payment would keep the
|
|
|
7799
9122
|
var UNSUPPORTED_SDK_REFUSAL = "Refusing to pay: this checkout uses a Primer SDK Agentcard does not support yet. Nothing was sent.";
|
|
7800
9123
|
var NETWORK_MISMATCH_REFUSAL = "Refusing to pay: this Primer payment names a card network that is not your card's. Nothing was sent.";
|
|
7801
9124
|
var FILL_REFUSAL = "Could not fill the card fields for Primer. Nothing was sent.";
|
|
7802
|
-
var
|
|
9125
|
+
var BODY_LIMIT48 = 16384;
|
|
7803
9126
|
var RESPONSE_LIMIT = 32768;
|
|
7804
9127
|
var ROOT_KEYS10 = ["paymentInstrument", "userDescription", "tokenType", "paymentFlow"];
|
|
7805
9128
|
var INSTRUMENT_KEYS = ["number", "cvv", "expirationMonth", "expirationYear", "cardholderName", "preferredNetwork"];
|
|
7806
9129
|
var REQUIRED_INSTRUMENT_KEYS = ["number", "cvv", "expirationMonth", "expirationYear"];
|
|
7807
|
-
var
|
|
9130
|
+
var record41 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
7808
9131
|
var owns8 = (value, key) => Object.prototype.hasOwnProperty.call(value, key);
|
|
7809
9132
|
var exact5 = (pattern, value) => typeof value === "string" && pattern.exec(value)?.[0] === value;
|
|
7810
|
-
var
|
|
9133
|
+
var text10 = (value, max) => typeof value === "string" && value.length <= max && !/[\u0000-\u001f\u007f]/.test(value);
|
|
7811
9134
|
var digits3 = (value, min, max) => typeof value === "string" && value.length >= min && value.length <= max && !/[^0-9]/.test(value);
|
|
7812
9135
|
var panLike2 = (value) => /(?:[0-9][ _.:-]*){12,}/.test(value);
|
|
7813
|
-
var plain2 = (value, max) =>
|
|
7814
|
-
var
|
|
7815
|
-
var
|
|
9136
|
+
var plain2 = (value, max) => text10(value, max) && !panLike2(value);
|
|
9137
|
+
var MONTH25 = /^(?:0[1-9]|1[0-2])$/;
|
|
9138
|
+
var YEAR26 = /^20[0-9]{2}$/;
|
|
7816
9139
|
var NETWORK3 = /^[A-Z][A-Z_]{1,31}$/;
|
|
7817
9140
|
function isPrimerTokenizeUrl(url, method = "POST") {
|
|
7818
9141
|
if (method !== "POST" || typeof url !== "string" || url.length > 256 || url.includes("?") || url.includes("#"))
|
|
@@ -7827,7 +9150,7 @@ function isPrimerTokenizeUrl(url, method = "POST") {
|
|
|
7827
9150
|
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;
|
|
7828
9151
|
}
|
|
7829
9152
|
function judgeBody6(body) {
|
|
7830
|
-
if (typeof body !== "string" || body === "" || body.length >
|
|
9153
|
+
if (typeof body !== "string" || body === "" || body.length > BODY_LIMIT48)
|
|
7831
9154
|
return null;
|
|
7832
9155
|
let value;
|
|
7833
9156
|
try {
|
|
@@ -7836,14 +9159,14 @@ function judgeBody6(body) {
|
|
|
7836
9159
|
catch {
|
|
7837
9160
|
return null;
|
|
7838
9161
|
}
|
|
7839
|
-
if (!
|
|
9162
|
+
if (!record41(value) || !roundTrips(value, body))
|
|
7840
9163
|
return null;
|
|
7841
9164
|
if (!Object.keys(value).every((key) => ROOT_KEYS10.includes(key)) || !owns8(value, "paymentInstrument"))
|
|
7842
9165
|
return null;
|
|
7843
9166
|
const instrument = value.paymentInstrument;
|
|
7844
|
-
if (!
|
|
9167
|
+
if (!record41(instrument) || !Object.keys(instrument).every((key) => INSTRUMENT_KEYS.includes(key)) || !REQUIRED_INSTRUMENT_KEYS.every((key) => owns8(instrument, key)))
|
|
7845
9168
|
return null;
|
|
7846
|
-
if (!digits3(instrument.number, 12, 19) || !digits3(instrument.cvv, 3, 4) || !exact5(
|
|
9169
|
+
if (!digits3(instrument.number, 12, 19) || !digits3(instrument.cvv, 3, 4) || !exact5(MONTH25, instrument.expirationMonth) || !exact5(YEAR26, instrument.expirationYear))
|
|
7847
9170
|
return null;
|
|
7848
9171
|
if (owns8(instrument, "cardholderName") && instrument.cardholderName !== null && !plain2(instrument.cardholderName, 256) || owns8(instrument, "preferredNetwork") && instrument.preferredNetwork !== null && !exact5(NETWORK3, instrument.preferredNetwork) || owns8(value, "userDescription") && value.userDescription !== null && !plain2(value.userDescription, 256) || owns8(value, "tokenType") && value.tokenType !== "MULTI_USE" || owns8(value, "paymentFlow") && value.paymentFlow !== "VAULT")
|
|
7849
9172
|
return null;
|
|
@@ -7869,7 +9192,7 @@ var CLIENT_TOKEN = /^[A-Za-z0-9._~+/=-]{16,4096}$/;
|
|
|
7869
9192
|
var REQUEST_ID = /^[A-Za-z0-9-]{1,64}$/;
|
|
7870
9193
|
var API_VERSION = /^2\.[0-9]{1,2}$/;
|
|
7871
9194
|
function readHeaders(headers) {
|
|
7872
|
-
if (!
|
|
9195
|
+
if (!record41(headers))
|
|
7873
9196
|
return null;
|
|
7874
9197
|
const folded = /* @__PURE__ */ new Map();
|
|
7875
9198
|
for (const [name, value] of Object.entries(headers)) {
|
|
@@ -7916,7 +9239,7 @@ function onTokenizePath(url) {
|
|
|
7916
9239
|
}
|
|
7917
9240
|
}
|
|
7918
9241
|
function primerTokenizeRefusal(request) {
|
|
7919
|
-
if (!
|
|
9242
|
+
if (!record41(request) || request.method !== "POST" || !isPrimerTokenizeUrl(request.url))
|
|
7920
9243
|
return "unsupported";
|
|
7921
9244
|
return headersRefusal(request.headers) ?? primerBodyRefusal(request.body);
|
|
7922
9245
|
}
|
|
@@ -7931,7 +9254,7 @@ function primerCardOnFileRefusal(url, options, policy = PRIMER_SESSION_CARD_ON_F
|
|
|
7931
9254
|
return "unsupported";
|
|
7932
9255
|
if (new URL(url).hostname !== LIVE_PCI_HOST)
|
|
7933
9256
|
return null;
|
|
7934
|
-
return primerCardOnFileDisclosure(url, policy) &&
|
|
9257
|
+
return primerCardOnFileDisclosure(url, policy) && record41(options) && options.keepOnFile === true ? null : "keep_on_file";
|
|
7935
9258
|
}
|
|
7936
9259
|
function primerRefusalMessage(reason) {
|
|
7937
9260
|
if (reason === "keep_on_file")
|
|
@@ -7992,7 +9315,7 @@ function injectPrimerCard(body, card) {
|
|
|
7992
9315
|
}
|
|
7993
9316
|
var TOKEN4 = /^[A-Za-z0-9_-]{8,256}$/;
|
|
7994
9317
|
var ERROR_ID = /^[A-Za-z][A-Za-z0-9_.-]{0,63}$/;
|
|
7995
|
-
var
|
|
9318
|
+
var CODE10 = /^[A-Z][A-Z0-9_]{0,63}$/;
|
|
7996
9319
|
var NETWORK_NAME2 = /^[A-Za-z][A-Za-z0-9 _-]{0,31}$/;
|
|
7997
9320
|
var RESPONSE_MONTH = /^(?:0?[1-9]|1[0-2])$/;
|
|
7998
9321
|
var RESPONSE_YEAR = /^(?:[0-9]{2}|20[0-9]{2})$/;
|
|
@@ -8015,7 +9338,7 @@ function readAnswer(body) {
|
|
|
8015
9338
|
return null;
|
|
8016
9339
|
try {
|
|
8017
9340
|
const value = JSON.parse(body);
|
|
8018
|
-
return
|
|
9341
|
+
return record41(value) ? value : null;
|
|
8019
9342
|
}
|
|
8020
9343
|
catch {
|
|
8021
9344
|
return null;
|
|
@@ -8024,16 +9347,16 @@ function readAnswer(body) {
|
|
|
8024
9347
|
var tokenValue = (value) => exact5(TOKEN4, value) && !panLike2(value);
|
|
8025
9348
|
var optional = (value, key, check) => !owns8(value, key) || value[key] === null || check(value[key]);
|
|
8026
9349
|
function cardDetails(data) {
|
|
8027
|
-
if (!
|
|
9350
|
+
if (!record41(data) || !exact5(/^[0-9]{4}$/, data.last4Digits))
|
|
8028
9351
|
return null;
|
|
8029
|
-
if (!optional(data, "first6Digits", (v) => exact5(/^[0-9]{6}$/, v)) || !optional(data, "expirationMonth", (v) => exact5(RESPONSE_MONTH, v)) || !optional(data, "expirationYear", (v) => exact5(RESPONSE_YEAR, v)) || !optional(data, "cardholderName", (v) => plain2(v, 256)) || !optional(data, "network", (v) => exact5(NETWORK_NAME2, v)) || !optional(data, "isNetworkTokenized", (v) => typeof v === "boolean") || !optional(data, "binData",
|
|
9352
|
+
if (!optional(data, "first6Digits", (v) => exact5(/^[0-9]{6}$/, v)) || !optional(data, "expirationMonth", (v) => exact5(RESPONSE_MONTH, v)) || !optional(data, "expirationYear", (v) => exact5(RESPONSE_YEAR, v)) || !optional(data, "cardholderName", (v) => plain2(v, 256)) || !optional(data, "network", (v) => exact5(NETWORK_NAME2, v)) || !optional(data, "isNetworkTokenized", (v) => typeof v === "boolean") || !optional(data, "binData", record41))
|
|
8030
9353
|
return null;
|
|
8031
9354
|
const safe = { last4Digits: data.last4Digits };
|
|
8032
9355
|
for (const key of ["first6Digits", "expirationMonth", "expirationYear", "cardholderName", "network", "isNetworkTokenized"]) {
|
|
8033
9356
|
if (owns8(data, key) && data[key] !== null)
|
|
8034
9357
|
safe[key] = data[key];
|
|
8035
9358
|
}
|
|
8036
|
-
if (
|
|
9359
|
+
if (record41(data.binData)) {
|
|
8037
9360
|
const bin = {};
|
|
8038
9361
|
for (const key of BIN_KEYS) {
|
|
8039
9362
|
if (!owns8(data.binData, key) || data.binData[key] === null)
|
|
@@ -8051,7 +9374,7 @@ function cardDetails(data) {
|
|
|
8051
9374
|
function threeDsSummary(value) {
|
|
8052
9375
|
if (value === void 0 || value === null)
|
|
8053
9376
|
return null;
|
|
8054
|
-
if (!
|
|
9377
|
+
if (!record41(value) || !exact5(CODE10, value.responseCode) || !optional(value, "reasonCode", (v) => exact5(CODE10, v)) || !optional(value, "reasonText", (v) => plain2(v, 256)) || !optional(value, "protocolVersion", (v) => v === "" || exact5(PROTOCOL2, v)) || !optional(value, "challengeIssued", (v) => typeof v === "boolean"))
|
|
8055
9378
|
return void 0;
|
|
8056
9379
|
const safe = { responseCode: value.responseCode };
|
|
8057
9380
|
for (const key of ["reasonCode", "reasonText", "protocolVersion", "challengeIssued"]) {
|
|
@@ -8079,7 +9402,7 @@ function rebuildToken(value) {
|
|
|
8079
9402
|
}
|
|
8080
9403
|
function primerErrorId(body) {
|
|
8081
9404
|
const value = readAnswer(body);
|
|
8082
|
-
const id = value &&
|
|
9405
|
+
const id = value && record41(value.error) ? value.error.errorId : null;
|
|
8083
9406
|
return exact5(ERROR_ID, id) && !panLike2(id) ? id : null;
|
|
8084
9407
|
}
|
|
8085
9408
|
function matchesCard(details, card) {
|