@agent-cards/sdk 0.24.0 → 0.24.2
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 +32 -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 +1854 -440
- package/dist/cardlink-vpos.d.ts +43 -0
- package/dist/cardlink-vpos.js +90 -0
- package/dist/cdp.js +22 -0
- package/dist/checkout-com.generated.js +5 -1
- package/dist/client.d.ts +75 -0
- package/dist/client.js +75 -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/lifecycle.d.ts +10 -0
- package/dist/lifecycle.js +25 -0
- package/dist/paddle-tokenex.generated.js +7 -2
- package/dist/payrails.generated.js +7 -2
- package/dist/pre-claim.d.ts +5 -0
- package/dist/pre-claim.js +90 -2
- package/dist/preflight-catalog.json +179 -1
- package/dist/preflight-schemas.json +16 -0
- package/dist/preflight.generated.d.ts +5 -0
- package/dist/preflight.generated.js +49 -3
- package/dist/preparation.d.ts +7 -0
- package/dist/preparation.js +21 -0
- package/dist/primer.generated.js +1856 -442
- package/dist/shiji-sts.generated.js +7 -2
- package/dist/stripe-checkout.generated.js +1837 -475
- package/dist/substitutions.generated.js +94 -1
- package/dist/tap-payments.generated.js +7 -2
- package/dist/token-repeats.d.ts +32 -0
- package/dist/token-repeats.js +64 -0
- 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: 90e78fe2563fa4e058ffb098ef6a1354baffee49d6d73fc52018b2700683b755
|
|
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 own24 = Object.keys(value);
|
|
369
|
+
return own24.length === keys.length && own24.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 own24 = Object.keys(value);
|
|
788
|
+
return own24.length === keys.length && own24.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 own24 = Object.keys(value);
|
|
1278
|
+
return own24.length === keys.length && own24.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 own24 = Object.keys(value);
|
|
1481
|
+
return own24.length === keys.length && own24.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 own24 = Object.keys(value);
|
|
1712
|
+
return own24.length === keys.length && own24.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 own24 = Object.keys(value);
|
|
2763
|
+
return own24.length === keys.length && own24.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 own24 = Object.keys(value);
|
|
3469
|
+
return own24.length === keys.length && own24.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 own24 = Object.keys(value);
|
|
4161
|
+
return own24.length === keys.length && own24.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 own24 = Object.keys(value);
|
|
4561
|
+
return own24.length === keys.length && own24.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 own24 = 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 (own24 !== null && !own24.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,182 @@ 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
|
+
});
|
|
6265
|
+
// src/processors/bigcommerce.js
|
|
6266
|
+
var BIGCOMMERCE_PSP = "bigcommerce";
|
|
6267
|
+
var BIGCOMMERCE_OPERATION = "bigcommerce.card_request";
|
|
6268
|
+
var BIGCOMMERCE_PAYMENTS_URL = "https://payments.bigcommerce.com/api/public/v1/orders/payments";
|
|
6269
|
+
var BODY_LIMIT36 = 65536;
|
|
6270
|
+
var CARD_KEYS16 = /* @__PURE__ */ new Set([
|
|
6271
|
+
"account_name",
|
|
6272
|
+
"month",
|
|
6273
|
+
"number",
|
|
6274
|
+
"verification_value",
|
|
6275
|
+
"year",
|
|
6276
|
+
"customer_code",
|
|
6277
|
+
"three_d_secure",
|
|
6278
|
+
"hosted_form_nonce"
|
|
6279
|
+
]);
|
|
6280
|
+
var OTHER_INSTRUMENTS = /* @__PURE__ */ Object.freeze(["bigpay_token", "credit_card_token", "credit_card_cryptogram"]);
|
|
6281
|
+
var NUMBER8 = /^[0-9]{12,19}$/;
|
|
6282
|
+
var CURRENCY6 = /^[A-Z]{3}$/;
|
|
6283
|
+
var record32 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
6284
|
+
var own12 = (value, key) => Object.prototype.hasOwnProperty.call(value, key);
|
|
6285
|
+
var refuse38 = (code) => Object.freeze({ verdict: "refuse", code });
|
|
6286
|
+
var CARD37 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
|
|
6287
|
+
var CONTINUE13 = /* @__PURE__ */ Object.freeze({ verdict: "continue" });
|
|
6288
|
+
function isBigcommercePaymentsUrl(url) {
|
|
6289
|
+
return url === BIGCOMMERCE_PAYMENTS_URL;
|
|
6290
|
+
}
|
|
6291
|
+
function readBody22(body) {
|
|
6292
|
+
if (typeof body !== "string" || body === "" || body.length > BODY_LIMIT36)
|
|
6293
|
+
return null;
|
|
6294
|
+
try {
|
|
6295
|
+
const parsed = JSON.parse(body);
|
|
6296
|
+
return record32(parsed) && record32(parsed.payment) ? parsed : null;
|
|
6297
|
+
}
|
|
6298
|
+
catch {
|
|
6299
|
+
return null;
|
|
6300
|
+
}
|
|
6301
|
+
}
|
|
6302
|
+
function bigcommerceBodyVerdict(body, url) {
|
|
6303
|
+
if (url !== void 0 && !isBigcommercePaymentsUrl(url))
|
|
6304
|
+
return refuse38("bigcommerce_url_refused");
|
|
6305
|
+
const parsed = readBody22(body);
|
|
6306
|
+
if (!parsed)
|
|
6307
|
+
return refuse38("bigcommerce_body_unsupported");
|
|
6308
|
+
const { payment } = parsed;
|
|
6309
|
+
if (!own12(payment, "credit_card"))
|
|
6310
|
+
return CONTINUE13;
|
|
6311
|
+
const card = payment.credit_card;
|
|
6312
|
+
if (!record32(card) || OTHER_INSTRUMENTS.some((key) => own12(payment, key)) || Object.keys(card).some((key) => !CARD_KEYS16.has(key)) || typeof card.number !== "string" || !NUMBER8.test(card.number)) {
|
|
6313
|
+
return refuse38("bigcommerce_body_unsupported");
|
|
6314
|
+
}
|
|
6315
|
+
if (payment.vault_payment_instrument === true)
|
|
6316
|
+
return refuse38("bigcommerce_keep_on_file");
|
|
6317
|
+
return CARD37;
|
|
6318
|
+
}
|
|
6319
|
+
function bigcommerceAmount(template) {
|
|
6320
|
+
const parsed = record32(template) ? readBody22(template.body) : null;
|
|
6321
|
+
const order = parsed && record32(parsed.order) ? parsed.order : null;
|
|
6322
|
+
const total = order && record32(order.totals) ? order.totals.grand_total : void 0;
|
|
6323
|
+
if (!Number.isSafeInteger(total) || total <= 0 || typeof order.currency !== "string" || !CURRENCY6.test(order.currency))
|
|
6324
|
+
return null;
|
|
6325
|
+
return { amountCents: total, currency: order.currency.toLowerCase() };
|
|
6326
|
+
}
|
|
6327
|
+
var bigcommerce_default = /* @__PURE__ */ registerProcessor({
|
|
6328
|
+
psp: BIGCOMMERCE_PSP,
|
|
6329
|
+
definitions: [
|
|
6330
|
+
{
|
|
6331
|
+
psp: "bigcommerce",
|
|
6332
|
+
// The card request above. One host serves every BigCommerce store, test and live alike, so no sandbox host is
|
|
6333
|
+
// marked. Ships dark: served only to a client that declares `bigcommerce_card_form`, for a company the backend's
|
|
6334
|
+
// processor gate turns BigCommerce on for. `(?![\w/.%-])` ends the path for a consumer that tests `match`
|
|
6335
|
+
// unanchored; the exact-URL rule holds the rest.
|
|
6336
|
+
capability: "bigcommerce_card_form",
|
|
6337
|
+
match: "payments\\.bigcommerce\\.com/api/public/v1/orders/payments(?![\\w/.%-])",
|
|
6338
|
+
hosts: ["^payments\\.bigcommerce\\.com$"],
|
|
6339
|
+
encoding: "json",
|
|
6340
|
+
// The order's payment token and the JSON Accept. Origin, Referer and cookies never ride.
|
|
6341
|
+
passthroughHeaders: ["^authorization$", "^accept$"],
|
|
6342
|
+
jsonCardFields: [["payment", "credit_card", "number"]],
|
|
6343
|
+
// A payment with no new card on the same URL continues untouched (bigcommerceBodyVerdict says which).
|
|
6344
|
+
passWithoutCard: "payments\\.bigcommerce\\.com/api/public/v1/orders/payments"
|
|
6345
|
+
}
|
|
6346
|
+
],
|
|
6347
|
+
// The request charges the store's gateway at once, so only the cardholder's device sends it, after a person approves.
|
|
6348
|
+
refusedOperations: [BIGCOMMERCE_OPERATION],
|
|
6349
|
+
// Not surveyed: reading a BigCommerce payment back takes the store's own API credentials, which Agentcard never holds.
|
|
6350
|
+
settlementReadback: "not_surveyed",
|
|
6351
|
+
exactUrl: isBigcommercePaymentsUrl,
|
|
6352
|
+
bodyGate: (url, body) => bigcommerceBodyVerdict(body, url),
|
|
6353
|
+
amount: bigcommerceAmount
|
|
6354
|
+
});
|
|
6174
6355
|
// src/processors/bluesnap.js
|
|
6175
6356
|
var BLUESNAP_PSP = "bluesnap";
|
|
6176
6357
|
var BLUESNAP_OPERATION = "bluesnap.card_request";
|
|
@@ -6178,16 +6359,16 @@ var BLUESNAP_HOSTS = /* @__PURE__ */ Object.freeze({ 1: "ws1.bluesnap.com", 2: "
|
|
|
6178
6359
|
var BLUESNAP_SANDBOX_HOST = "sandpay.bluesnap.com";
|
|
6179
6360
|
var BLUESNAP_CARD_KEYS = /* @__PURE__ */ Object.freeze(["cvv", "ccNumber", "expDate"]);
|
|
6180
6361
|
var BLUESNAP_LEG_KEYS = /* @__PURE__ */ Object.freeze(["cvv", "expDate"]);
|
|
6181
|
-
var
|
|
6362
|
+
var BODY_LIMIT37 = 1024;
|
|
6182
6363
|
var TOKEN_URL2 = /^https:\/\/(ws1|ws2|sandpay)\.bluesnap\.com\/services\/2\/payment-fields-tokens\/([0-9a-f]{64}_[12]?)$/;
|
|
6183
6364
|
var CARD_NUMBER18 = /^[0-9]{12,19}$/;
|
|
6184
6365
|
var SECURITY_CODE22 = /^[0-9]{3,4}$/;
|
|
6185
6366
|
var EXPIRY3 = /^(?:0[1-9]|1[0-2])\/20[0-9]{2}$/;
|
|
6186
6367
|
var SAVED_CARD_KEYS2 = ["last4Digits", "lastFourDigits", "ccType"];
|
|
6187
|
-
var
|
|
6188
|
-
var
|
|
6189
|
-
var
|
|
6190
|
-
var
|
|
6368
|
+
var record33 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
6369
|
+
var own13 = (value, key) => Object.prototype.hasOwnProperty.call(value, key);
|
|
6370
|
+
var refuse39 = (code) => Object.freeze({ verdict: "refuse", code });
|
|
6371
|
+
var CARD38 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
|
|
6191
6372
|
var LEG = /* @__PURE__ */ Object.freeze({ verdict: "continue" });
|
|
6192
6373
|
function bluesnapTokenUrl(url) {
|
|
6193
6374
|
const match = typeof url === "string" ? TOKEN_URL2.exec(url) : null;
|
|
@@ -6199,30 +6380,30 @@ function bluesnapTokenUrl(url) {
|
|
|
6199
6380
|
function isBluesnapTokenUrl(url) {
|
|
6200
6381
|
return bluesnapTokenUrl(url) !== null;
|
|
6201
6382
|
}
|
|
6202
|
-
function
|
|
6203
|
-
if (typeof body !== "string" || body === "" || body.length >
|
|
6383
|
+
function readBody23(body) {
|
|
6384
|
+
if (typeof body !== "string" || body === "" || body.length > BODY_LIMIT37)
|
|
6204
6385
|
return null;
|
|
6205
6386
|
try {
|
|
6206
6387
|
const value = JSON.parse(body);
|
|
6207
|
-
return
|
|
6388
|
+
return record33(value) && JSON.stringify(value) === body ? value : null;
|
|
6208
6389
|
}
|
|
6209
6390
|
catch {
|
|
6210
6391
|
return null;
|
|
6211
6392
|
}
|
|
6212
6393
|
}
|
|
6213
6394
|
function bluesnapBodyVerdict(body) {
|
|
6214
|
-
const value =
|
|
6395
|
+
const value = readBody23(body);
|
|
6215
6396
|
if (value === null)
|
|
6216
|
-
return
|
|
6397
|
+
return refuse39("bluesnap_body_unsupported");
|
|
6217
6398
|
const keys = Object.keys(value);
|
|
6218
6399
|
if (keys.some((key) => SAVED_CARD_KEYS2.includes(key)))
|
|
6219
|
-
return
|
|
6400
|
+
return refuse39(own13(value, "ccNumber") ? "bluesnap_body_unsupported" : "bluesnap_saved_card");
|
|
6220
6401
|
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
|
|
6402
|
+
return refuse39("bluesnap_body_unsupported");
|
|
6222
6403
|
}
|
|
6223
|
-
if (
|
|
6224
|
-
return
|
|
6225
|
-
return
|
|
6404
|
+
if (own13(value, "ccNumber") && !(typeof value.ccNumber === "string" && CARD_NUMBER18.test(value.ccNumber)) || own13(value, "cvv") && !(typeof value.cvv === "string" && SECURITY_CODE22.test(value.cvv)) || own13(value, "expDate") && !(typeof value.expDate === "string" && EXPIRY3.test(value.expDate)))
|
|
6405
|
+
return refuse39("bluesnap_body_unsupported");
|
|
6406
|
+
return own13(value, "ccNumber") ? CARD38 : LEG;
|
|
6226
6407
|
}
|
|
6227
6408
|
var bluesnap_default = /* @__PURE__ */ registerProcessor({
|
|
6228
6409
|
psp: BLUESNAP_PSP,
|
|
@@ -6256,65 +6437,981 @@ var bluesnap_default = /* @__PURE__ */ registerProcessor({
|
|
|
6256
6437
|
exactUrl: isBluesnapTokenUrl,
|
|
6257
6438
|
bodyGate: (url, body) => url !== void 0 && !isBluesnapTokenUrl(url) ? { verdict: "refuse", code: "bluesnap_url_refused" } : bluesnapBodyVerdict(body)
|
|
6258
6439
|
});
|
|
6259
|
-
// src/processors/
|
|
6260
|
-
var
|
|
6261
|
-
var
|
|
6262
|
-
var
|
|
6263
|
-
|
|
6264
|
-
|
|
6265
|
-
"
|
|
6266
|
-
"
|
|
6267
|
-
"
|
|
6268
|
-
"
|
|
6269
|
-
"
|
|
6270
|
-
"
|
|
6271
|
-
"
|
|
6272
|
-
"
|
|
6273
|
-
"
|
|
6440
|
+
// src/processors/ekashu.js
|
|
6441
|
+
var EKASHU_HOSTS = Object.freeze(["live.ekashu.com", "test.ekashu.com"]);
|
|
6442
|
+
var EKASHU_TEST_PANS = Object.freeze(["4100000000000100", "5100000000000107"]);
|
|
6443
|
+
var EKASHU_SIGNED_FIELDS = Object.freeze([
|
|
6444
|
+
"ekashu_3d_secure_verify",
|
|
6445
|
+
"ekashu_amount",
|
|
6446
|
+
"ekashu_amount_format",
|
|
6447
|
+
"ekashu_auto_confirm",
|
|
6448
|
+
"ekashu_callback_failure_url",
|
|
6449
|
+
"ekashu_callback_include_post",
|
|
6450
|
+
"ekashu_callback_success_url",
|
|
6451
|
+
"ekashu_card_address_editable",
|
|
6452
|
+
"ekashu_card_address_required",
|
|
6453
|
+
"ekashu_card_address_verify",
|
|
6454
|
+
"ekashu_card_email_address_mandatory",
|
|
6455
|
+
"ekashu_card_phone_number_mandatory",
|
|
6456
|
+
"ekashu_card_title_mandatory",
|
|
6457
|
+
"ekashu_card_zip_code_verify",
|
|
6458
|
+
"ekashu_currency",
|
|
6459
|
+
"ekashu_delivery_address_editable",
|
|
6460
|
+
"ekashu_delivery_address_required",
|
|
6461
|
+
"ekashu_delivery_email_address_mandatory",
|
|
6462
|
+
"ekashu_delivery_phone_number_mandatory",
|
|
6463
|
+
"ekashu_delivery_title_mandatory",
|
|
6464
|
+
"ekashu_description",
|
|
6465
|
+
"ekashu_device",
|
|
6466
|
+
"ekashu_duplicate_check",
|
|
6467
|
+
"ekashu_duplicate_minutes",
|
|
6468
|
+
"ekashu_failure_return_text",
|
|
6469
|
+
"ekashu_failure_url",
|
|
6470
|
+
"ekashu_hash_code_format",
|
|
6471
|
+
"ekashu_hash_code_type",
|
|
6472
|
+
"ekashu_hash_code_version",
|
|
6473
|
+
"ekashu_include_post",
|
|
6474
|
+
"ekashu_invoice_address_editable",
|
|
6475
|
+
"ekashu_invoice_address_required",
|
|
6476
|
+
"ekashu_invoice_email_address_mandatory",
|
|
6477
|
+
"ekashu_invoice_phone_number_mandatory",
|
|
6478
|
+
"ekashu_invoice_title_mandatory",
|
|
6479
|
+
"ekashu_locale",
|
|
6480
|
+
"ekashu_payment_methods",
|
|
6481
|
+
"ekashu_reference",
|
|
6482
|
+
"ekashu_request_type",
|
|
6483
|
+
"ekashu_return_text",
|
|
6484
|
+
"ekashu_seller_address",
|
|
6485
|
+
"ekashu_seller_email_address",
|
|
6486
|
+
"ekashu_seller_id",
|
|
6487
|
+
"ekashu_seller_key",
|
|
6488
|
+
"ekashu_seller_name",
|
|
6489
|
+
"ekashu_shortcut_icon",
|
|
6490
|
+
"ekashu_style_sheet",
|
|
6491
|
+
"ekashu_success_url",
|
|
6492
|
+
"ekashu_title",
|
|
6493
|
+
"ekashu_verification_value_mask",
|
|
6494
|
+
"ekashu_verification_value_verify",
|
|
6495
|
+
"ekashu_viewport"
|
|
6274
6496
|
]);
|
|
6275
|
-
var
|
|
6276
|
-
"
|
|
6277
|
-
"
|
|
6278
|
-
"
|
|
6279
|
-
"
|
|
6280
|
-
"
|
|
6281
|
-
"
|
|
6282
|
-
"
|
|
6497
|
+
var REQUIRED = Object.freeze([
|
|
6498
|
+
"ekashu_seller_id",
|
|
6499
|
+
"ekashu_seller_key",
|
|
6500
|
+
"ekashu_amount",
|
|
6501
|
+
"ekashu_currency",
|
|
6502
|
+
"ekashu_reference",
|
|
6503
|
+
"ekashu_hash_code",
|
|
6504
|
+
"ekashu_hash_code_type",
|
|
6505
|
+
"ekashu_hash_code_version",
|
|
6506
|
+
"ekashu_success_url",
|
|
6507
|
+
"ekashu_failure_url",
|
|
6508
|
+
"ekashu_callback_success_url"
|
|
6283
6509
|
]);
|
|
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
|
-
|
|
6510
|
+
var CARD_KEYS17 = Object.freeze([
|
|
6511
|
+
"ekashu_card_number",
|
|
6512
|
+
"ekashu_expires_end_month",
|
|
6513
|
+
"ekashu_expires_end_year",
|
|
6514
|
+
"ekashu_verification_value",
|
|
6515
|
+
"ekashu_valid_from_month",
|
|
6516
|
+
"ekashu_valid_from_year",
|
|
6517
|
+
"ekashu_issue_number"
|
|
6518
|
+
]);
|
|
6519
|
+
var PAGE_KEYS = Object.freeze(["ekashu_stage", "ekashu_context", "ekashu_submission_id"]);
|
|
6520
|
+
var STORED_KEYS = Object.freeze(["ekashu_card_hash", "ekashu_card_reference", "ekashu_cof_initiated_by", "ekashu_cof_reason", "ekashu_cof_id"]);
|
|
6521
|
+
var REDIRECT_KEYS = Object.freeze(["ekashu_success_url", "ekashu_failure_url", "ekashu_return_url"]);
|
|
6522
|
+
var CALLBACK_KEYS = Object.freeze(["ekashu_callback_success_url", "ekashu_callback_failure_url"]);
|
|
6523
|
+
var MAX_ENTRY = 16 * 1024;
|
|
6524
|
+
var MAX_PAGE = 256 * 1024;
|
|
6525
|
+
var EKASHU_SELLERS = Object.freeze([
|
|
6526
|
+
Object.freeze({ sellerId: "25060100", merchant: "Heathrow Drop-off", entryHost: "heathrowdropoff.apcoa.com", callbackHost: "incomingapi.apcoa.co.uk" })
|
|
6527
|
+
]);
|
|
6528
|
+
var CARD_FIELDS = Object.freeze({
|
|
6529
|
+
number: "ekashu_card_number",
|
|
6530
|
+
month: "ekashu_expires_end_month",
|
|
6531
|
+
year: "ekashu_expires_end_year",
|
|
6532
|
+
cvc: "ekashu_verification_value"
|
|
6533
|
+
});
|
|
6534
|
+
var NAME_FIELDS = Object.freeze({ first: "ekashu_card_first_name", last: "ekashu_card_last_name" });
|
|
6535
|
+
var LEFT_EMPTY = Object.freeze(["ekashu_card_title", "ekashu_valid_from_month", "ekashu_valid_from_year", "ekashu_issue_number"]);
|
|
6536
|
+
var VISIBLE = /* @__PURE__ */ new Set([...Object.values(CARD_FIELDS), ...Object.values(NAME_FIELDS), ...LEFT_EMPTY]);
|
|
6537
|
+
// src/processors/redsys.js
|
|
6538
|
+
var REDSYS_HOSTS = Object.freeze(["sis.redsys.es"]);
|
|
6539
|
+
var REDSYS_ENTRY_PATHS = Object.freeze(["/sis/realizarPago", "/sis/realizarPago/utf-8"]);
|
|
6540
|
+
var REDSYS_MERCHANTS = Object.freeze([]);
|
|
6541
|
+
var MAX_ENTRY2 = 16 * 1024;
|
|
6542
|
+
var MAX_PARAMETERS = 8 * 1024;
|
|
6543
|
+
var FORM_KEY = /^[A-Za-z][A-Za-z0-9_-]{0,63}$/;
|
|
6544
|
+
var ENTRY_KEYS = Object.freeze(["Ds_SignatureVersion", "Ds_MerchantParameters", "Ds_Signature"]);
|
|
6545
|
+
var REQUIRED2 = Object.freeze([
|
|
6546
|
+
"DS_MERCHANT_AMOUNT",
|
|
6547
|
+
"DS_MERCHANT_CURRENCY",
|
|
6548
|
+
"DS_MERCHANT_MERCHANTCODE",
|
|
6549
|
+
"DS_MERCHANT_ORDER",
|
|
6550
|
+
"DS_MERCHANT_TERMINAL",
|
|
6551
|
+
"DS_MERCHANT_TRANSACTIONTYPE",
|
|
6552
|
+
"DS_MERCHANT_MERCHANTURL",
|
|
6553
|
+
"DS_MERCHANT_URLOK",
|
|
6554
|
+
"DS_MERCHANT_URLKO"
|
|
6555
|
+
]);
|
|
6556
|
+
var STORED = Object.freeze([
|
|
6557
|
+
"DS_MERCHANT_IDENTIFIER",
|
|
6558
|
+
"DS_MERCHANT_GROUP",
|
|
6559
|
+
"DS_MERCHANT_COF_INI",
|
|
6560
|
+
"DS_MERCHANT_COF_TYPE",
|
|
6561
|
+
"DS_MERCHANT_COF_TXNID"
|
|
6562
|
+
]);
|
|
6563
|
+
var SPECIAL = Object.freeze([
|
|
6564
|
+
"DS_MERCHANT_DIRECTPAYMENT",
|
|
6565
|
+
"DS_MERCHANT_SUMTOTAL",
|
|
6566
|
+
"DS_MERCHANT_DATEFRECUENCY",
|
|
6567
|
+
"DS_MERCHANT_CHARGEEXPIRYDATE",
|
|
6568
|
+
"DS_MERCHANT_IDOPER"
|
|
6569
|
+
]);
|
|
6570
|
+
var CARD_PARAMETERS = Object.freeze(["DS_MERCHANT_PAN", "DS_MERCHANT_EXPIRYDATE", "DS_MERCHANT_CVV2"]);
|
|
6571
|
+
var CURRENCIES = Object.freeze({ 978: "eur", 840: "usd", 826: "gbp", 756: "chf" });
|
|
6572
|
+
function decode(text11) {
|
|
6573
|
+
return decodeURIComponent(text11.replace(/\+/g, " "));
|
|
6574
|
+
}
|
|
6575
|
+
function parseRedsysForm(body) {
|
|
6576
|
+
if (typeof body !== "string" || body.length === 0 || body.length > MAX_ENTRY2 || /[^\x21-\x7e]/.test(body))
|
|
6577
|
+
return null;
|
|
6578
|
+
const pairs = [];
|
|
6579
|
+
const seen = /* @__PURE__ */ new Set();
|
|
6580
|
+
for (const chunk of body.split("&")) {
|
|
6581
|
+
const eq = chunk.indexOf("=");
|
|
6582
|
+
if (eq < 1)
|
|
6583
|
+
return null;
|
|
6584
|
+
let key;
|
|
6585
|
+
let value;
|
|
6586
|
+
try {
|
|
6587
|
+
key = decode(chunk.slice(0, eq));
|
|
6588
|
+
value = decode(chunk.slice(eq + 1));
|
|
6589
|
+
}
|
|
6590
|
+
catch {
|
|
6591
|
+
return null;
|
|
6592
|
+
}
|
|
6593
|
+
if (!FORM_KEY.test(key) || value.length > MAX_PARAMETERS || /[\u0000-\u001f\u007f]/.test(value))
|
|
6594
|
+
return null;
|
|
6595
|
+
const folded = key.toLowerCase();
|
|
6596
|
+
if (seen.has(folded))
|
|
6597
|
+
return null;
|
|
6598
|
+
seen.add(folded);
|
|
6599
|
+
pairs.push({ key, value });
|
|
6304
6600
|
}
|
|
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);
|
|
6601
|
+
return pairs;
|
|
6311
6602
|
}
|
|
6312
|
-
|
|
6313
|
-
|
|
6603
|
+
var MAX_PAGE2 = 256 * 1024;
|
|
6604
|
+
var CARD_FIELDS2 = Object.freeze({
|
|
6605
|
+
shown: "Sis_card-number",
|
|
6606
|
+
expiry: "SIS_card-expiration",
|
|
6607
|
+
cvc: "Sis_Tarjeta_CVV2",
|
|
6608
|
+
holder: "cardholderName",
|
|
6609
|
+
number: "Sis_Numero_Tarjeta",
|
|
6610
|
+
month: "Sis_Caducidad_Tarjeta_Mes",
|
|
6611
|
+
year: "Sis_Caducidad_Tarjeta_Anno"
|
|
6612
|
+
});
|
|
6613
|
+
var BROWSER_FIELDS = Object.freeze([
|
|
6614
|
+
"browserJavaEnabled",
|
|
6615
|
+
"browserJavascriptEnabled",
|
|
6616
|
+
"browserLanguage",
|
|
6617
|
+
"browserColorDepth",
|
|
6618
|
+
"browserScreenHeight",
|
|
6619
|
+
"browserScreenWidth",
|
|
6620
|
+
"browserTZ",
|
|
6621
|
+
"browserUserAgent"
|
|
6622
|
+
]);
|
|
6623
|
+
var AS_SERVED = Object.freeze(["cvvObligatorio", "threeDSCompInd", "fuc", "terminal", "merchantOrder", "bcancel"]);
|
|
6624
|
+
var CARD_PAGE = /* @__PURE__ */ new Set([...Object.values(CARD_FIELDS2), ...BROWSER_FIELDS, ...AS_SERVED]);
|
|
6625
|
+
var VISIBLE2 = /* @__PURE__ */ new Set([CARD_FIELDS2.shown, CARD_FIELDS2.expiry, CARD_FIELDS2.cvc, CARD_FIELDS2.holder]);
|
|
6626
|
+
var METHOD_PAGE = /* @__PURE__ */ new Set(["resultadoMethod", ...BROWSER_FIELDS, "threeDSCompInd"]);
|
|
6627
|
+
var REDSYS_REFUSALS = Object.freeze(["redsys_card_page", "redsys_3ds_challenge", "redsys_declined"]);
|
|
6628
|
+
// src/processors/cardlink_vpos.js
|
|
6629
|
+
var CARDLINK_VPOS_PSP = "cardlink_vpos";
|
|
6630
|
+
var CARDLINK_VPOS_HOSTS = Object.freeze({
|
|
6631
|
+
"vpos.eurocommerce.gr": "worldline",
|
|
6632
|
+
"ecommerce.cardlink.gr": "cardlink",
|
|
6633
|
+
"www.alphaecommerce.gr": "nexi"
|
|
6634
|
+
});
|
|
6635
|
+
var CARDLINK_VPOS_TEST_HOSTS = Object.freeze([
|
|
6636
|
+
"eurocommerce-test.cardlink.gr",
|
|
6637
|
+
"ecommerce-test.cardlink.gr",
|
|
6638
|
+
"alphaecommerce-test.cardlink.gr"
|
|
6639
|
+
]);
|
|
6640
|
+
var CARDLINK_VPOS_ENTRY_PATH = "/vpos/shophandlermpi";
|
|
6641
|
+
var CARDLINK_VPOS_MERCHANTS = Object.freeze([
|
|
6642
|
+
Object.freeze({ merchant: "Holy Great Monastery of Vatopedi", mid: "0021713862", vposHost: "vpos.eurocommerce.gr", host: "www.vatopedi.gr" })
|
|
6643
|
+
]);
|
|
6644
|
+
var CARDLINK_VPOS_ENTRY_FIELDS = Object.freeze([
|
|
6645
|
+
"version",
|
|
6646
|
+
"mid",
|
|
6647
|
+
"lang",
|
|
6648
|
+
"deviceCategory",
|
|
6649
|
+
"orderid",
|
|
6650
|
+
"orderDesc",
|
|
6651
|
+
"orderAmount",
|
|
6652
|
+
"currency",
|
|
6653
|
+
"payerEmail",
|
|
6654
|
+
"payerPhone",
|
|
6655
|
+
"billCountry",
|
|
6656
|
+
"billState",
|
|
6657
|
+
"billZip",
|
|
6658
|
+
"billCity",
|
|
6659
|
+
"billAddress",
|
|
6660
|
+
"weight",
|
|
6661
|
+
"dimensions",
|
|
6662
|
+
"shipCountry",
|
|
6663
|
+
"shipState",
|
|
6664
|
+
"shipZip",
|
|
6665
|
+
"shipCity",
|
|
6666
|
+
"shipAddress",
|
|
6667
|
+
"addFraudScore",
|
|
6668
|
+
"maxPayRetries",
|
|
6669
|
+
"reject3dsU",
|
|
6670
|
+
"payMethod",
|
|
6671
|
+
"trType",
|
|
6672
|
+
"extInstallmentoffset",
|
|
6673
|
+
"extInstallmentperiod",
|
|
6674
|
+
"extRecurringfrequency",
|
|
6675
|
+
"extRecurringenddate",
|
|
6676
|
+
"blockScore",
|
|
6677
|
+
"cssUrl",
|
|
6678
|
+
"confirmUrl",
|
|
6679
|
+
"cancelUrl",
|
|
6680
|
+
"extTokenOptions",
|
|
6681
|
+
"extToken",
|
|
6682
|
+
"var1",
|
|
6683
|
+
"var2",
|
|
6684
|
+
"var3",
|
|
6685
|
+
"var4",
|
|
6686
|
+
"var5",
|
|
6687
|
+
"var6",
|
|
6688
|
+
"var7",
|
|
6689
|
+
"var8",
|
|
6690
|
+
"var9",
|
|
6691
|
+
"digest"
|
|
6692
|
+
]);
|
|
6693
|
+
var KNOWN = new Set(CARDLINK_VPOS_ENTRY_FIELDS);
|
|
6694
|
+
var REQUIRED3 = Object.freeze([
|
|
6695
|
+
"version",
|
|
6696
|
+
"mid",
|
|
6697
|
+
"orderid",
|
|
6698
|
+
"orderDesc",
|
|
6699
|
+
"orderAmount",
|
|
6700
|
+
"currency",
|
|
6701
|
+
"payerEmail",
|
|
6702
|
+
"confirmUrl",
|
|
6703
|
+
"cancelUrl",
|
|
6704
|
+
"digest"
|
|
6705
|
+
]);
|
|
6706
|
+
var STORED2 = Object.freeze(["extTokenOptions", "extToken"]);
|
|
6707
|
+
var SPECIAL2 = Object.freeze(["extInstallmentoffset", "extInstallmentperiod", "extRecurringfrequency", "extRecurringenddate"]);
|
|
6708
|
+
var CURRENCIES2 = Object.freeze({ EUR: "eur" });
|
|
6709
|
+
var MAX_URL = 512;
|
|
6710
|
+
var MAX_ENTRY3 = 8 * 1024;
|
|
6711
|
+
var MAX_VALUE = 256;
|
|
6712
|
+
var own14 = (value, key) => Object.prototype.hasOwnProperty.call(value, key);
|
|
6713
|
+
var field2 = (name, reason) => ({ ok: false, code: "hosted_form_field_refused", field: name, reason });
|
|
6714
|
+
function cardlinkVposEntryHost(raw) {
|
|
6715
|
+
if (typeof raw !== "string" || raw.length > MAX_URL || raw.includes("?") || raw.includes("#"))
|
|
6314
6716
|
return null;
|
|
6717
|
+
let url;
|
|
6315
6718
|
try {
|
|
6316
|
-
|
|
6317
|
-
|
|
6719
|
+
url = new URL(raw);
|
|
6720
|
+
}
|
|
6721
|
+
catch {
|
|
6722
|
+
return null;
|
|
6723
|
+
}
|
|
6724
|
+
if (url.href !== raw || url.protocol !== "https:" || url.port || url.username || url.password || !own14(CARDLINK_VPOS_HOSTS, url.hostname) || url.pathname !== CARDLINK_VPOS_ENTRY_PATH)
|
|
6725
|
+
return null;
|
|
6726
|
+
return url.hostname;
|
|
6727
|
+
}
|
|
6728
|
+
function isCardlinkVposEntryUrl(raw) {
|
|
6729
|
+
return cardlinkVposEntryHost(raw) !== null;
|
|
6730
|
+
}
|
|
6731
|
+
function parseCardlinkVposForm(body) {
|
|
6732
|
+
if (typeof body !== "string" || body.length === 0 || body.length > MAX_ENTRY3 || /[^\x21-\x7e]/.test(body))
|
|
6733
|
+
return null;
|
|
6734
|
+
const pairs = [];
|
|
6735
|
+
const seen = /* @__PURE__ */ new Set();
|
|
6736
|
+
for (const chunk of body.split("&")) {
|
|
6737
|
+
const eq = chunk.indexOf("=");
|
|
6738
|
+
if (eq < 1)
|
|
6739
|
+
return null;
|
|
6740
|
+
let key;
|
|
6741
|
+
let value;
|
|
6742
|
+
try {
|
|
6743
|
+
key = decodeURIComponent(chunk.slice(0, eq).replace(/\+/g, " "));
|
|
6744
|
+
value = decodeURIComponent(chunk.slice(eq + 1).replace(/\+/g, " "));
|
|
6745
|
+
}
|
|
6746
|
+
catch {
|
|
6747
|
+
return null;
|
|
6748
|
+
}
|
|
6749
|
+
if (!/^[A-Za-z_.][A-Za-z0-9_.-]{0,63}$/.test(key) || value.length > MAX_VALUE || /[\u0000-\u001f\u007f]/.test(value))
|
|
6750
|
+
return null;
|
|
6751
|
+
if (seen.has(key))
|
|
6752
|
+
return null;
|
|
6753
|
+
seen.add(key);
|
|
6754
|
+
pairs.push({ key, value });
|
|
6755
|
+
}
|
|
6756
|
+
return pairs;
|
|
6757
|
+
}
|
|
6758
|
+
function cardlinkVposMerchant(mid, vposHost, merchants = CARDLINK_VPOS_MERCHANTS) {
|
|
6759
|
+
if (typeof mid !== "string" || typeof vposHost !== "string" || !Array.isArray(merchants))
|
|
6760
|
+
return null;
|
|
6761
|
+
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 !== "");
|
|
6762
|
+
return found.length === 1 ? found[0] : null;
|
|
6763
|
+
}
|
|
6764
|
+
function entryAmount(values) {
|
|
6765
|
+
const amount2 = values.get("orderAmount");
|
|
6766
|
+
const code = values.get("currency");
|
|
6767
|
+
const currency = typeof code === "string" && own14(CURRENCIES2, code) ? CURRENCIES2[code] : null;
|
|
6768
|
+
if (!currency || typeof amount2 !== "string" || !/^(?:0|[1-9]\d{0,11})(?:\.\d{1,2})?$/.test(amount2))
|
|
6769
|
+
return null;
|
|
6770
|
+
const [whole2, fraction = ""] = amount2.split(".");
|
|
6771
|
+
const cents2 = Number(whole2) * 100 + Number(fraction.padEnd(2, "0"));
|
|
6772
|
+
return Number.isSafeInteger(cents2) && cents2 > 0 ? { amountCents: cents2, currency } : null;
|
|
6773
|
+
}
|
|
6774
|
+
function httpsUrl(value) {
|
|
6775
|
+
let url;
|
|
6776
|
+
try {
|
|
6777
|
+
url = new URL(value);
|
|
6778
|
+
}
|
|
6779
|
+
catch {
|
|
6780
|
+
return null;
|
|
6781
|
+
}
|
|
6782
|
+
if (url.protocol !== "https:" || url.username || url.password || url.port || url.hash)
|
|
6783
|
+
return null;
|
|
6784
|
+
return url;
|
|
6785
|
+
}
|
|
6786
|
+
function checkCardlinkVposEntry(body, { url = null, merchants = CARDLINK_VPOS_MERCHANTS } = {}) {
|
|
6787
|
+
const vposHost = cardlinkVposEntryHost(url);
|
|
6788
|
+
if (!vposHost)
|
|
6789
|
+
return field2("(url)", "malformed_field");
|
|
6790
|
+
const pairs = parseCardlinkVposForm(body);
|
|
6791
|
+
if (!pairs)
|
|
6792
|
+
return field2("(body)", "malformed");
|
|
6793
|
+
const values = new Map(pairs.map(({ key, value }) => [key, value]));
|
|
6794
|
+
for (const { key } of pairs) {
|
|
6795
|
+
if (KNOWN.has(key))
|
|
6796
|
+
continue;
|
|
6797
|
+
return field2(key, /^(?:card[._]|cvv|cmd$|trid$|st$|paystep$|paymentmethod$)/i.test(key) ? "card_in_entry" : "not_an_entry");
|
|
6798
|
+
}
|
|
6799
|
+
const missing = REQUIRED3.filter((name) => !values.get(name));
|
|
6800
|
+
if (missing.length)
|
|
6801
|
+
return { ok: false, code: "hosted_form_template_incomplete", missing };
|
|
6802
|
+
if (values.get("version") !== "2")
|
|
6803
|
+
return field2("version", "malformed");
|
|
6804
|
+
if (!/^[A-Za-z0-9+/]{43}=$/.test(values.get("digest")))
|
|
6805
|
+
return field2("digest", "unsigned");
|
|
6806
|
+
for (const name of STORED2)
|
|
6807
|
+
if (values.has(name))
|
|
6808
|
+
return field2(name, "stored_credential");
|
|
6809
|
+
for (const name of SPECIAL2)
|
|
6810
|
+
if (values.get(name))
|
|
6811
|
+
return field2(name, "special_flow");
|
|
6812
|
+
for (let i = 1; i <= 9; i += 1)
|
|
6813
|
+
if (/moto\s*=\s*true/i.test(values.get(`var${i}`) ?? ""))
|
|
6814
|
+
return field2(`var${i}`, "moto");
|
|
6815
|
+
if (values.has("trType") && values.get("trType") !== "1")
|
|
6816
|
+
return field2("trType", "not_a_sale");
|
|
6817
|
+
const method = values.get("payMethod");
|
|
6818
|
+
if (method)
|
|
6819
|
+
return field2("payMethod", /^iris$/i.test(method) ? "not_a_card_payment" : "special_flow");
|
|
6820
|
+
const amount2 = entryAmount(values);
|
|
6821
|
+
if (!amount2)
|
|
6822
|
+
return field2(own14(CURRENCIES2, values.get("currency")) ? "orderAmount" : "currency", "malformed");
|
|
6823
|
+
if (!/^\d{1,30}$/.test(values.get("mid")))
|
|
6824
|
+
return field2("mid", "malformed");
|
|
6825
|
+
if (!/^[A-Za-z0-9]{1,50}$/.test(values.get("orderid")))
|
|
6826
|
+
return field2("orderid", "malformed");
|
|
6827
|
+
const seller = cardlinkVposMerchant(values.get("mid"), vposHost, merchants);
|
|
6828
|
+
if (!seller)
|
|
6829
|
+
return field2("mid", "seller_unreviewed");
|
|
6830
|
+
for (const name of ["confirmUrl", "cancelUrl"]) {
|
|
6831
|
+
const target = httpsUrl(values.get(name));
|
|
6832
|
+
if (!target || target.hostname !== seller.host)
|
|
6833
|
+
return field2(name, "callback_host");
|
|
6834
|
+
}
|
|
6835
|
+
return {
|
|
6836
|
+
ok: true,
|
|
6837
|
+
pairs,
|
|
6838
|
+
gated: false,
|
|
6839
|
+
dedupe: [vposHost, values.get("mid"), values.get("orderid"), values.get("orderAmount"), values.get("currency")],
|
|
6840
|
+
seller
|
|
6841
|
+
};
|
|
6842
|
+
}
|
|
6843
|
+
function cardlinkVposEntryAmount(body) {
|
|
6844
|
+
const pairs = parseCardlinkVposForm(body);
|
|
6845
|
+
return pairs ? entryAmount(new Map(pairs.map(({ key, value }) => [key, value]))) : null;
|
|
6846
|
+
}
|
|
6847
|
+
var CARDLINK_VPOS_TDS2_FIELDS = Object.freeze([
|
|
6848
|
+
"TDS2_Navigator_language",
|
|
6849
|
+
"TDS2_Navigator_jsEnabled",
|
|
6850
|
+
"TDS2_Navigator_javaEnabled",
|
|
6851
|
+
"TDS2_Screen_colorDepth",
|
|
6852
|
+
"TDS2_Screen_height",
|
|
6853
|
+
"TDS2_Screen_width",
|
|
6854
|
+
"TDS2_screen_pixelDepth",
|
|
6855
|
+
"TDS2_TimezoneOffset"
|
|
6856
|
+
]);
|
|
6857
|
+
var PAGE_FIELDS = Object.freeze(["trid", "st", "payStep", "cmd", "startbonus", "bonusdata"]);
|
|
6858
|
+
var WALLET_FIELDS2 = Object.freeze(["walletId", "applePayResponse"]);
|
|
6859
|
+
var CARD39 = Object.freeze({ number: "card.pan", holder: "card.holderName", month: "card.expiryMonth", year: "card.expiryYear", cvc: "card.cvv" });
|
|
6860
|
+
var TEXT_CONTROLS = /* @__PURE__ */ new Set([CARD39.number, CARD39.holder, CARD39.cvc]);
|
|
6861
|
+
var SELECT_CONTROLS = /* @__PURE__ */ new Set([CARD39.month, CARD39.year]);
|
|
6862
|
+
var MAX_PAGE3 = 256 * 1024;
|
|
6863
|
+
var COOKIE_DOMAINS = Object.freeze({
|
|
6864
|
+
"vpos.eurocommerce.gr": "eurocommerce.gr",
|
|
6865
|
+
"ecommerce.cardlink.gr": "cardlink.gr",
|
|
6866
|
+
"www.alphaecommerce.gr": "alphaecommerce.gr"
|
|
6867
|
+
});
|
|
6868
|
+
var POST_REQUIRED = Object.freeze(["trid", "st", "cmd", CARD39.number, CARD39.holder, CARD39.month, CARD39.year, CARD39.cvc, "makepayment"]);
|
|
6869
|
+
var POST_EMPTY = Object.freeze(["payStep", "startbonus", "bonusdata", ...WALLET_FIELDS2]);
|
|
6870
|
+
var POST_ALLOWED = /* @__PURE__ */ new Set([...POST_REQUIRED, ...POST_EMPTY, "paymentMethod", ...CARDLINK_VPOS_TDS2_FIELDS]);
|
|
6871
|
+
var CARDLINK_VPOS_REFUSALS = Object.freeze([
|
|
6872
|
+
"cardlink_vpos_card_refused",
|
|
6873
|
+
"cardlink_vpos_card_page",
|
|
6874
|
+
"cardlink_vpos_3ds_challenge",
|
|
6875
|
+
"cardlink_vpos_declined"
|
|
6876
|
+
]);
|
|
6877
|
+
var REFUSAL_FOR = Object.freeze({
|
|
6878
|
+
card_refused: "cardlink_vpos_card_refused",
|
|
6879
|
+
card_page: "cardlink_vpos_card_page",
|
|
6880
|
+
challenge: "cardlink_vpos_3ds_challenge",
|
|
6881
|
+
declined: "cardlink_vpos_declined"
|
|
6882
|
+
});
|
|
6883
|
+
var CARDLINK_VPOS_CAPABILITY = "cardlink_vpos_hosted_payment_page";
|
|
6884
|
+
var CARDLINK_VPOS_OPERATION = "cardlink_vpos.hosted_sale";
|
|
6885
|
+
var cardlink_vpos_default = /* @__PURE__ */ registerProcessor({
|
|
6886
|
+
psp: CARDLINK_VPOS_PSP,
|
|
6887
|
+
definitions: [
|
|
6888
|
+
{
|
|
6889
|
+
psp: "cardlink_vpos",
|
|
6890
|
+
// The merchant's signed entry, as the header above reads it: a Document navigation that carries no card. The
|
|
6891
|
+
// cardholder's device repeats it over the end-to-end TLS relay, fills the card into the page the VPOS returns
|
|
6892
|
+
// and posts it in that same session, and the runtime resolves the paused navigation with the hosted_form notice.
|
|
6893
|
+
// Only the entry path on the three live hosts is matched (isCardlinkVposEntryUrl). The card page posts to the same
|
|
6894
|
+
// path, so the SDK fails every other post to these hosts in the agent's browser, and no placeholder card reaches
|
|
6895
|
+
// the VPOS. The test hosts are listed so a live host classifies as live and the create refuses a test row there;
|
|
6896
|
+
// no entry on them is paused. Ships dark: served only to a client that declares
|
|
6897
|
+
// `cardlink_vpos_hosted_payment_page`, and gated off for every company the operator has not turned it on for.
|
|
6898
|
+
capability: CARDLINK_VPOS_CAPABILITY,
|
|
6899
|
+
match: "(?:vpos\\.eurocommerce\\.gr|ecommerce\\.cardlink\\.gr|www\\.alphaecommerce\\.gr)/vpos/shophandlermpi(?![\\w/.%;=!-])",
|
|
6900
|
+
hosts: [
|
|
6901
|
+
"^vpos\\.eurocommerce\\.gr$",
|
|
6902
|
+
"^ecommerce\\.cardlink\\.gr$",
|
|
6903
|
+
"^www\\.alphaecommerce\\.gr$",
|
|
6904
|
+
"^eurocommerce-test\\.cardlink\\.gr$",
|
|
6905
|
+
"^ecommerce-test\\.cardlink\\.gr$",
|
|
6906
|
+
"^alphaecommerce-test\\.cardlink\\.gr$"
|
|
6907
|
+
],
|
|
6908
|
+
sandboxHosts: ["^eurocommerce-test\\.cardlink\\.gr$", "^ecommerce-test\\.cardlink\\.gr$", "^alphaecommerce-test\\.cardlink\\.gr$"],
|
|
6909
|
+
hostEnvironmentPinned: true,
|
|
6910
|
+
encoding: "form",
|
|
6911
|
+
// A form navigation: no captured header is ever replayed.
|
|
6912
|
+
passthroughHeaders: [],
|
|
6913
|
+
mode: "hosted_form",
|
|
6914
|
+
hostedForm: {
|
|
6915
|
+
// The card goes into the VPOS's own page on the device, never into the entry, which must carry none
|
|
6916
|
+
// (checkCardlinkVposEntry). The entry's rules come with this registration (hostedEntry below), so no policy is
|
|
6917
|
+
// named here.
|
|
6918
|
+
cardIn: "processor_page",
|
|
6919
|
+
required: [...REQUIRED3],
|
|
6920
|
+
// The card page's own fields, which the device fills on that page.
|
|
6921
|
+
card: { number: "card.pan", month: "card.expiryMonth", year: "card.expiryYear", cvc: "card.cvv" },
|
|
6922
|
+
// The host, the mid, the order id and the amount name one payment; the entry's rules read the host from its URL.
|
|
6923
|
+
dedupe: ["(vposHost)", "mid", "orderid", "orderAmount", "currency"]
|
|
6924
|
+
}
|
|
6925
|
+
}
|
|
6926
|
+
],
|
|
6927
|
+
// Only the cardholder's device repeats an entry, after a person approves; no reviewed list names cardlink_vpos.
|
|
6928
|
+
refusedOperations: [CARDLINK_VPOS_OPERATION],
|
|
6929
|
+
// Not surveyed: the VPOS tells the merchant the result through the browser's return and a copy to its server, both
|
|
6930
|
+
// signed under the merchant's secret, which Agentcard never holds.
|
|
6931
|
+
settlementReadback: "not_surveyed",
|
|
6932
|
+
exactUrl: isCardlinkVposEntryUrl,
|
|
6933
|
+
hostedEntry: (body, { url }) => checkCardlinkVposEntry(body, { url }),
|
|
6934
|
+
amount: (template) => template && isCardlinkVposEntryUrl(template.url) ? cardlinkVposEntryAmount(template.body) : null,
|
|
6935
|
+
limitations: [
|
|
6936
|
+
"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.",
|
|
6937
|
+
"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.",
|
|
6938
|
+
"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.",
|
|
6939
|
+
"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.",
|
|
6940
|
+
"The browser receives a submission notice, not the processor result."
|
|
6941
|
+
]
|
|
6942
|
+
});
|
|
6943
|
+
// src/processors/eghl.js
|
|
6944
|
+
var EGHL_PSP = "eghl";
|
|
6945
|
+
var EGHL_OPERATION = "eghl.hosted_sale";
|
|
6946
|
+
var EGHL_HOST = "securepay.e-ghl.com";
|
|
6947
|
+
var EGHL_SANDBOX_HOST = "test2pay.ghl.com";
|
|
6948
|
+
var LIVE_PATH = "/ipg/payment.aspx";
|
|
6949
|
+
var SANDBOX_PATH = "/ipgsg/payment.aspx";
|
|
6950
|
+
var MAX_URL2 = 8192;
|
|
6951
|
+
var field3 = (name, reason) => ({ ok: false, code: "hosted_form_field_refused", field: name, reason });
|
|
6952
|
+
function eghlEntry(raw) {
|
|
6953
|
+
if (typeof raw !== "string" || raw.length > MAX_URL2 || raw.includes("#"))
|
|
6954
|
+
return null;
|
|
6955
|
+
let url;
|
|
6956
|
+
try {
|
|
6957
|
+
url = new URL(raw);
|
|
6958
|
+
}
|
|
6959
|
+
catch {
|
|
6960
|
+
return null;
|
|
6961
|
+
}
|
|
6962
|
+
if (url.href !== raw || url.protocol !== "https:" || url.port || url.username || url.password || url.search.length < 2)
|
|
6963
|
+
return null;
|
|
6964
|
+
const path = url.pathname.toLowerCase();
|
|
6965
|
+
const query = url.search.slice(1);
|
|
6966
|
+
if (url.hostname === EGHL_HOST && path === LIVE_PATH)
|
|
6967
|
+
return Object.freeze({ test: false, query });
|
|
6968
|
+
if (url.hostname === EGHL_SANDBOX_HOST && path === SANDBOX_PATH)
|
|
6969
|
+
return Object.freeze({ test: true, query });
|
|
6970
|
+
return null;
|
|
6971
|
+
}
|
|
6972
|
+
function isEghlEntryUrl(raw) {
|
|
6973
|
+
return eghlEntry(raw) !== null;
|
|
6974
|
+
}
|
|
6975
|
+
var EGHL_MERCHANTS = Object.freeze([
|
|
6976
|
+
Object.freeze({ merchant: "BookXcess", serviceId: "BXS", payee: "BookXcess Sdn Bhd", returnHosts: Object.freeze(["shopify.ghl.com:11443"]), test: false })
|
|
6977
|
+
]);
|
|
6978
|
+
var SERVICE_ID2 = /^[A-Za-z0-9]{3}$/;
|
|
6979
|
+
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})?$/;
|
|
6980
|
+
function eghlMerchant(serviceId, { test = false, merchants = EGHL_MERCHANTS } = {}) {
|
|
6981
|
+
if (typeof serviceId !== "string" || !SERVICE_ID2.test(serviceId) || !Array.isArray(merchants))
|
|
6982
|
+
return null;
|
|
6983
|
+
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)));
|
|
6984
|
+
return found.length === 1 ? found[0] : null;
|
|
6985
|
+
}
|
|
6986
|
+
var REQUIRED4 = Object.freeze([
|
|
6987
|
+
"TransactionType",
|
|
6988
|
+
"PymtMethod",
|
|
6989
|
+
"ServiceID",
|
|
6990
|
+
"PaymentID",
|
|
6991
|
+
"OrderNumber",
|
|
6992
|
+
"MerchantReturnURL",
|
|
6993
|
+
"MerchantCallBackURL",
|
|
6994
|
+
"Amount",
|
|
6995
|
+
"CurrencyCode",
|
|
6996
|
+
"HashValue"
|
|
6997
|
+
]);
|
|
6998
|
+
var CARD_KEYS18 = /* @__PURE__ */ new Set(["cardno", "cardexp", "cardcvv2", "cardholder", "param2", "param4", "cvv2", "epmonth2", "epyear2", "custocp"]);
|
|
6999
|
+
var SECRET_KEYS = /* @__PURE__ */ new Set(["password"]);
|
|
7000
|
+
var STORED_KEYS2 = /* @__PURE__ */ new Set([
|
|
7001
|
+
"tokentype",
|
|
7002
|
+
"token",
|
|
7003
|
+
"cardid",
|
|
7004
|
+
"precheckoutid",
|
|
7005
|
+
"reqtoken",
|
|
7006
|
+
"pairingtoken",
|
|
7007
|
+
"reqverifier",
|
|
7008
|
+
"pairingverifier",
|
|
7009
|
+
"checkoutresourceurl"
|
|
7010
|
+
]);
|
|
7011
|
+
var SPECIAL_KEYS = /* @__PURE__ */ new Set(["eppmonth", "promocode"]);
|
|
7012
|
+
var RESULT_KEYS = Object.freeze(["MerchantReturnURL", "MerchantCallBackURL", "MerchantApprovalURL", "MerchantUnApprovalURL"]);
|
|
7013
|
+
var CURRENCIES3 = /* @__PURE__ */ new Set(["MYR", "SGD", "USD", "PHP", "THB"]);
|
|
7014
|
+
var AMOUNT3 = /^(0|[1-9]\d{0,8})\.(\d{2})$/;
|
|
7015
|
+
function httpsUrl2(value) {
|
|
7016
|
+
let url;
|
|
7017
|
+
try {
|
|
7018
|
+
url = new URL(value);
|
|
7019
|
+
}
|
|
7020
|
+
catch {
|
|
7021
|
+
return null;
|
|
7022
|
+
}
|
|
7023
|
+
if (url.protocol !== "https:" || url.username || url.password || url.hash)
|
|
7024
|
+
return null;
|
|
7025
|
+
return url;
|
|
7026
|
+
}
|
|
7027
|
+
function entryFields(text11) {
|
|
7028
|
+
const pairs = parseRedsysForm(text11);
|
|
7029
|
+
if (!pairs)
|
|
7030
|
+
return null;
|
|
7031
|
+
return { pairs, values: new Map(pairs.map(({ key, value }) => [key.toLowerCase(), value])) };
|
|
7032
|
+
}
|
|
7033
|
+
function entryAmount2(values) {
|
|
7034
|
+
const currency = values.get("currencycode");
|
|
7035
|
+
const amount2 = AMOUNT3.exec(values.get("amount") ?? "");
|
|
7036
|
+
if (!amount2 || typeof currency !== "string" || !CURRENCIES3.has(currency))
|
|
7037
|
+
return null;
|
|
7038
|
+
const cents2 = Number(amount2[1]) * 100 + Number(amount2[2]);
|
|
7039
|
+
return cents2 > 0 && Number.isSafeInteger(cents2) ? { amountCents: cents2, currency: currency.toLowerCase() } : null;
|
|
7040
|
+
}
|
|
7041
|
+
function checkEghlEntry(body, { url = null, merchants = EGHL_MERCHANTS } = {}) {
|
|
7042
|
+
if (body !== void 0 && body !== null && body !== "")
|
|
7043
|
+
return field3("(body)", "not_an_entry");
|
|
7044
|
+
const entry = eghlEntry(url);
|
|
7045
|
+
if (!entry)
|
|
7046
|
+
return field3("(url)", "malformed_field");
|
|
7047
|
+
const fields = entryFields(entry.query);
|
|
7048
|
+
if (!fields)
|
|
7049
|
+
return field3("(query)", "malformed");
|
|
7050
|
+
const { pairs, values } = fields;
|
|
7051
|
+
for (const { key, value } of pairs) {
|
|
7052
|
+
if (value === "")
|
|
7053
|
+
continue;
|
|
7054
|
+
const folded = key.toLowerCase();
|
|
7055
|
+
if (CARD_KEYS18.has(folded))
|
|
7056
|
+
return field3(key, "card_in_entry");
|
|
7057
|
+
if (SECRET_KEYS.has(folded))
|
|
7058
|
+
return field3(key, "not_an_entry");
|
|
7059
|
+
if (STORED_KEYS2.has(folded))
|
|
7060
|
+
return field3(key, "stored_credential");
|
|
7061
|
+
if (SPECIAL_KEYS.has(folded))
|
|
7062
|
+
return field3(key, "special_flow");
|
|
7063
|
+
}
|
|
7064
|
+
const missing = REQUIRED4.filter((name) => !values.get(name.toLowerCase()));
|
|
7065
|
+
if (missing.length)
|
|
7066
|
+
return { ok: false, code: "hosted_form_template_incomplete", missing };
|
|
7067
|
+
if (values.get("transactiontype") !== "SALE")
|
|
7068
|
+
return field3("TransactionType", "not_a_sale");
|
|
7069
|
+
if (!["ANY", "CC"].includes(values.get("pymtmethod")))
|
|
7070
|
+
return field3("PymtMethod", "special_flow");
|
|
7071
|
+
if (!/^[0-9A-Fa-f]{64}$/.test(values.get("hashvalue")))
|
|
7072
|
+
return field3("HashValue", "unsigned");
|
|
7073
|
+
if (!entryAmount2(values))
|
|
7074
|
+
return field3(CURRENCIES3.has(values.get("currencycode")) ? "Amount" : "CurrencyCode", "malformed");
|
|
7075
|
+
if (!SERVICE_ID2.test(values.get("serviceid")))
|
|
7076
|
+
return field3("ServiceID", "malformed");
|
|
7077
|
+
if (!/^[A-Za-z0-9._-]{1,20}$/.test(values.get("paymentid")))
|
|
7078
|
+
return field3("PaymentID", "malformed");
|
|
7079
|
+
if (values.get("ordernumber").length > 20)
|
|
7080
|
+
return field3("OrderNumber", "malformed");
|
|
7081
|
+
const pageTimeout = values.get("pagetimeout");
|
|
7082
|
+
if (pageTimeout !== void 0 && !/^[1-9]\d{1,4}$/.test(pageTimeout))
|
|
7083
|
+
return field3("PageTimeout", "malformed");
|
|
7084
|
+
const seller = eghlMerchant(values.get("serviceid"), { test: entry.test, merchants });
|
|
7085
|
+
if (!seller)
|
|
7086
|
+
return field3("ServiceID", "seller_unreviewed");
|
|
7087
|
+
for (const name of RESULT_KEYS) {
|
|
7088
|
+
const value = values.get(name.toLowerCase());
|
|
7089
|
+
if (!value)
|
|
7090
|
+
continue;
|
|
7091
|
+
const target = httpsUrl2(value);
|
|
7092
|
+
if (!target || !seller.returnHosts.includes(target.host) || [EGHL_HOST, EGHL_SANDBOX_HOST].includes(target.hostname))
|
|
7093
|
+
return field3(name, "callback_host");
|
|
7094
|
+
}
|
|
7095
|
+
return { ok: true, pairs, gated: false, dedupe: [values.get("serviceid"), values.get("paymentid")], sandbox: entry.test, seller };
|
|
7096
|
+
}
|
|
7097
|
+
function eghlEntryAmount(body, url) {
|
|
7098
|
+
if (body !== void 0 && body !== null && body !== "")
|
|
7099
|
+
return null;
|
|
7100
|
+
const entry = eghlEntry(url);
|
|
7101
|
+
const fields = entry ? entryFields(entry.query) : null;
|
|
7102
|
+
return fields ? entryAmount2(fields.values) : null;
|
|
7103
|
+
}
|
|
7104
|
+
var MAX_PAGE4 = 1024 * 1024;
|
|
7105
|
+
var NEVER_SENT = new Set(["expressCheckoutType", "c2pRememberMeBrowser", "CustOCP", "CustRecurr", "CustAddress"].map((name) => name.toLowerCase()));
|
|
7106
|
+
var PAGE_REQUIRED = Object.freeze([
|
|
7107
|
+
"TransactionType",
|
|
7108
|
+
"ServiceID",
|
|
7109
|
+
"MerchantName",
|
|
7110
|
+
"PaymentID",
|
|
7111
|
+
"Amount",
|
|
7112
|
+
"BaseTxnAmount",
|
|
7113
|
+
"CurrencyCode",
|
|
7114
|
+
"BaseCurrencyCode",
|
|
7115
|
+
"HashValue",
|
|
7116
|
+
"Param2",
|
|
7117
|
+
"Param4",
|
|
7118
|
+
"CardExp",
|
|
7119
|
+
"CVV2",
|
|
7120
|
+
"PymtMethod"
|
|
7121
|
+
]);
|
|
7122
|
+
var EGHL_REFUSALS = Object.freeze(["eghl_failed", "eghl_cancelled"]);
|
|
7123
|
+
var MAX_ANSWER = 256 * 1024;
|
|
7124
|
+
var RESULT_FIELDS = Object.freeze(["TxnStatus", "ServiceID", "PaymentID", "Amount", "CurrencyCode"]);
|
|
7125
|
+
var eghl_default = /* @__PURE__ */ registerProcessor({
|
|
7126
|
+
psp: EGHL_PSP,
|
|
7127
|
+
definitions: [
|
|
7128
|
+
{
|
|
7129
|
+
psp: "eghl",
|
|
7130
|
+
// The merchant's entry to eGHL's payment page, as the header above reads it: a GET Document navigation whose
|
|
7131
|
+
// query names the payment and which carries no card. The cardholder's device repeats it over the end-to-end TLS
|
|
7132
|
+
// relay and pays on the page eGHL returns to it, and the runtime resolves the paused navigation with the
|
|
7133
|
+
// hosted_form notice. Only the entry is matched (isEghlEntryUrl): the card page's own card post goes to the same
|
|
7134
|
+
// path as a POST. The path is matched in any letter case, as IIS reads it; `(?![\\w/.%-])` ends it for a consumer
|
|
7135
|
+
// that tests `match` unanchored. Ships dark: served only to a client that declares `eghl_hosted_payment_page`, and
|
|
7136
|
+
// gated off for every company the operator has not allowlisted.
|
|
7137
|
+
capability: "eghl_hosted_payment_page",
|
|
7138
|
+
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/.%-])",
|
|
7139
|
+
hosts: ["^securepay\\.e-ghl\\.com$", "^test2pay\\.ghl\\.com$"],
|
|
7140
|
+
sandboxHosts: ["^test2pay\\.ghl\\.com$"],
|
|
7141
|
+
hostEnvironmentPinned: true,
|
|
7142
|
+
// `encoding` describes the card page's own card post, which the device makes as the page does, since the entry
|
|
7143
|
+
// has no body. No captured header is ever replayed.
|
|
7144
|
+
encoding: "form",
|
|
7145
|
+
passthroughHeaders: [],
|
|
7146
|
+
// The paused request is the navigation itself, a GET with the payment in its query.
|
|
7147
|
+
request: { method: "GET", cardIn: "processor_page", response: "document" },
|
|
7148
|
+
mode: "hosted_form",
|
|
7149
|
+
hostedForm: {
|
|
7150
|
+
// The card goes into eGHL's page on the device, never into the entry (checkEghlEntry refuses one there). The
|
|
7151
|
+
// entry's own rules come with this registration (hostedEntry below), so no policy is named here.
|
|
7152
|
+
cardIn: "processor_page",
|
|
7153
|
+
required: ["TransactionType", "PymtMethod", "ServiceID", "PaymentID", "OrderNumber", "MerchantReturnURL", "MerchantCallBackURL", "Amount", "CurrencyCode", "HashValue"],
|
|
7154
|
+
// The card page's own inputs in its card form (frmProcessPayment, read card free on 2026-11-05): the number in
|
|
7155
|
+
// Param2, the expiry in CardExp as YYYYMM, which the page builds from its month and year selects, the code in
|
|
7156
|
+
// CVV2. The cardholder's name goes in Param4.
|
|
7157
|
+
card: { number: "Param2", expiry: "CardExp", cvc: "CVV2" },
|
|
7158
|
+
// eGHL takes one PaymentID once per merchant.
|
|
7159
|
+
dedupe: ["ServiceID", "PaymentID"]
|
|
7160
|
+
}
|
|
7161
|
+
}
|
|
7162
|
+
],
|
|
7163
|
+
// Only the cardholder's device repeats an entry, after a person approves; no reviewed list names eghl.
|
|
7164
|
+
refusedOperations: [EGHL_OPERATION],
|
|
7165
|
+
// Not surveyed: eGHL tells the merchant's server the result (MerchantCallBackURL), and its return carries a hash only
|
|
7166
|
+
// the merchant can check.
|
|
7167
|
+
settlementReadback: "not_surveyed",
|
|
7168
|
+
exactUrl: isEghlEntryUrl,
|
|
7169
|
+
amount: (template) => template && typeof template === "object" ? eghlEntryAmount(template.body, template.url) : null,
|
|
7170
|
+
hostedEntry: (body, { url = null } = {}) => checkEghlEntry(body, { url }),
|
|
7171
|
+
limitations: [
|
|
7172
|
+
"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.",
|
|
7173
|
+
"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.",
|
|
7174
|
+
"eGHL runs 3-D Secure on the card. A challenge ends the payment on the device with nothing charged.",
|
|
7175
|
+
"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."
|
|
7176
|
+
]
|
|
7177
|
+
});
|
|
7178
|
+
// src/processors/frisbii.js
|
|
7179
|
+
var FRISBII_PSP = "frisbii";
|
|
7180
|
+
var FRISBII_OPERATION = "frisbii.card_request";
|
|
7181
|
+
var FRISBII_HOSTS = /* @__PURE__ */ Object.freeze({ "card.reepay.com": "reepay", "card.frisbii.com": "frisbii" });
|
|
7182
|
+
var FRISBII_TOKEN_PATH = "/v1/token/";
|
|
7183
|
+
var FRISBII_REFUSED_PATHS = /* @__PURE__ */ Object.freeze({
|
|
7184
|
+
"/v1/token/cof/": "frisbii_stored_card_unsupported",
|
|
7185
|
+
"/v1/token/create_click_to_pay": "frisbii_click_to_pay_unsupported"
|
|
7186
|
+
});
|
|
7187
|
+
var BODY_LIMIT38 = 8192;
|
|
7188
|
+
var URL_LIMIT15 = 256;
|
|
7189
|
+
var CARD_NUMBER19 = /^[0-9]{12,19}$/;
|
|
7190
|
+
var MONTH19 = /^(?:0[1-9]|1[0-2])$/;
|
|
7191
|
+
var YEAR20 = /^[0-9]{2}$/;
|
|
7192
|
+
var SECURITY_CODE23 = /^(?:[0-9]{3,4})?$/;
|
|
7193
|
+
var IDENTIFIER2 = /^[A-Za-z0-9_-]{8,128}$/;
|
|
7194
|
+
var SCA_RULES = /* @__PURE__ */ Object.freeze([
|
|
7195
|
+
"DO_NOT_USE_SCA",
|
|
7196
|
+
"MUST_USE_SCA_AUTH",
|
|
7197
|
+
"MUST_USE_SCA_PREAUTH",
|
|
7198
|
+
"USE_SCA_IF_AVAILABLE_AUTH",
|
|
7199
|
+
"USE_SCA_IF_AVAILABLE_PREAUTH"
|
|
7200
|
+
]);
|
|
7201
|
+
var BODY_ORDER = /* @__PURE__ */ Object.freeze([
|
|
7202
|
+
"number",
|
|
7203
|
+
"month",
|
|
7204
|
+
"year",
|
|
7205
|
+
"cvv",
|
|
7206
|
+
"cardTypeOverride",
|
|
7207
|
+
"click_to_pay_encrypt",
|
|
7208
|
+
"billing_address",
|
|
7209
|
+
"pkey",
|
|
7210
|
+
"recurring",
|
|
7211
|
+
"cardholder_name",
|
|
7212
|
+
"intent",
|
|
7213
|
+
"recurringAverageAmount",
|
|
7214
|
+
"agreementFilter",
|
|
7215
|
+
"strongAuthenticationRule",
|
|
7216
|
+
"tokenStrongAuthenticationRequest"
|
|
7217
|
+
]);
|
|
7218
|
+
var BODY_REQUIRED = /* @__PURE__ */ Object.freeze(["number", "month", "year", "cvv", "pkey", "recurring", "strongAuthenticationRule"]);
|
|
7219
|
+
var BODY_REFUSED = /* @__PURE__ */ Object.freeze(["cardTypeOverride", "click_to_pay_encrypt", "billing_address"]);
|
|
7220
|
+
var SCA_ORDER = /* @__PURE__ */ Object.freeze(["amount", "currency", "orderId", "orderText", "merchantScaData", "returnUrl", "tokenBrowserInfo"]);
|
|
7221
|
+
var BROWSER_ORDER = /* @__PURE__ */ Object.freeze([
|
|
7222
|
+
"javascriptEnabled",
|
|
7223
|
+
"challengeWindowSize",
|
|
7224
|
+
"colorDepth",
|
|
7225
|
+
"javaEnabled",
|
|
7226
|
+
"screenHeight",
|
|
7227
|
+
"screenWidth",
|
|
7228
|
+
"tz"
|
|
7229
|
+
]);
|
|
7230
|
+
var LABEL = /^[A-Za-z0-9_-]{1,64}$/;
|
|
7231
|
+
var record34 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
7232
|
+
var own15 = (value, key) => Object.prototype.hasOwnProperty.call(value, key);
|
|
7233
|
+
var refuse40 = (code) => Object.freeze({ verdict: "refuse", code });
|
|
7234
|
+
var CARD40 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
|
|
7235
|
+
var text9 = (value, max) => typeof value === "string" && value.length <= max;
|
|
7236
|
+
var absentOrNull = (value) => value === void 0 || value === null;
|
|
7237
|
+
var inOrder6 = (value, order) => Object.keys(value).every((key) => order.includes(key)) && Object.keys(value).join() === order.filter((key) => own15(value, key)).join();
|
|
7238
|
+
function frisbiiTokenUrl(url) {
|
|
7239
|
+
if (typeof url !== "string" || url.length > URL_LIMIT15 || url.includes("#"))
|
|
7240
|
+
return null;
|
|
7241
|
+
let parsed;
|
|
7242
|
+
try {
|
|
7243
|
+
parsed = new URL(url);
|
|
7244
|
+
}
|
|
7245
|
+
catch {
|
|
7246
|
+
return null;
|
|
7247
|
+
}
|
|
7248
|
+
if (parsed.href !== url || parsed.protocol !== "https:" || parsed.port || parsed.username || parsed.password || !own15(FRISBII_HOSTS, parsed.hostname) || parsed.pathname !== FRISBII_TOKEN_PATH)
|
|
7249
|
+
return null;
|
|
7250
|
+
const match = /^\?session=([A-Za-z0-9_-]{8,128})$/.exec(parsed.search);
|
|
7251
|
+
return match ? Object.freeze({ host: parsed.hostname, brand: FRISBII_HOSTS[parsed.hostname], session: match[1] }) : null;
|
|
7252
|
+
}
|
|
7253
|
+
var isFrisbiiTokenUrl = (url) => frisbiiTokenUrl(url) !== null;
|
|
7254
|
+
function frisbiiRefusedFlowUrl(url) {
|
|
7255
|
+
if (typeof url !== "string" || url.length > URL_LIMIT15 || url.includes("#"))
|
|
7256
|
+
return null;
|
|
7257
|
+
let parsed;
|
|
7258
|
+
try {
|
|
7259
|
+
parsed = new URL(url);
|
|
7260
|
+
}
|
|
7261
|
+
catch {
|
|
7262
|
+
return null;
|
|
7263
|
+
}
|
|
7264
|
+
if (parsed.href !== url || parsed.protocol !== "https:" || parsed.port || parsed.username || parsed.password || !own15(FRISBII_HOSTS, parsed.hostname) || !own15(FRISBII_REFUSED_PATHS, parsed.pathname))
|
|
7265
|
+
return null;
|
|
7266
|
+
return FRISBII_REFUSED_PATHS[parsed.pathname];
|
|
7267
|
+
}
|
|
7268
|
+
function luhn9(digits4) {
|
|
7269
|
+
let sum = 0;
|
|
7270
|
+
for (let at = digits4.length - 1, double = false; at >= 0; at -= 1, double = !double) {
|
|
7271
|
+
let digit = digits4.charCodeAt(at) - 48;
|
|
7272
|
+
if (double)
|
|
7273
|
+
digit = digit * 2 > 9 ? digit * 2 - 9 : digit * 2;
|
|
7274
|
+
sum += digit;
|
|
7275
|
+
}
|
|
7276
|
+
return sum % 10 === 0;
|
|
7277
|
+
}
|
|
7278
|
+
function readBody24(body) {
|
|
7279
|
+
if (typeof body !== "string" || body === "" || body.length > BODY_LIMIT38)
|
|
7280
|
+
return null;
|
|
7281
|
+
try {
|
|
7282
|
+
const value = JSON.parse(body);
|
|
7283
|
+
return record34(value) && JSON.stringify(value) === body ? value : null;
|
|
7284
|
+
}
|
|
7285
|
+
catch {
|
|
7286
|
+
return null;
|
|
7287
|
+
}
|
|
7288
|
+
}
|
|
7289
|
+
function browserInfo(info) {
|
|
7290
|
+
return record34(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;
|
|
7291
|
+
}
|
|
7292
|
+
function scaBlock(block, target) {
|
|
7293
|
+
if (!record34(block) || !inOrder6(block, SCA_ORDER) || !own15(block, "returnUrl") || !own15(block, "tokenBrowserInfo"))
|
|
7294
|
+
return false;
|
|
7295
|
+
if (!Number.isSafeInteger(block.amount) || block.amount < 0 || typeof block.currency !== "string" || !/^[A-Z]{3}$/.test(block.currency))
|
|
7296
|
+
return false;
|
|
7297
|
+
if (!(absentOrNull(block.orderId) || text9(block.orderId, 128)) || !(absentOrNull(block.orderText) || text9(block.orderText, 512)))
|
|
7298
|
+
return false;
|
|
7299
|
+
if (!(absentOrNull(block.merchantScaData) || record34(block.merchantScaData)))
|
|
7300
|
+
return false;
|
|
7301
|
+
if (!text9(block.returnUrl, 2048) || !browserInfo(block.tokenBrowserInfo))
|
|
7302
|
+
return false;
|
|
7303
|
+
const back = /^https:\/\/checkout\.(reepay|frisbii)\.com\/return\.001\.html\?id=([A-Za-z0-9_-]{8,128})(?:&[A-Za-z0-9_.~%=+/-]*)*$/.exec(block.returnUrl);
|
|
7304
|
+
return back !== null && (target === null || back[1] === target.brand && back[2] === target.session);
|
|
7305
|
+
}
|
|
7306
|
+
function frisbiiBodyVerdict(body, url) {
|
|
7307
|
+
const value = readBody24(body);
|
|
7308
|
+
if (value === null || !inOrder6(value, BODY_ORDER) || !BODY_REQUIRED.every((key) => own15(value, key)) || BODY_REFUSED.some((key) => own15(value, key)))
|
|
7309
|
+
return refuse40("frisbii_body_unsupported");
|
|
7310
|
+
if (value.recurring === true || value.intent === "CHARGE_AND_STORE")
|
|
7311
|
+
return refuse40("frisbii_card_on_file");
|
|
7312
|
+
const target = url === void 0 ? null : frisbiiTokenUrl(url);
|
|
7313
|
+
if (url !== void 0 && target === null)
|
|
7314
|
+
return refuse40("frisbii_body_unsupported");
|
|
7315
|
+
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));
|
|
7316
|
+
return sound ? CARD40 : refuse40("frisbii_body_unsupported");
|
|
7317
|
+
}
|
|
7318
|
+
var frisbii_default = /* @__PURE__ */ registerProcessor({
|
|
7319
|
+
psp: FRISBII_PSP,
|
|
7320
|
+
definitions: [
|
|
7321
|
+
{
|
|
7322
|
+
psp: "frisbii",
|
|
7323
|
+
// The hosted page's card request, as the header above reads it, on both brands' card hosts. A test account
|
|
7324
|
+
// shares the live hosts, so no sandbox host is marked. The match reads the host and the path and ends with it. It
|
|
7325
|
+
// also takes the page's two other card paths, /v1/token/cof/ and /v1/token/create_click_to_pay, so the pause
|
|
7326
|
+
// decision holds them, and the body gate refuses every body there; the exact-URL rule below holds the session
|
|
7327
|
+
// query of the card request. Ships dark: served only to a client that declares `frisbii_card_token`, and only for a company
|
|
7328
|
+
// the backend's processor gate turns Frisbii on for.
|
|
7329
|
+
capability: "frisbii_card_token",
|
|
7330
|
+
match: "card\\.(?:reepay|frisbii)\\.com/v1/token/(?:cof/|create_click_to_pay)?",
|
|
7331
|
+
hosts: ["^card\\.reepay\\.com$", "^card\\.frisbii\\.com$"],
|
|
7332
|
+
encoding: "json",
|
|
7333
|
+
// The page sends no header but its content type. Origin, Referer and cookies never ride.
|
|
7334
|
+
passthroughHeaders: [],
|
|
7335
|
+
jsonCardFields: [["number"]]
|
|
7336
|
+
}
|
|
7337
|
+
],
|
|
7338
|
+
// Only the cardholder's device would send this card, after a person approves; no reviewed list names frisbii.
|
|
7339
|
+
refusedOperations: [FRISBII_OPERATION],
|
|
7340
|
+
// Not surveyed: the card request mints a token and moves no money, and the page then charges the session with it
|
|
7341
|
+
// in a card-free request. Whether the session's own read (checkout-api /v1/checkout/<session>) can confirm that
|
|
7342
|
+
// charge was not read.
|
|
7343
|
+
settlementReadback: "not_surveyed",
|
|
7344
|
+
exactUrl: (url) => isFrisbiiTokenUrl(url) || frisbiiRefusedFlowUrl(url) !== null,
|
|
7345
|
+
// A stored card's token and Click to Pay are refused whatever their body; the card request is judged by its body.
|
|
7346
|
+
bodyGate: (url, body) => {
|
|
7347
|
+
if (url === void 0)
|
|
7348
|
+
return frisbiiBodyVerdict(body);
|
|
7349
|
+
const flow = frisbiiRefusedFlowUrl(url);
|
|
7350
|
+
if (flow !== null)
|
|
7351
|
+
return refuse40(flow);
|
|
7352
|
+
return isFrisbiiTokenUrl(url) ? frisbiiBodyVerdict(body, url) : refuse40("frisbii_url_refused");
|
|
7353
|
+
},
|
|
7354
|
+
limitations: ["A live Frisbii card goes only to a merchant account a reviewed pin lists, and none is pinned yet."]
|
|
7355
|
+
});
|
|
7356
|
+
// src/processors/iyzico.js
|
|
7357
|
+
var IYZICO_PSP = "iyzico";
|
|
7358
|
+
var IYZICO_OPERATION = "iyzico.card_request";
|
|
7359
|
+
var PATHS = ["/payment/iyzipos/checkoutform/auth/ecom", "/payment/iyzipos/checkoutform/initialize3ds/ecom"];
|
|
7360
|
+
var IYZICO_CARD_URLS = /* @__PURE__ */ Object.freeze(["https://api.iyzipay.com", "https://sandbox-api.iyzipay.com"].flatMap((origin) => PATHS.map((path) => `${origin}${path}`)));
|
|
7361
|
+
var IYZICO_BODY_KEYS = /* @__PURE__ */ Object.freeze([
|
|
7362
|
+
"installment",
|
|
7363
|
+
"paidPrice",
|
|
7364
|
+
"paymentChannel",
|
|
7365
|
+
"paymentCard",
|
|
7366
|
+
"buyerProtected",
|
|
7367
|
+
"gsmNumber",
|
|
7368
|
+
"dccPayment",
|
|
7369
|
+
"dccQueryRrn",
|
|
7370
|
+
"pwiMetadata"
|
|
7371
|
+
]);
|
|
7372
|
+
var IYZICO_CARD_KEYS = /* @__PURE__ */ Object.freeze([
|
|
7373
|
+
"cardNumber",
|
|
7374
|
+
"cardHolderName",
|
|
7375
|
+
"expireYear",
|
|
7376
|
+
"expireMonth",
|
|
7377
|
+
"cvc",
|
|
7378
|
+
"registerConsumerCard",
|
|
7379
|
+
"registerCard"
|
|
7380
|
+
]);
|
|
7381
|
+
var BODY_LIMIT39 = 4096;
|
|
7382
|
+
var CARD_NUMBER20 = /^[0-9]{12,19}$/;
|
|
7383
|
+
var SECURITY_CODE24 = /^[0-9]{3,4}$/;
|
|
7384
|
+
var MONTH20 = /^(?:0?[1-9]|1[0-2])$/;
|
|
7385
|
+
var YEAR21 = /^(?:[0-9]{2}|20[0-9]{2})$/;
|
|
7386
|
+
var PRICE = /^([1-9][0-9]{0,8}|0)(?:\.([0-9]{1,2}))?$/;
|
|
7387
|
+
var CHANNELS = /* @__PURE__ */ Object.freeze(["WEB", "MOBILE_WEB", "MOBILE_IOS", "MOBILE_ANDROID", "MOBILE_WINDOWS"]);
|
|
7388
|
+
var METADATA_KEYS3 = /* @__PURE__ */ Object.freeze(["lightRedesign", "pwiGrowthActionDisabled"]);
|
|
7389
|
+
var FLAG = /^[A-Za-z_]{1,16}$/;
|
|
7390
|
+
var HOLDER5 = /^[^\x00-\x1f\x7f0-9]{3,100}$/u;
|
|
7391
|
+
var record35 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
7392
|
+
var own16 = (value, key) => Object.prototype.hasOwnProperty.call(value, key);
|
|
7393
|
+
var inOrder7 = (value, keys) => {
|
|
7394
|
+
let at = 0;
|
|
7395
|
+
for (const name of Object.keys(value)) {
|
|
7396
|
+
while (at < keys.length && keys[at] !== name)
|
|
7397
|
+
at += 1;
|
|
7398
|
+
if (at === keys.length)
|
|
7399
|
+
return false;
|
|
7400
|
+
at += 1;
|
|
7401
|
+
}
|
|
7402
|
+
return true;
|
|
7403
|
+
};
|
|
7404
|
+
var refuse41 = (code) => Object.freeze({ verdict: "refuse", code });
|
|
7405
|
+
var CARD41 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
|
|
7406
|
+
function isIyzicoCardUrl(url) {
|
|
7407
|
+
return typeof url === "string" && IYZICO_CARD_URLS.includes(url);
|
|
7408
|
+
}
|
|
7409
|
+
function readBody25(body) {
|
|
7410
|
+
if (typeof body !== "string" || body === "" || body.length > BODY_LIMIT39)
|
|
7411
|
+
return null;
|
|
7412
|
+
try {
|
|
7413
|
+
const value = JSON.parse(body);
|
|
7414
|
+
return record35(value) && JSON.stringify(value) === body ? value : null;
|
|
6318
7415
|
}
|
|
6319
7416
|
catch {
|
|
6320
7417
|
return null;
|
|
@@ -6326,26 +7423,26 @@ function hundredths(price) {
|
|
|
6326
7423
|
return value > 0 ? value : null;
|
|
6327
7424
|
}
|
|
6328
7425
|
var holderName2 = (name) => typeof name === "string" && HOLDER5.test(name) && name.trim().split(/\s+/).filter((word) => word.length > 1).length > 1;
|
|
6329
|
-
var metadata = (value) =>
|
|
7426
|
+
var metadata = (value) => record35(value) && inOrder7(value, METADATA_KEYS3) && Object.values(value).every((flag3) => Array.isArray(flag3) && flag3.length === 1 && typeof flag3[0] === "string" && FLAG.test(flag3[0]));
|
|
6330
7427
|
function iyzicoBodyVerdict(body) {
|
|
6331
|
-
const value =
|
|
7428
|
+
const value = readBody25(body);
|
|
6332
7429
|
if (value === null)
|
|
6333
|
-
return
|
|
7430
|
+
return refuse41("iyzico_body_unsupported");
|
|
6334
7431
|
const card = value.paymentCard;
|
|
6335
|
-
if (
|
|
6336
|
-
return
|
|
6337
|
-
if (
|
|
6338
|
-
return
|
|
6339
|
-
if (
|
|
6340
|
-
return
|
|
7432
|
+
if (record35(card) && (own16(card, "cardToken") || own16(card, "ucsToken") || own16(card, "consumerToken")) && !own16(card, "cardNumber"))
|
|
7433
|
+
return refuse41("iyzico_saved_card");
|
|
7434
|
+
if (own16(value, "dccPayment") || own16(value, "dccQueryRrn"))
|
|
7435
|
+
return refuse41("iyzico_dcc_refused");
|
|
7436
|
+
if (own16(value, "gsmNumber") || own16(value, "buyerProtected") && value.buyerProtected !== false || record35(card) && (own16(card, "registerCard") && card.registerCard !== 0 || own16(card, "registerConsumerCard") && card.registerConsumerCard !== false)) {
|
|
7437
|
+
return refuse41("iyzico_keeps_card");
|
|
6341
7438
|
}
|
|
6342
7439
|
if (Number.isSafeInteger(value.installment) && value.installment > 1)
|
|
6343
|
-
return
|
|
6344
|
-
if (!
|
|
6345
|
-
return
|
|
6346
|
-
if (!
|
|
6347
|
-
return
|
|
6348
|
-
return
|
|
7440
|
+
return refuse41("iyzico_installments_refused");
|
|
7441
|
+
if (!inOrder7(value, IYZICO_BODY_KEYS) || !["installment", "paidPrice", "paymentChannel", "paymentCard"].every((key) => own16(value, key)) || value.installment !== 1 || hundredths(value.paidPrice) === null || !CHANNELS.includes(value.paymentChannel) || own16(value, "pwiMetadata") && !metadata(value.pwiMetadata))
|
|
7442
|
+
return refuse41("iyzico_body_unsupported");
|
|
7443
|
+
if (!record35(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))
|
|
7444
|
+
return refuse41("iyzico_body_unsupported");
|
|
7445
|
+
return CARD41;
|
|
6349
7446
|
}
|
|
6350
7447
|
var iyzico_default = /* @__PURE__ */ registerProcessor({
|
|
6351
7448
|
psp: IYZICO_PSP,
|
|
@@ -6378,7 +7475,7 @@ var iyzico_default = /* @__PURE__ */ registerProcessor({
|
|
|
6378
7475
|
source: "https://docs.iyzico.com/en/payment-methods/checkoutform/cf-implementation/cf-retrieve"
|
|
6379
7476
|
},
|
|
6380
7477
|
exactUrl: isIyzicoCardUrl,
|
|
6381
|
-
bodyGate: (url, body) => url !== void 0 && !isIyzicoCardUrl(url) ?
|
|
7478
|
+
bodyGate: (url, body) => url !== void 0 && !isIyzicoCardUrl(url) ? refuse41("iyzico_url_refused") : iyzicoBodyVerdict(body)
|
|
6382
7479
|
});
|
|
6383
7480
|
// src/processors/midtrans.js
|
|
6384
7481
|
var MIDTRANS_PSP = "midtrans";
|
|
@@ -6386,15 +7483,15 @@ var MIDTRANS_OPERATION = "midtrans.card_request";
|
|
|
6386
7483
|
var MIDTRANS_TOKEN_URL = "https://api.midtrans.com/v2/token";
|
|
6387
7484
|
var MIDTRANS_SANDBOX_TOKEN_URL = "https://api.sandbox.midtrans.com/v2/token";
|
|
6388
7485
|
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
|
|
7486
|
+
var BODY_LIMIT40 = 4096;
|
|
7487
|
+
var CARD_NUMBER21 = /^[0-9]{12,19}$/;
|
|
7488
|
+
var SECURITY_CODE25 = /^[0-9]{3,4}$/;
|
|
7489
|
+
var MONTH21 = /^(?:0[1-9]|1[0-2])$/;
|
|
7490
|
+
var YEAR22 = /^20[0-9]{2}$/;
|
|
6394
7491
|
var TERM = /^[0-9]{1,3}$/;
|
|
6395
|
-
var
|
|
6396
|
-
var
|
|
6397
|
-
var
|
|
7492
|
+
var record36 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
7493
|
+
var own17 = (value, key) => Object.prototype.hasOwnProperty.call(value, key);
|
|
7494
|
+
var inOrder8 = (value, keys) => {
|
|
6398
7495
|
let at = 0;
|
|
6399
7496
|
for (const name of Object.keys(value)) {
|
|
6400
7497
|
while (at < keys.length && keys[at] !== name)
|
|
@@ -6405,18 +7502,18 @@ var inOrder7 = (value, keys) => {
|
|
|
6405
7502
|
}
|
|
6406
7503
|
return true;
|
|
6407
7504
|
};
|
|
6408
|
-
var
|
|
6409
|
-
var
|
|
7505
|
+
var refuse42 = (code) => Object.freeze({ verdict: "refuse", code });
|
|
7506
|
+
var CARD42 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
|
|
6410
7507
|
function isMidtransTokenUrl(url) {
|
|
6411
7508
|
return url === MIDTRANS_TOKEN_URL || url === MIDTRANS_SANDBOX_TOKEN_URL;
|
|
6412
7509
|
}
|
|
6413
|
-
function
|
|
6414
|
-
if (typeof body !== "string" || body === "" || body.length >
|
|
7510
|
+
function readBody26(body) {
|
|
7511
|
+
if (typeof body !== "string" || body === "" || body.length > BODY_LIMIT40)
|
|
6415
7512
|
return null;
|
|
6416
7513
|
let value;
|
|
6417
7514
|
try {
|
|
6418
7515
|
value = JSON.parse(body);
|
|
6419
|
-
if (!
|
|
7516
|
+
if (!record36(value) || JSON.stringify(value) !== body)
|
|
6420
7517
|
return null;
|
|
6421
7518
|
}
|
|
6422
7519
|
catch {
|
|
@@ -6425,20 +7522,20 @@ function readBody23(body) {
|
|
|
6425
7522
|
return value;
|
|
6426
7523
|
}
|
|
6427
7524
|
function midtransBodyVerdict(body) {
|
|
6428
|
-
const value =
|
|
6429
|
-
if (value === null || !
|
|
6430
|
-
if (
|
|
6431
|
-
return
|
|
6432
|
-
return
|
|
7525
|
+
const value = readBody26(body);
|
|
7526
|
+
if (value === null || !inOrder8(value, MIDTRANS_TOKEN_KEYS)) {
|
|
7527
|
+
if (record36(value) && (own17(value, "token_id") || own17(value, "two_click")) && !own17(value, "card_number"))
|
|
7528
|
+
return refuse42("midtrans_saved_card");
|
|
7529
|
+
return refuse42("midtrans_body_unsupported");
|
|
6433
7530
|
}
|
|
6434
|
-
if (!
|
|
6435
|
-
return
|
|
7531
|
+
if (!own17(value, "card_cvv") || !own17(value, "card_number") || !own17(value, "card_exp_month") || !own17(value, "card_exp_year")) {
|
|
7532
|
+
return refuse42("midtrans_body_unsupported");
|
|
6436
7533
|
}
|
|
6437
|
-
if (typeof value.card_cvv !== "string" || !
|
|
6438
|
-
return
|
|
6439
|
-
if (
|
|
6440
|
-
return
|
|
6441
|
-
return
|
|
7534
|
+
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))
|
|
7535
|
+
return refuse42("midtrans_body_unsupported");
|
|
7536
|
+
if (own17(value, "installment_term") && (typeof value.installment_term !== "string" || !TERM.test(value.installment_term)))
|
|
7537
|
+
return refuse42("midtrans_body_unsupported");
|
|
7538
|
+
return CARD42;
|
|
6442
7539
|
}
|
|
6443
7540
|
var midtrans_default = /* @__PURE__ */ registerProcessor({
|
|
6444
7541
|
psp: MIDTRANS_PSP,
|
|
@@ -6456,18 +7553,111 @@ var midtrans_default = /* @__PURE__ */ registerProcessor({
|
|
|
6456
7553
|
sandboxHosts: ["^api\\.sandbox\\.midtrans\\.com$"],
|
|
6457
7554
|
hostEnvironmentPinned: true,
|
|
6458
7555
|
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"]]
|
|
7556
|
+
// Snap's own headers: the publishable client key (Authorization Basic) and X-Service. Origin, Referer and
|
|
7557
|
+
// cookies never ride.
|
|
7558
|
+
passthroughHeaders: ["^authorization$", "^x-service$"],
|
|
7559
|
+
jsonCardFields: [["card_number"]]
|
|
7560
|
+
}
|
|
7561
|
+
],
|
|
7562
|
+
// Only the cardholder's device sends a token, after a person approves; no reviewed list names midtrans.
|
|
7563
|
+
refusedOperations: [MIDTRANS_OPERATION],
|
|
7564
|
+
// Not surveyed: the token moves no money, and the merchant's own charge names its status by the order id alone.
|
|
7565
|
+
settlementReadback: "not_surveyed",
|
|
7566
|
+
exactUrl: isMidtransTokenUrl,
|
|
7567
|
+
bodyGate: (url, body) => url !== void 0 && !isMidtransTokenUrl(url) ? { verdict: "refuse", code: "midtrans_url_refused" } : midtransBodyVerdict(body)
|
|
7568
|
+
});
|
|
7569
|
+
// src/processors/monei.js
|
|
7570
|
+
var MONEI_PSP = "monei";
|
|
7571
|
+
var MONEI_OPERATION = "monei.card_request";
|
|
7572
|
+
var MONEI_TOKENS_URL = "https://api.monei.com/v1/tokens";
|
|
7573
|
+
var BODY_LIMIT41 = 1024;
|
|
7574
|
+
var PAYMENT_ID = /^(?:[0-9a-f]{32}|[0-9a-f]{40})$/;
|
|
7575
|
+
var MONEI_CARD_KEYS = /* @__PURE__ */ Object.freeze(["number", "expMonth", "expYear", "cvc"]);
|
|
7576
|
+
var NUMBER9 = /^[0-9]{12,19}$/;
|
|
7577
|
+
var MONTH22 = /^(?:0[1-9]|1[0-2])$/;
|
|
7578
|
+
var YEAR23 = /^[0-9]{2}$/;
|
|
7579
|
+
var CODE8 = /^[0-9]{3,4}$/;
|
|
7580
|
+
var record37 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
7581
|
+
var keysAre2 = (value, keys) => {
|
|
7582
|
+
const found = Object.keys(value);
|
|
7583
|
+
return found.length === keys.length && found.every((key, at) => key === keys[at]);
|
|
7584
|
+
};
|
|
7585
|
+
var refuse43 = (code) => Object.freeze({ verdict: "refuse", code });
|
|
7586
|
+
var CARD43 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
|
|
7587
|
+
function luhn10(digits4) {
|
|
7588
|
+
let sum = 0;
|
|
7589
|
+
for (let at = 0; at < digits4.length; at += 1) {
|
|
7590
|
+
let digit = Number(digits4[digits4.length - 1 - at]);
|
|
7591
|
+
if (at % 2 === 1) {
|
|
7592
|
+
digit *= 2;
|
|
7593
|
+
if (digit > 9)
|
|
7594
|
+
digit -= 9;
|
|
7595
|
+
}
|
|
7596
|
+
sum += digit;
|
|
7597
|
+
}
|
|
7598
|
+
return sum % 10 === 0;
|
|
7599
|
+
}
|
|
7600
|
+
function isMoneiTokensUrl(url) {
|
|
7601
|
+
return url === MONEI_TOKENS_URL;
|
|
7602
|
+
}
|
|
7603
|
+
function readBody27(body) {
|
|
7604
|
+
if (typeof body !== "string" || body === "" || body.length > BODY_LIMIT41)
|
|
7605
|
+
return null;
|
|
7606
|
+
try {
|
|
7607
|
+
const value = JSON.parse(body);
|
|
7608
|
+
return record37(value) && JSON.stringify(value) === body ? value : null;
|
|
7609
|
+
}
|
|
7610
|
+
catch {
|
|
7611
|
+
return null;
|
|
7612
|
+
}
|
|
7613
|
+
}
|
|
7614
|
+
function moneiBodyVerdict(body, url) {
|
|
7615
|
+
if (url !== void 0 && !isMoneiTokensUrl(url))
|
|
7616
|
+
return refuse43("monei_url_refused");
|
|
7617
|
+
const value = readBody27(body);
|
|
7618
|
+
if (value === null || !keysAre2(value, ["paymentId", "paymentMethod"]) || typeof value.paymentId !== "string" || !PAYMENT_ID.test(value.paymentId))
|
|
7619
|
+
return refuse43("monei_body_unsupported");
|
|
7620
|
+
const method = value.paymentMethod;
|
|
7621
|
+
if (!record37(method) || !keysAre2(method, ["card"]) || !record37(method.card) || !keysAre2(method.card, MONEI_CARD_KEYS))
|
|
7622
|
+
return refuse43("monei_body_unsupported");
|
|
7623
|
+
const { number, expMonth, expYear, cvc } = method.card;
|
|
7624
|
+
if (![number, expMonth, expYear, cvc].every((part) => typeof part === "string"))
|
|
7625
|
+
return refuse43("monei_body_unsupported");
|
|
7626
|
+
if (!NUMBER9.test(number) || !luhn10(number) || !MONTH22.test(expMonth) || !YEAR23.test(expYear) || !CODE8.test(cvc))
|
|
7627
|
+
return refuse43("monei_body_unsupported");
|
|
7628
|
+
return CARD43;
|
|
7629
|
+
}
|
|
7630
|
+
var MONEI_MERCHANT_PINS = /* @__PURE__ */ Object.freeze([
|
|
7631
|
+
Object.freeze({ merchant: "Genuins", accountIds: Object.freeze(["8d58ab4c-4ad0-4053-b18f-79d80e9ee158"]), merchantUrls: Object.freeze(["https://genuins.com/"]) })
|
|
7632
|
+
]);
|
|
7633
|
+
var monei_default = /* @__PURE__ */ registerProcessor({
|
|
7634
|
+
psp: MONEI_PSP,
|
|
7635
|
+
definitions: [
|
|
7636
|
+
{
|
|
7637
|
+
psp: "monei",
|
|
7638
|
+
// The card frame's token request, as the header above reads it. One host serves test and live payments alike,
|
|
7639
|
+
// so no sandbox host is marked: MONEI's record of the payment names its mode, and the device sends a test payment
|
|
7640
|
+
// only MONEI's documented test cards (moneiDeviceRefusal). The frame sets no deadline on the fetch, so the
|
|
7641
|
+
// cardholder approves at the shopper's Pay. `(?![\w/.%-])` ends the path for a consumer that tests `match`
|
|
7642
|
+
// unanchored, and the exact-URL rule below holds the rest. Ships dark: served only to a client that declares
|
|
7643
|
+
// `monei_card_token`, and gated off for every company until the backend's gate names one.
|
|
7644
|
+
capability: "monei_card_token",
|
|
7645
|
+
match: "api\\.monei\\.com/v1/tokens(?![\\w/.%-])",
|
|
7646
|
+
hosts: ["^api\\.monei\\.com$"],
|
|
7647
|
+
encoding: "json",
|
|
7648
|
+
// The frame's two device headers. Origin, Referer and cookies never ride.
|
|
7649
|
+
passthroughHeaders: ["^x-client-env$", "^x-client-fingerprint$"],
|
|
7650
|
+
jsonCardFields: [["paymentMethod", "card", "number"]]
|
|
6463
7651
|
}
|
|
6464
7652
|
],
|
|
6465
|
-
// Only the cardholder's device sends a
|
|
6466
|
-
refusedOperations: [
|
|
6467
|
-
// Not surveyed: the token moves no money
|
|
7653
|
+
// Only the cardholder's device sends a card, after a person approves; no reviewed list names monei.
|
|
7654
|
+
refusedOperations: [MONEI_OPERATION],
|
|
7655
|
+
// Not surveyed: the card request mints a token and moves no money; MONEI's confirm, which the page sends, charges it.
|
|
6468
7656
|
settlementReadback: "not_surveyed",
|
|
6469
|
-
exactUrl:
|
|
6470
|
-
bodyGate: (url, body) =>
|
|
7657
|
+
exactUrl: isMoneiTokensUrl,
|
|
7658
|
+
bodyGate: (url, body) => moneiBodyVerdict(body, url)
|
|
7659
|
+
// No amount reader: the request names none. MONEI's record of the payment names it, and the device holds that record
|
|
7660
|
+
// to the approved amount before it writes any card.
|
|
6471
7661
|
});
|
|
6472
7662
|
// src/processors/oceanpayment.js
|
|
6473
7663
|
var OCEANPAYMENT_PSP = "oceanpayment";
|
|
@@ -6498,10 +7688,10 @@ var OCEANPAYMENT_FORM_FIELDS = /* @__PURE__ */ Object.freeze([
|
|
|
6498
7688
|
"methods",
|
|
6499
7689
|
"reference"
|
|
6500
7690
|
]);
|
|
6501
|
-
var
|
|
6502
|
-
var
|
|
7691
|
+
var URL_LIMIT16 = 2048;
|
|
7692
|
+
var BODY_LIMIT42 = 8192;
|
|
6503
7693
|
var SEND_PAY = /^\/gateway\/sendPay;jsessionid=[A-Za-z0-9._!-]{16,128}$/;
|
|
6504
|
-
var
|
|
7694
|
+
var own18 = (value, key) => Object.prototype.hasOwnProperty.call(value, key);
|
|
6505
7695
|
var exact4 = (pattern, value) => typeof value === "string" && pattern.test(value);
|
|
6506
7696
|
var CARD_RUN = /[0-9]{12}/;
|
|
6507
7697
|
var printable5 = (max) => (value) => typeof value === "string" && value.length <= max && /^[\x20-\x7e]*$/.test(value) && !CARD_RUN.test(value);
|
|
@@ -6539,7 +7729,7 @@ var SHAPES2 = /* @__PURE__ */ new Map([
|
|
|
6539
7729
|
["button", (v) => v === ""]
|
|
6540
7730
|
]);
|
|
6541
7731
|
function oceanpaymentSendPayUrl(url) {
|
|
6542
|
-
if (typeof url !== "string" || url.length >
|
|
7732
|
+
if (typeof url !== "string" || url.length > URL_LIMIT16 || url.includes("?") || url.includes("#"))
|
|
6543
7733
|
return null;
|
|
6544
7734
|
let parsed;
|
|
6545
7735
|
try {
|
|
@@ -6548,7 +7738,7 @@ function oceanpaymentSendPayUrl(url) {
|
|
|
6548
7738
|
catch {
|
|
6549
7739
|
return null;
|
|
6550
7740
|
}
|
|
6551
|
-
if (parsed.href !== url || parsed.protocol !== "https:" || parsed.port || parsed.username || parsed.password || !
|
|
7741
|
+
if (parsed.href !== url || parsed.protocol !== "https:" || parsed.port || parsed.username || parsed.password || !own18(OCEANPAYMENT_HOSTS, parsed.hostname) || !SEND_PAY.test(parsed.pathname))
|
|
6552
7742
|
return null;
|
|
6553
7743
|
return Object.freeze({ host: parsed.hostname, environment: OCEANPAYMENT_HOSTS[parsed.hostname] });
|
|
6554
7744
|
}
|
|
@@ -6576,7 +7766,7 @@ function formDecode2(raw) {
|
|
|
6576
7766
|
return formEncode3(value) === raw ? value : null;
|
|
6577
7767
|
}
|
|
6578
7768
|
function readPairs2(body) {
|
|
6579
|
-
if (typeof body !== "string" || body === "" || body.length >
|
|
7769
|
+
if (typeof body !== "string" || body === "" || body.length > BODY_LIMIT42)
|
|
6580
7770
|
return null;
|
|
6581
7771
|
const pairs = [];
|
|
6582
7772
|
for (const chunk of body.split("&")) {
|
|
@@ -6661,7 +7851,7 @@ var PAYMENTWALL_PSP = "paymentwall";
|
|
|
6661
7851
|
var PAYMENTWALL_OPERATION = "paymentwall.card_request";
|
|
6662
7852
|
var PAYMENTWALL_TOKEN_URL = "https://pwgateway.com/api/token";
|
|
6663
7853
|
var PAYMENTWALL_SANDBOX_TOKEN_URL = "https://api.paymentwall.com/api/brick/token";
|
|
6664
|
-
var
|
|
7854
|
+
var BODY_LIMIT43 = 2048;
|
|
6665
7855
|
var KEY3 = "public_key";
|
|
6666
7856
|
var PUBLIC_KEY2 = /^(?:t_)?[A-Za-z0-9]{16,64}$/;
|
|
6667
7857
|
var SHAPES3 = /* @__PURE__ */ Object.freeze({
|
|
@@ -6671,9 +7861,9 @@ var SHAPES3 = /* @__PURE__ */ Object.freeze({
|
|
|
6671
7861
|
"card[exp_year]": /^(?:[0-9]{2}|20[0-9]{2})$/,
|
|
6672
7862
|
"card[cvv]": /^[0-9]{3,4}$/
|
|
6673
7863
|
});
|
|
6674
|
-
var
|
|
6675
|
-
var
|
|
6676
|
-
function
|
|
7864
|
+
var refuse44 = (code) => Object.freeze({ verdict: "refuse", code });
|
|
7865
|
+
var CARD44 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
|
|
7866
|
+
function luhn11(digits4) {
|
|
6677
7867
|
let sum = 0;
|
|
6678
7868
|
for (let at = 0; at < digits4.length; at += 1) {
|
|
6679
7869
|
let digit = Number(digits4[digits4.length - 1 - at]);
|
|
@@ -6700,7 +7890,7 @@ function paymentwallKeyEnvironment(publicKey) {
|
|
|
6700
7890
|
return publicKey.startsWith("t_") ? "sandbox" : "production";
|
|
6701
7891
|
}
|
|
6702
7892
|
function readPairs3(body) {
|
|
6703
|
-
if (typeof body !== "string" || body === "" || body.length >
|
|
7893
|
+
if (typeof body !== "string" || body === "" || body.length > BODY_LIMIT43 || !/^[A-Za-z0-9_[\]=&]+$/.test(body))
|
|
6704
7894
|
return null;
|
|
6705
7895
|
const pairs = /* @__PURE__ */ new Map();
|
|
6706
7896
|
for (const chunk of body.split("&")) {
|
|
@@ -6716,21 +7906,21 @@ function readPairs3(body) {
|
|
|
6716
7906
|
}
|
|
6717
7907
|
function paymentwallBodyVerdict(body, url) {
|
|
6718
7908
|
if (url !== void 0 && !isPaymentwallTokenUrl(url))
|
|
6719
|
-
return
|
|
7909
|
+
return refuse44("paymentwall_url_refused");
|
|
6720
7910
|
const pairs = readPairs3(body);
|
|
6721
7911
|
if (pairs === null)
|
|
6722
|
-
return
|
|
7912
|
+
return refuse44("paymentwall_body_unsupported");
|
|
6723
7913
|
if (pairs.has("card[token]") && !pairs.has("card[number]"))
|
|
6724
|
-
return
|
|
7914
|
+
return refuse44("paymentwall_saved_card");
|
|
6725
7915
|
const keys = Object.keys(SHAPES3);
|
|
6726
7916
|
if (pairs.size !== keys.length || !keys.every((key) => pairs.has(key) && SHAPES3[key].test(pairs.get(key)))) {
|
|
6727
|
-
return
|
|
7917
|
+
return refuse44("paymentwall_body_unsupported");
|
|
6728
7918
|
}
|
|
6729
|
-
if (!
|
|
6730
|
-
return
|
|
7919
|
+
if (!luhn11(pairs.get("card[number]")))
|
|
7920
|
+
return refuse44("paymentwall_body_unsupported");
|
|
6731
7921
|
if (url !== void 0 && paymentwallKeyEnvironment(pairs.get(KEY3)) !== paymentwallUrlEnvironment(url))
|
|
6732
|
-
return
|
|
6733
|
-
return
|
|
7922
|
+
return refuse44("paymentwall_key_refused");
|
|
7923
|
+
return CARD44;
|
|
6734
7924
|
}
|
|
6735
7925
|
var paymentwall_default = /* @__PURE__ */ registerProcessor({
|
|
6736
7926
|
psp: PAYMENTWALL_PSP,
|
|
@@ -6759,112 +7949,15 @@ var paymentwall_default = /* @__PURE__ */ registerProcessor({
|
|
|
6759
7949
|
exactUrl: isPaymentwallTokenUrl,
|
|
6760
7950
|
bodyGate: (url, body) => paymentwallBodyVerdict(body, url)
|
|
6761
7951
|
});
|
|
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
7952
|
// src/processors/payplug.js
|
|
6860
7953
|
var PAYPLUG_PSP = "payplug";
|
|
6861
7954
|
var PAYPLUG_OPERATION = "payplug.hosted_sale";
|
|
6862
7955
|
var PAYPLUG_HOST = "secure.payplug.com";
|
|
6863
7956
|
var ENTRY_PATH = /^\/pay\/(?:(test)\/)?([A-Za-z0-9]{22})$/;
|
|
6864
|
-
var
|
|
6865
|
-
var
|
|
7957
|
+
var MAX_URL3 = 256;
|
|
7958
|
+
var field4 = (name, reason) => ({ ok: false, code: "hosted_form_field_refused", field: name, reason });
|
|
6866
7959
|
function payplugEntry(raw) {
|
|
6867
|
-
if (typeof raw !== "string" || raw.length >
|
|
7960
|
+
if (typeof raw !== "string" || raw.length > MAX_URL3 || raw.includes("?") || raw.includes("#"))
|
|
6868
7961
|
return null;
|
|
6869
7962
|
let url;
|
|
6870
7963
|
try {
|
|
@@ -6886,7 +7979,7 @@ var PAYPLUG_MERCHANTS = Object.freeze([
|
|
|
6886
7979
|
]);
|
|
6887
7980
|
var ACCOUNT_ID = /^[A-Za-z0-9-]{1,64}$/;
|
|
6888
7981
|
function payplugMerchant(checkoutOrigin, merchants = PAYPLUG_MERCHANTS) {
|
|
6889
|
-
if (typeof checkoutOrigin !== "string" || checkoutOrigin.length >
|
|
7982
|
+
if (typeof checkoutOrigin !== "string" || checkoutOrigin.length > MAX_URL3 || !Array.isArray(merchants))
|
|
6890
7983
|
return null;
|
|
6891
7984
|
let url;
|
|
6892
7985
|
try {
|
|
@@ -6902,16 +7995,16 @@ function payplugMerchant(checkoutOrigin, merchants = PAYPLUG_MERCHANTS) {
|
|
|
6902
7995
|
}
|
|
6903
7996
|
function checkPayplugEntry(body, { url = null, checkoutOrigin = null, merchants = PAYPLUG_MERCHANTS } = {}) {
|
|
6904
7997
|
if (body !== void 0 && body !== null && body !== "")
|
|
6905
|
-
return
|
|
7998
|
+
return field4("(body)", "not_an_entry");
|
|
6906
7999
|
const entry = payplugEntry(url);
|
|
6907
8000
|
if (!entry)
|
|
6908
|
-
return
|
|
8001
|
+
return field4("(url)", "malformed_field");
|
|
6909
8002
|
const seller = payplugMerchant(checkoutOrigin, merchants);
|
|
6910
8003
|
if (!seller)
|
|
6911
|
-
return
|
|
8004
|
+
return field4("(checkout_origin)", "seller_unreviewed");
|
|
6912
8005
|
return { ok: true, pairs: [], gated: false, dedupe: [entry.id], paymentId: entry.id, sandbox: entry.test, seller };
|
|
6913
8006
|
}
|
|
6914
|
-
var
|
|
8007
|
+
var MAX_PAGE5 = 512 * 1024;
|
|
6915
8008
|
var PAYPLUG_REFUSALS = Object.freeze(["payplug_failed", "payplug_expired", "payplug_cancelled"]);
|
|
6916
8009
|
var payplug_default = /* @__PURE__ */ registerProcessor({
|
|
6917
8010
|
psp: PAYPLUG_PSP,
|
|
@@ -6961,11 +8054,129 @@ var payplug_default = /* @__PURE__ */ registerProcessor({
|
|
|
6961
8054
|
"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
8055
|
]
|
|
6963
8056
|
});
|
|
8057
|
+
// src/processors/paystack.js
|
|
8058
|
+
var PAYSTACK_PSP = "paystack";
|
|
8059
|
+
var PAYSTACK_OPERATION = "paystack.card_request";
|
|
8060
|
+
var PAYSTACK_CHARGE_URL = "https://standard.paystack.co/charge/";
|
|
8061
|
+
var PAYSTACK_BODY_KEYS = /* @__PURE__ */ Object.freeze([
|
|
8062
|
+
"clientdata",
|
|
8063
|
+
"last4",
|
|
8064
|
+
"trans",
|
|
8065
|
+
"access_code",
|
|
8066
|
+
"device",
|
|
8067
|
+
"offset",
|
|
8068
|
+
"remember_card",
|
|
8069
|
+
"card_holder_name",
|
|
8070
|
+
"transaction_type"
|
|
8071
|
+
]);
|
|
8072
|
+
var OPTIONAL = /* @__PURE__ */ new Set(["access_code", "card_holder_name", "transaction_type"]);
|
|
8073
|
+
var BODY_LIMIT44 = 4096;
|
|
8074
|
+
var CIPHERTEXT_BYTES2 = [62, 63, 64];
|
|
8075
|
+
var BASE646 = /^[A-Za-z0-9+/]+={0,2}$/;
|
|
8076
|
+
var SHAPES4 = /* @__PURE__ */ Object.freeze({
|
|
8077
|
+
last4: /^[0-9]{4}$/,
|
|
8078
|
+
trans: /^[0-9]{1,20}$/,
|
|
8079
|
+
access_code: /^[A-Za-z0-9]{1,64}$/,
|
|
8080
|
+
device: /^[\x21-\x7e]{1,512}$/,
|
|
8081
|
+
offset: /^-?[0-9]{1,3}$/,
|
|
8082
|
+
remember_card: /^false$/,
|
|
8083
|
+
// A name carries no digit, so no card number can ride in it.
|
|
8084
|
+
card_holder_name: /^[^\x00-\x1f\x7f0-9]{1,128}$/u,
|
|
8085
|
+
transaction_type: /^[a-z_]{1,32}$/
|
|
8086
|
+
});
|
|
8087
|
+
var own19 = (value, key) => Object.prototype.hasOwnProperty.call(value, key);
|
|
8088
|
+
var refuse45 = (code) => Object.freeze({ verdict: "refuse", code });
|
|
8089
|
+
function paystackFormValue(value) {
|
|
8090
|
+
return encodeURIComponent(String(value)).replace(/%20/g, "+").replace(/[!'()*~]/g, (c) => `%${c.charCodeAt(0).toString(16).toUpperCase()}`);
|
|
8091
|
+
}
|
|
8092
|
+
function paystackFormBody(entries) {
|
|
8093
|
+
return entries.map(([key, value]) => `${paystackFormValue(key)}=${paystackFormValue(value)}`).join("&");
|
|
8094
|
+
}
|
|
8095
|
+
function isPaystackChargeUrl(url) {
|
|
8096
|
+
return url === PAYSTACK_CHARGE_URL;
|
|
8097
|
+
}
|
|
8098
|
+
function isCiphertext2(value) {
|
|
8099
|
+
if (value.length % 4 !== 0 || !BASE646.test(value))
|
|
8100
|
+
return false;
|
|
8101
|
+
let binary;
|
|
8102
|
+
try {
|
|
8103
|
+
binary = atob(value);
|
|
8104
|
+
}
|
|
8105
|
+
catch {
|
|
8106
|
+
return false;
|
|
8107
|
+
}
|
|
8108
|
+
return btoa(binary) === value && CIPHERTEXT_BYTES2.includes(binary.length);
|
|
8109
|
+
}
|
|
8110
|
+
function readForm3(body) {
|
|
8111
|
+
if (typeof body !== "string" || body === "" || body.length > BODY_LIMIT44)
|
|
8112
|
+
return null;
|
|
8113
|
+
const entries = [];
|
|
8114
|
+
for (const part of body.split("&")) {
|
|
8115
|
+
const at = part.indexOf("=");
|
|
8116
|
+
if (at <= 0)
|
|
8117
|
+
return null;
|
|
8118
|
+
try {
|
|
8119
|
+
entries.push([decodeURIComponent(part.slice(0, at).replace(/\+/g, " ")), decodeURIComponent(part.slice(at + 1).replace(/\+/g, " "))]);
|
|
8120
|
+
}
|
|
8121
|
+
catch {
|
|
8122
|
+
return null;
|
|
8123
|
+
}
|
|
8124
|
+
}
|
|
8125
|
+
return paystackFormBody(entries) === body ? entries : null;
|
|
8126
|
+
}
|
|
8127
|
+
function paystackBodyVerdict(body) {
|
|
8128
|
+
const entries = readForm3(body);
|
|
8129
|
+
if (entries === null)
|
|
8130
|
+
return refuse45("paystack_body_unsupported");
|
|
8131
|
+
const keys = entries.map(([key]) => key);
|
|
8132
|
+
if (keys.includes("subscription"))
|
|
8133
|
+
return refuse45("paystack_subscription");
|
|
8134
|
+
if (keys.includes("remember_card") && entries.find(([key]) => key === "remember_card")[1] !== "false")
|
|
8135
|
+
return refuse45("paystack_saved_card");
|
|
8136
|
+
const expected = PAYSTACK_BODY_KEYS.filter((key) => !OPTIONAL.has(key) || keys.includes(key));
|
|
8137
|
+
if (keys.length !== expected.length || keys.some((key, i) => key !== expected[i]))
|
|
8138
|
+
return refuse45("paystack_body_unsupported");
|
|
8139
|
+
const fields = Object.fromEntries(entries);
|
|
8140
|
+
if (!isCiphertext2(fields.clientdata))
|
|
8141
|
+
return refuse45("paystack_body_unsupported");
|
|
8142
|
+
for (const [key, shape] of Object.entries(SHAPES4)) {
|
|
8143
|
+
if (own19(fields, key) && !shape.test(fields[key]))
|
|
8144
|
+
return refuse45("paystack_body_unsupported");
|
|
8145
|
+
}
|
|
8146
|
+
return Object.freeze({ verdict: "card", fields: Object.freeze(fields) });
|
|
8147
|
+
}
|
|
8148
|
+
var paystack_default = /* @__PURE__ */ registerProcessor({
|
|
8149
|
+
psp: PAYSTACK_PSP,
|
|
8150
|
+
definitions: [
|
|
8151
|
+
{
|
|
8152
|
+
psp: "paystack",
|
|
8153
|
+
// The card page's charge, as the header above reads it. Live and test transactions share standard.paystack.co,
|
|
8154
|
+
// so no sandbox host is listed and no environment is pinned. Ships dark: served only to a client that declares
|
|
8155
|
+
// `paystack_pinned_key`, and only for a company the backend's processor gate turns Paystack on for.
|
|
8156
|
+
// `(?![\w/.%?#-])` ends the path for a consumer that tests `match` unanchored; the exact-URL rule takes no query.
|
|
8157
|
+
capability: "paystack_pinned_key",
|
|
8158
|
+
match: "standard\\.paystack\\.co/charge/(?![\\w/.%?#-])",
|
|
8159
|
+
hosts: ["^standard\\.paystack\\.co$"],
|
|
8160
|
+
encoding: "form",
|
|
8161
|
+
// The browser's language rides as the page sent it; Origin, Referer and cookies never do (the page sends no cookie).
|
|
8162
|
+
passthroughHeaders: ["^accept-language$"],
|
|
8163
|
+
cardFields: ["clientdata"]
|
|
8164
|
+
}
|
|
8165
|
+
],
|
|
8166
|
+
// Only the cardholder's device sends this charge, after a person approves; no reviewed list names paystack.
|
|
8167
|
+
refusedOperations: [PAYSTACK_OPERATION],
|
|
8168
|
+
// Not surveyed: reading a charge back takes the merchant's secret key, which Agentcard never holds.
|
|
8169
|
+
settlementReadback: "not_surveyed",
|
|
8170
|
+
exactUrl: isPaystackChargeUrl,
|
|
8171
|
+
bodyGate: (url, body) => url !== void 0 && !isPaystackChargeUrl(url) ? refuse45("paystack_url_refused") : paystackBodyVerdict(body),
|
|
8172
|
+
// No amount reader: the charge names none, so the agent's pair is the figure the cardholder approves.
|
|
8173
|
+
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."]
|
|
8174
|
+
});
|
|
6964
8175
|
// src/processors/processout.js
|
|
6965
8176
|
var PROCESSOUT_PSP = "processout";
|
|
6966
8177
|
var PROCESSOUT_OPERATION = "processout.card_request";
|
|
6967
|
-
var
|
|
6968
|
-
var
|
|
8178
|
+
var URL_LIMIT17 = 512;
|
|
8179
|
+
var BODY_LIMIT45 = 4096;
|
|
6969
8180
|
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
8181
|
var PAGE_KEYS2 = /* @__PURE__ */ Object.freeze(["name", "contact", "preferred_scheme"]);
|
|
6971
8182
|
var CONTACT_KEYS = /* @__PURE__ */ Object.freeze(["address1", "address2", "city", "state", "country_code", "zip"]);
|
|
@@ -6980,31 +8191,31 @@ var DEVICE_KEYS4 = /* @__PURE__ */ Object.freeze([
|
|
|
6980
8191
|
]);
|
|
6981
8192
|
var PROCESSOUT_CARD_KEYS = /* @__PURE__ */ Object.freeze(["number", "exp_month", "exp_year", "cvc2"]);
|
|
6982
8193
|
var BODY_KEYS3 = /* @__PURE__ */ new Set([...PAGE_KEYS2, "device", ...DEVICE_KEYS4, ...PROCESSOUT_CARD_KEYS]);
|
|
6983
|
-
var
|
|
6984
|
-
var
|
|
6985
|
-
var
|
|
6986
|
-
var
|
|
8194
|
+
var NUMBER10 = /^[0-9]{12,19}$/;
|
|
8195
|
+
var MONTH23 = /^(?:[1-9]|1[0-2])$/;
|
|
8196
|
+
var YEAR24 = /^20[0-9]{2}$/;
|
|
8197
|
+
var CODE9 = /^[0-9]{3,4}$/;
|
|
6987
8198
|
var TEXT_LIMIT14 = 256;
|
|
6988
8199
|
var SCHEME = /^[A-Za-z][A-Za-z0-9 _-]{0,31}$/;
|
|
6989
8200
|
var LANGUAGE5 = /^[A-Za-z]{1,8}(?:-[A-Za-z0-9]{1,8}){0,4}$/;
|
|
6990
8201
|
var PAN_LIKE7 = /(?:[0-9][^0-9A-Za-z]*){12,}/;
|
|
6991
|
-
var
|
|
6992
|
-
var
|
|
6993
|
-
var
|
|
6994
|
-
var
|
|
6995
|
-
var
|
|
6996
|
-
function base64Of(
|
|
8202
|
+
var record38 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
8203
|
+
var own20 = (value, key) => Object.prototype.hasOwnProperty.call(value, key);
|
|
8204
|
+
var refuse46 = (code) => Object.freeze({ verdict: "refuse", code });
|
|
8205
|
+
var CARD45 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
|
|
8206
|
+
var BASE647 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
8207
|
+
function base64Of(text11) {
|
|
6997
8208
|
let out = "";
|
|
6998
|
-
for (let at = 0; at <
|
|
6999
|
-
const a =
|
|
7000
|
-
const b = at + 1 <
|
|
7001
|
-
const c = at + 2 <
|
|
7002
|
-
out +=
|
|
8209
|
+
for (let at = 0; at < text11.length; at += 3) {
|
|
8210
|
+
const a = text11.charCodeAt(at);
|
|
8211
|
+
const b = at + 1 < text11.length ? text11.charCodeAt(at + 1) : NaN;
|
|
8212
|
+
const c = at + 2 < text11.length ? text11.charCodeAt(at + 2) : NaN;
|
|
8213
|
+
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
8214
|
}
|
|
7004
8215
|
return out;
|
|
7005
8216
|
}
|
|
7006
8217
|
var basicOf = (projectId) => base64Of(`${projectId}:`);
|
|
7007
|
-
function
|
|
8218
|
+
function luhn12(digits4) {
|
|
7008
8219
|
let sum = 0;
|
|
7009
8220
|
for (let at = 0; at < digits4.length; at += 1) {
|
|
7010
8221
|
let digit = Number(digits4[digits4.length - 1 - at]);
|
|
@@ -7018,7 +8229,7 @@ function luhn10(digits4) {
|
|
|
7018
8229
|
return sum % 10 === 0;
|
|
7019
8230
|
}
|
|
7020
8231
|
function processoutCardTarget(url) {
|
|
7021
|
-
if (typeof url !== "string" || url.length >
|
|
8232
|
+
if (typeof url !== "string" || url.length > URL_LIMIT17)
|
|
7022
8233
|
return null;
|
|
7023
8234
|
const match = CARD_URL2.exec(url);
|
|
7024
8235
|
if (!match || match[2] !== basicOf(match[1]))
|
|
@@ -7028,12 +8239,12 @@ function processoutCardTarget(url) {
|
|
|
7028
8239
|
function isProcessoutCardUrl(url) {
|
|
7029
8240
|
return processoutCardTarget(url) !== null;
|
|
7030
8241
|
}
|
|
7031
|
-
function
|
|
7032
|
-
if (typeof body !== "string" || body === "" || body.length >
|
|
8242
|
+
function readBody28(body) {
|
|
8243
|
+
if (typeof body !== "string" || body === "" || body.length > BODY_LIMIT45)
|
|
7033
8244
|
return null;
|
|
7034
8245
|
try {
|
|
7035
8246
|
const value = JSON.parse(body);
|
|
7036
|
-
return
|
|
8247
|
+
return record38(value) && JSON.stringify(value) === body ? value : null;
|
|
7037
8248
|
}
|
|
7038
8249
|
catch {
|
|
7039
8250
|
return null;
|
|
@@ -7051,31 +8262,31 @@ var DEVICE_RULES = /* @__PURE__ */ Object.freeze({
|
|
|
7051
8262
|
});
|
|
7052
8263
|
function soundDevice3(value) {
|
|
7053
8264
|
const device = value.device;
|
|
7054
|
-
if (!
|
|
8265
|
+
if (!record38(device) || !own20(device, "request_origin") || !own20(device, "app_timezone_offset"))
|
|
7055
8266
|
return false;
|
|
7056
|
-
return DEVICE_KEYS4.every((key) =>
|
|
8267
|
+
return DEVICE_KEYS4.every((key) => own20(device, key) ? DEVICE_RULES[key](device[key]) && own20(value, key) && value[key] === device[key] : !own20(value, key)) && Object.keys(device).every((key) => DEVICE_KEYS4.includes(key));
|
|
7057
8268
|
}
|
|
7058
8269
|
function soundPageData(value) {
|
|
7059
|
-
if (
|
|
8270
|
+
if (own20(value, "name") && !pageText2(value.name))
|
|
7060
8271
|
return false;
|
|
7061
|
-
if (
|
|
8272
|
+
if (own20(value, "preferred_scheme") && !(value.preferred_scheme === null || typeof value.preferred_scheme === "string" && SCHEME.test(value.preferred_scheme)))
|
|
7062
8273
|
return false;
|
|
7063
8274
|
const contact = value.contact;
|
|
7064
|
-
return
|
|
8275
|
+
return record38(contact) && Object.keys(contact).every((key) => CONTACT_KEYS.includes(key) && pageText2(contact[key]));
|
|
7065
8276
|
}
|
|
7066
8277
|
function processoutBodyVerdict(body, url) {
|
|
7067
8278
|
if (url !== void 0 && processoutCardTarget(url) === null)
|
|
7068
|
-
return
|
|
7069
|
-
const value =
|
|
8279
|
+
return refuse46("processout_url_refused");
|
|
8280
|
+
const value = readBody28(body);
|
|
7070
8281
|
if (value === null || !Object.keys(value).every((key) => BODY_KEYS3.has(key)))
|
|
7071
|
-
return
|
|
8282
|
+
return refuse46("processout_body_unsupported");
|
|
7072
8283
|
if (!PROCESSOUT_CARD_KEYS.every((key) => typeof value[key] === "string"))
|
|
7073
|
-
return
|
|
7074
|
-
if (!
|
|
7075
|
-
return
|
|
8284
|
+
return refuse46("processout_body_unsupported");
|
|
8285
|
+
if (!NUMBER10.test(value.number) || !luhn12(value.number) || !MONTH23.test(value.exp_month) || !YEAR24.test(value.exp_year) || !CODE9.test(value.cvc2))
|
|
8286
|
+
return refuse46("processout_body_unsupported");
|
|
7076
8287
|
if (!soundPageData(value) || !soundDevice3(value))
|
|
7077
|
-
return
|
|
7078
|
-
return
|
|
8288
|
+
return refuse46("processout_body_unsupported");
|
|
8289
|
+
return CARD45;
|
|
7079
8290
|
}
|
|
7080
8291
|
var processout_default = /* @__PURE__ */ registerProcessor({
|
|
7081
8292
|
psp: PROCESSOUT_PSP,
|
|
@@ -7118,17 +8329,17 @@ var USAEPAY_HOSTS = /* @__PURE__ */ Object.freeze({
|
|
|
7118
8329
|
"sandbox.usaepay.com": "sandbox"
|
|
7119
8330
|
});
|
|
7120
8331
|
var USAEPAY_PAYMENT_KEYS_PATH = "/api/v2/pub/payment_keys";
|
|
7121
|
-
var
|
|
7122
|
-
var
|
|
7123
|
-
var
|
|
8332
|
+
var BODY_LIMIT46 = 512;
|
|
8333
|
+
var URL_LIMIT18 = 256;
|
|
8334
|
+
var CARD_NUMBER22 = /^[0-9]{13,19}$/;
|
|
7124
8335
|
var EXPIRATION2 = /^(?:0[1-9]|1[0-2])[0-9]{2}$/;
|
|
7125
|
-
var
|
|
7126
|
-
var
|
|
7127
|
-
var
|
|
7128
|
-
var
|
|
7129
|
-
var
|
|
8336
|
+
var SECURITY_CODE26 = /^(?:[0-9]{3,4})?$/;
|
|
8337
|
+
var record39 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
8338
|
+
var own21 = (value, key) => Object.prototype.hasOwnProperty.call(value, key);
|
|
8339
|
+
var refuse47 = (code) => Object.freeze({ verdict: "refuse", code });
|
|
8340
|
+
var CARD46 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
|
|
7130
8341
|
function usaepayPaymentKeysUrl(url) {
|
|
7131
|
-
if (typeof url !== "string" || url.length >
|
|
8342
|
+
if (typeof url !== "string" || url.length > URL_LIMIT18 || url.includes("?") || url.includes("#"))
|
|
7132
8343
|
return null;
|
|
7133
8344
|
let parsed;
|
|
7134
8345
|
try {
|
|
@@ -7137,12 +8348,12 @@ function usaepayPaymentKeysUrl(url) {
|
|
|
7137
8348
|
catch {
|
|
7138
8349
|
return null;
|
|
7139
8350
|
}
|
|
7140
|
-
if (parsed.href !== url || parsed.protocol !== "https:" || parsed.port || parsed.username || parsed.password || !
|
|
8351
|
+
if (parsed.href !== url || parsed.protocol !== "https:" || parsed.port || parsed.username || parsed.password || !own21(USAEPAY_HOSTS, parsed.hostname) || parsed.pathname !== USAEPAY_PAYMENT_KEYS_PATH)
|
|
7141
8352
|
return null;
|
|
7142
8353
|
return Object.freeze({ host: parsed.hostname, environment: USAEPAY_HOSTS[parsed.hostname] });
|
|
7143
8354
|
}
|
|
7144
8355
|
var isUsaepayPaymentKeysUrl = (url) => usaepayPaymentKeysUrl(url) !== null;
|
|
7145
|
-
function
|
|
8356
|
+
function luhn13(digits4) {
|
|
7146
8357
|
let sum = 0;
|
|
7147
8358
|
for (let at = digits4.length - 1, double = false; at >= 0; at -= 1, double = !double) {
|
|
7148
8359
|
let digit = digits4.charCodeAt(at) - 48;
|
|
@@ -7152,23 +8363,23 @@ function luhn11(digits4) {
|
|
|
7152
8363
|
}
|
|
7153
8364
|
return sum % 10 === 0;
|
|
7154
8365
|
}
|
|
7155
|
-
function
|
|
7156
|
-
if (typeof body !== "string" || body === "" || body.length >
|
|
8366
|
+
function readBody29(body) {
|
|
8367
|
+
if (typeof body !== "string" || body === "" || body.length > BODY_LIMIT46)
|
|
7157
8368
|
return null;
|
|
7158
8369
|
try {
|
|
7159
8370
|
const value = JSON.parse(body);
|
|
7160
|
-
return
|
|
8371
|
+
return record39(value) && JSON.stringify(value) === body ? value : null;
|
|
7161
8372
|
}
|
|
7162
8373
|
catch {
|
|
7163
8374
|
return null;
|
|
7164
8375
|
}
|
|
7165
8376
|
}
|
|
7166
8377
|
function usaepayBodyVerdict(body) {
|
|
7167
|
-
const value =
|
|
8378
|
+
const value = readBody29(body);
|
|
7168
8379
|
const card = value === null ? null : value.creditcard;
|
|
7169
|
-
if (value === null || Object.keys(value).join() !== "creditcard" || !
|
|
7170
|
-
return
|
|
7171
|
-
return
|
|
8380
|
+
if (value === null || Object.keys(value).join() !== "creditcard" || !record39(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))
|
|
8381
|
+
return refuse47("usaepay_body_unsupported");
|
|
8382
|
+
return CARD46;
|
|
7172
8383
|
}
|
|
7173
8384
|
var usaepay_default = /* @__PURE__ */ registerProcessor({
|
|
7174
8385
|
psp: USAEPAY_PSP,
|
|
@@ -7200,9 +8411,204 @@ var usaepay_default = /* @__PURE__ */ registerProcessor({
|
|
|
7200
8411
|
source: "https://help.usaepay.info/developer/payjs-v2/ , https://help.usaepay.info/api/rest/"
|
|
7201
8412
|
},
|
|
7202
8413
|
exactUrl: isUsaepayPaymentKeysUrl,
|
|
7203
|
-
bodyGate: (url, body) => url !== void 0 && !isUsaepayPaymentKeysUrl(url) ?
|
|
8414
|
+
bodyGate: (url, body) => url !== void 0 && !isUsaepayPaymentKeysUrl(url) ? refuse47("usaepay_url_refused") : usaepayBodyVerdict(body)
|
|
7204
8415
|
// No amount reader: the request names none, so the agent's pair is the figure the cardholder approves.
|
|
7205
8416
|
});
|
|
8417
|
+
// src/processors/viva_wallet.js
|
|
8418
|
+
var VIVA_WALLET_PSP = "viva_wallet";
|
|
8419
|
+
var VIVA_WALLET_OPERATION = "viva_wallet.card_request";
|
|
8420
|
+
var VIVA_WALLET_HOSTS = /* @__PURE__ */ Object.freeze({ "www.vivapayments.com": "production", "demo.vivapayments.com": "sandbox" });
|
|
8421
|
+
var VIVA_WALLET_CHARGE_TOKENS_PATH = "/web2/checkout/v2/chargetokens";
|
|
8422
|
+
var VIVA_WALLET_BODY_KEYS = /* @__PURE__ */ Object.freeze([
|
|
8423
|
+
"orderCode",
|
|
8424
|
+
"amount",
|
|
8425
|
+
"currencyCode",
|
|
8426
|
+
"holderName",
|
|
8427
|
+
"holderMail",
|
|
8428
|
+
"cvc",
|
|
8429
|
+
"number",
|
|
8430
|
+
"expirationMonth",
|
|
8431
|
+
"expirationYear",
|
|
8432
|
+
"installments",
|
|
8433
|
+
"customer",
|
|
8434
|
+
"rememberCard",
|
|
8435
|
+
"friendlyName",
|
|
8436
|
+
"maskedNumber",
|
|
8437
|
+
"bankId",
|
|
8438
|
+
"selectedBrand",
|
|
8439
|
+
"cardholderBrandSelection",
|
|
8440
|
+
"dccOptions",
|
|
8441
|
+
"dccAccepted",
|
|
8442
|
+
"offerCodes",
|
|
8443
|
+
"loyaltySupported",
|
|
8444
|
+
"redeemedAmount",
|
|
8445
|
+
"retrievalReferenceNumber",
|
|
8446
|
+
"scaRequestedTransactionId",
|
|
8447
|
+
"merchantTrns",
|
|
8448
|
+
"captchaToken"
|
|
8449
|
+
]);
|
|
8450
|
+
var BODY_LIMIT47 = 16384;
|
|
8451
|
+
var URL_LIMIT19 = 256;
|
|
8452
|
+
var ORDER_CODE = /^[0-9]{16}$/;
|
|
8453
|
+
var CARD_NUMBER23 = /^[0-9]{13,19}$/;
|
|
8454
|
+
var MONTH24 = /^(?:0[1-9]|1[0-2])$/;
|
|
8455
|
+
var YEAR25 = /^[0-9]{2}$/;
|
|
8456
|
+
var SECURITY_CODE27 = /^[0-9]{3,4}$/;
|
|
8457
|
+
var CAPTCHA_TOKEN = /^[A-Za-z0-9_.-]{20,8192}$/;
|
|
8458
|
+
var MEMBER_NAME = /^[A-Za-z][A-Za-z0-9]{0,31}$/;
|
|
8459
|
+
var SHORT_ID = /^[A-Za-z0-9_-]{1,64}$/;
|
|
8460
|
+
var TEXT4 = /^[^\u0000-\u001f\u007f]{0,200}$/;
|
|
8461
|
+
var CARD_DIGITS2 = /[0-9]{12,}/;
|
|
8462
|
+
var record40 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
8463
|
+
var own22 = (value, key) => Object.prototype.hasOwnProperty.call(value, key);
|
|
8464
|
+
var refuse48 = (code) => Object.freeze({ verdict: "refuse", code });
|
|
8465
|
+
var CARD47 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
|
|
8466
|
+
var inOrder9 = (value, keys) => {
|
|
8467
|
+
let at = 0;
|
|
8468
|
+
for (const name of Object.keys(value)) {
|
|
8469
|
+
while (at < keys.length && keys[at] !== name)
|
|
8470
|
+
at += 1;
|
|
8471
|
+
if (at === keys.length)
|
|
8472
|
+
return false;
|
|
8473
|
+
at += 1;
|
|
8474
|
+
}
|
|
8475
|
+
return true;
|
|
8476
|
+
};
|
|
8477
|
+
var cardDigits2 = (text11) => CARD_DIGITS2.test(text11.replace(/[^0-9A-Za-z]/g, ""));
|
|
8478
|
+
var plainText8 = (value) => typeof value === "string" && TEXT4.test(value) && !cardDigits2(value);
|
|
8479
|
+
var scalar = (value) => value === null || typeof value === "boolean" || Number.isSafeInteger(value) && Math.abs(value) < 1e9 || plainText8(value);
|
|
8480
|
+
var flatRecord = (value, limit) => record40(value) && Object.keys(value).length <= limit && Object.entries(value).every(([key, item]) => MEMBER_NAME.test(key) && scalar(item));
|
|
8481
|
+
function vivaWalletChargeTokensUrl(url) {
|
|
8482
|
+
if (typeof url !== "string" || url.length > URL_LIMIT19 || url.includes("?") || url.includes("#"))
|
|
8483
|
+
return null;
|
|
8484
|
+
let parsed;
|
|
8485
|
+
try {
|
|
8486
|
+
parsed = new URL(url);
|
|
8487
|
+
}
|
|
8488
|
+
catch {
|
|
8489
|
+
return null;
|
|
8490
|
+
}
|
|
8491
|
+
if (parsed.href !== url || parsed.protocol !== "https:" || parsed.port || parsed.username || parsed.password || !own22(VIVA_WALLET_HOSTS, parsed.hostname) || parsed.pathname !== VIVA_WALLET_CHARGE_TOKENS_PATH)
|
|
8492
|
+
return null;
|
|
8493
|
+
return Object.freeze({ host: parsed.hostname, environment: VIVA_WALLET_HOSTS[parsed.hostname] });
|
|
8494
|
+
}
|
|
8495
|
+
var isVivaWalletChargeTokensUrl = (url) => vivaWalletChargeTokensUrl(url) !== null;
|
|
8496
|
+
function luhn14(digits4) {
|
|
8497
|
+
let sum = 0;
|
|
8498
|
+
for (let at = digits4.length - 1, double = false; at >= 0; at -= 1, double = !double) {
|
|
8499
|
+
let digit = digits4.charCodeAt(at) - 48;
|
|
8500
|
+
if (double)
|
|
8501
|
+
digit = digit * 2 > 9 ? digit * 2 - 9 : digit * 2;
|
|
8502
|
+
sum += digit;
|
|
8503
|
+
}
|
|
8504
|
+
return sum % 10 === 0;
|
|
8505
|
+
}
|
|
8506
|
+
function vivaWalletMaskedNumber(number) {
|
|
8507
|
+
return `${number.slice(0, 6)}${"X".repeat(Math.max(0, number.length - 10))}${number.slice(-4)}`;
|
|
8508
|
+
}
|
|
8509
|
+
function readBody30(body) {
|
|
8510
|
+
if (typeof body !== "string" || body === "" || body.length > BODY_LIMIT47)
|
|
8511
|
+
return null;
|
|
8512
|
+
try {
|
|
8513
|
+
const value = JSON.parse(body);
|
|
8514
|
+
return record40(value) && JSON.stringify(value) === body ? value : null;
|
|
8515
|
+
}
|
|
8516
|
+
catch {
|
|
8517
|
+
return null;
|
|
8518
|
+
}
|
|
8519
|
+
}
|
|
8520
|
+
function currencyNumber(value) {
|
|
8521
|
+
if (Number.isSafeInteger(value) && value > 0 && value < 1e3)
|
|
8522
|
+
return value;
|
|
8523
|
+
return typeof value === "string" && /^[0-9]{3}$/.test(value) ? Number(value) : null;
|
|
8524
|
+
}
|
|
8525
|
+
function vivaWalletBodyVerdict(body) {
|
|
8526
|
+
const value = readBody30(body);
|
|
8527
|
+
if (value === null || !Object.keys(value).every((key) => VIVA_WALLET_BODY_KEYS.includes(key))) {
|
|
8528
|
+
return value !== null && (own22(value, "creditCardId") || own22(value, "token")) ? refuse48("viva_wallet_stored_card") : refuse48("viva_wallet_body_unsupported");
|
|
8529
|
+
}
|
|
8530
|
+
if (value.rememberCard !== false)
|
|
8531
|
+
return refuse48(value.rememberCard === true ? "viva_wallet_keep_on_file" : "viva_wallet_body_unsupported");
|
|
8532
|
+
if (value.dccAccepted === true)
|
|
8533
|
+
return refuse48("viva_wallet_currency_conversion");
|
|
8534
|
+
if (own22(value, "dccAccepted") && value.dccAccepted !== false)
|
|
8535
|
+
return refuse48("viva_wallet_body_unsupported");
|
|
8536
|
+
if (own22(value, "scaRequestedTransactionId"))
|
|
8537
|
+
return refuse48("viva_wallet_retry_refused");
|
|
8538
|
+
if (!(value.installments === 0 || value.installments === 1)) {
|
|
8539
|
+
return refuse48(Number.isSafeInteger(value.installments) && value.installments > 1 ? "viva_wallet_installments" : "viva_wallet_body_unsupported");
|
|
8540
|
+
}
|
|
8541
|
+
if (!inOrder9(value, VIVA_WALLET_BODY_KEYS) || ["offerCodes", "loyaltySupported", "redeemedAmount", "retrievalReferenceNumber", "merchantTrns"].some((key) => own22(value, key)))
|
|
8542
|
+
return refuse48("viva_wallet_body_unsupported");
|
|
8543
|
+
const number = value.number;
|
|
8544
|
+
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) && (!own22(value, "friendlyName") || plainText8(value.friendlyName)) && value.maskedNumber === vivaWalletMaskedNumber(number) && (!own22(value, "bankId") || typeof value.bankId === "string" && SHORT_ID.test(value.bankId) || Number.isSafeInteger(value.bankId) && value.bankId >= 0) && (!own22(value, "selectedBrand") || value.selectedBrand === null || flatRecord(value.selectedBrand, 16)) && (!own22(value, "cardholderBrandSelection") || typeof value.cardholderBrandSelection === "boolean") && (!own22(value, "dccOptions") || flatRecord(value.dccOptions, 16)) && (!own22(value, "captchaToken") || typeof value.captchaToken === "string" && CAPTCHA_TOKEN.test(value.captchaToken));
|
|
8545
|
+
return sound ? CARD47 : refuse48("viva_wallet_body_unsupported");
|
|
8546
|
+
}
|
|
8547
|
+
var VIVA_WALLET_CURRENCIES = /* @__PURE__ */ Object.freeze({
|
|
8548
|
+
978: "eur",
|
|
8549
|
+
826: "gbp",
|
|
8550
|
+
946: "ron",
|
|
8551
|
+
985: "pln",
|
|
8552
|
+
203: "czk",
|
|
8553
|
+
348: "huf",
|
|
8554
|
+
752: "sek",
|
|
8555
|
+
208: "dkk"
|
|
8556
|
+
});
|
|
8557
|
+
function vivaWalletAmount(body) {
|
|
8558
|
+
if (vivaWalletBodyVerdict(body).verdict !== "card")
|
|
8559
|
+
return null;
|
|
8560
|
+
const value = JSON.parse(body);
|
|
8561
|
+
const currency = VIVA_WALLET_CURRENCIES[currencyNumber(value.currencyCode)];
|
|
8562
|
+
return currency ? { amountCents: value.amount, currency } : null;
|
|
8563
|
+
}
|
|
8564
|
+
var VIVA_WALLET_MERCHANT_PINS = /* @__PURE__ */ Object.freeze([
|
|
8565
|
+
Object.freeze({
|
|
8566
|
+
id: "klimaka_donation",
|
|
8567
|
+
merchant: "Klimaka",
|
|
8568
|
+
tradeName: "ΚΛΙΜΑΚΑ ΑΜΚΕ",
|
|
8569
|
+
orderCodes: Object.freeze(["7871752880772607"]),
|
|
8570
|
+
origin: "https://www.vivapayments.com",
|
|
8571
|
+
currencyCode: 978
|
|
8572
|
+
}),
|
|
8573
|
+
Object.freeze({
|
|
8574
|
+
id: "desmos_donation",
|
|
8575
|
+
merchant: "Desmos",
|
|
8576
|
+
tradeName: "DESMOS",
|
|
8577
|
+
orderCodes: Object.freeze(["8156257435672606"]),
|
|
8578
|
+
origin: "https://www.vivapayments.com",
|
|
8579
|
+
currencyCode: 978
|
|
8580
|
+
})
|
|
8581
|
+
]);
|
|
8582
|
+
var CARD_MEMBERS = Object.freeze(["cvc", "number", "expirationMonth", "expirationYear", "maskedNumber"]);
|
|
8583
|
+
var viva_wallet_default = /* @__PURE__ */ registerProcessor({
|
|
8584
|
+
psp: VIVA_WALLET_PSP,
|
|
8585
|
+
definitions: [
|
|
8586
|
+
{
|
|
8587
|
+
psp: "viva_wallet",
|
|
8588
|
+
// The page's card request, as the header above reads it. demo.vivapayments.com is Viva's sandbox, pinned to test
|
|
8589
|
+
// rows, which send only Viva's documented test cards (hostEnvironmentPinned, device-replay.js S7).
|
|
8590
|
+
// Ships dark: served only to a client that declares `viva_smart_checkout_chargetoken`, and only for a company the
|
|
8591
|
+
// backend's processor gate turns Viva Wallet on for. `(?![\w/.%-])` ends the path for a consumer that tests `match`
|
|
8592
|
+
// unanchored.
|
|
8593
|
+
capability: "viva_smart_checkout_chargetoken",
|
|
8594
|
+
match: "(?:www|demo)\\.vivapayments\\.com/web2/checkout/v2/chargetokens(?![\\w/.%-])",
|
|
8595
|
+
hosts: ["^www\\.vivapayments\\.com$", "^demo\\.vivapayments\\.com$"],
|
|
8596
|
+
sandboxHosts: ["^demo\\.vivapayments\\.com$"],
|
|
8597
|
+
hostEnvironmentPinned: true,
|
|
8598
|
+
encoding: "json",
|
|
8599
|
+
// The page sends no Authorization; Origin, Referer, cookies and the reCAPTCHA state never ride.
|
|
8600
|
+
passthroughHeaders: [],
|
|
8601
|
+
jsonCardFields: [["number"]]
|
|
8602
|
+
}
|
|
8603
|
+
],
|
|
8604
|
+
// Only the cardholder's device sends this card, after a person approves; no reviewed list names viva_wallet.
|
|
8605
|
+
refusedOperations: [VIVA_WALLET_OPERATION],
|
|
8606
|
+
settlementReadback: "not_surveyed",
|
|
8607
|
+
exactUrl: isVivaWalletChargeTokensUrl,
|
|
8608
|
+
bodyGate: (url, body) => url !== void 0 && !isVivaWalletChargeTokensUrl(url) ? refuse48("viva_wallet_url_refused") : vivaWalletBodyVerdict(body),
|
|
8609
|
+
// The body names the order's amount in cents and its numeric currency, which the page's card-free charge repeats.
|
|
8610
|
+
amount: (template) => record40(template) && isVivaWalletChargeTokensUrl(template.url) ? vivaWalletAmount(template.body) : null
|
|
8611
|
+
});
|
|
7206
8612
|
// src/processors/vtex_payments.js
|
|
7207
8613
|
var VTEX_PAYMENTS_PSP = "vtex_payments";
|
|
7208
8614
|
var VTEX_PAYMENTS_OPERATION = "vtex_payments.card_request";
|
|
@@ -7251,27 +8657,27 @@ var VTEX_PAYMENTS_MERCHANT_PINS = /* @__PURE__ */ Object.freeze([
|
|
|
7251
8657
|
Object.freeze({ account: "alssports", origin: "https://www.als.com", merchant: "Al's Sporting Goods", currency: "USD" }),
|
|
7252
8658
|
Object.freeze({ account: "roadrunnersports", origin: "https://www.roadrunnersports.com", merchant: "Road Runner Sports", currency: "USD" })
|
|
7253
8659
|
]);
|
|
7254
|
-
var
|
|
8660
|
+
var BODY_LIMIT48 = 16384;
|
|
7255
8661
|
var ACCOUNT_HOST = /^([a-z0-9]{1,63})\.vtexvault\.com$/;
|
|
7256
8662
|
var PATH = /^\/api\/payments\/transactions\/([0-9A-Fa-f]{32})\/payments$/;
|
|
7257
8663
|
var ORDER_GROUP = /^[0-9]{6,24}$/;
|
|
7258
|
-
var
|
|
7259
|
-
var
|
|
7260
|
-
var
|
|
8664
|
+
var BASE648 = /^[A-Za-z0-9+/]{4,1020}={0,2}$/;
|
|
8665
|
+
var CARD_NUMBER24 = /^[0-9]{12,19}$/;
|
|
8666
|
+
var SECURITY_CODE28 = /^[0-9]{3,4}$/;
|
|
7261
8667
|
var DUE_DATE = /^(?:0[1-9]|1[0-2])\/[0-9]{2}$/;
|
|
7262
|
-
var
|
|
8668
|
+
var CURRENCY7 = /^[A-Z]{3}$/;
|
|
7263
8669
|
var TRANSACTION_ID = /^[0-9A-Fa-f]{32}$/;
|
|
7264
8670
|
var MERCHANT_NAME = /^[A-Za-z0-9_.-]{1,64}$/;
|
|
7265
|
-
var
|
|
8671
|
+
var SHORT_ID2 = /^[A-Za-z0-9_-]{1,64}$/;
|
|
7266
8672
|
var FINGERPRINT4 = /^[A-Za-z0-9_.:=+/-]{1,256}$/;
|
|
7267
|
-
var
|
|
7268
|
-
var
|
|
8673
|
+
var TEXT5 = /^[^\u0000-\u001f\u007f]{1,200}$/;
|
|
8674
|
+
var CARD_DIGITS3 = /[0-9]{12,}/;
|
|
7269
8675
|
var DEVICE_INFO_KEYS = Object.freeze(["sw", "sh", "cd", "tz", "lang", "java", "sourceApplication"]);
|
|
7270
|
-
var
|
|
7271
|
-
var
|
|
7272
|
-
var
|
|
7273
|
-
var
|
|
7274
|
-
var
|
|
8676
|
+
var record41 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
8677
|
+
var own23 = (value, key) => Object.prototype.hasOwnProperty.call(value, key);
|
|
8678
|
+
var refuse49 = (code) => Object.freeze({ verdict: "refuse", code });
|
|
8679
|
+
var CARD48 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
|
|
8680
|
+
var inOrder10 = (value, keys) => {
|
|
7275
8681
|
let at = 0;
|
|
7276
8682
|
for (const name of Object.keys(value)) {
|
|
7277
8683
|
while (at < keys.length && keys[at] !== name)
|
|
@@ -7282,8 +8688,8 @@ var inOrder8 = (value, keys) => {
|
|
|
7282
8688
|
}
|
|
7283
8689
|
return true;
|
|
7284
8690
|
};
|
|
7285
|
-
var
|
|
7286
|
-
var
|
|
8691
|
+
var cardDigits3 = (text11) => CARD_DIGITS3.test(text11.replace(/[^0-9A-Za-z]/g, ""));
|
|
8692
|
+
var plainText9 = (value) => typeof value === "string" && TEXT5.test(value) && !cardDigits3(value);
|
|
7287
8693
|
var count = (value) => Number.isSafeInteger(value) && value >= 0;
|
|
7288
8694
|
var BASE64_ALPHABET2 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
7289
8695
|
function base64Text2(input) {
|
|
@@ -7307,10 +8713,10 @@ function base64Text2(input) {
|
|
|
7307
8713
|
}
|
|
7308
8714
|
return out;
|
|
7309
8715
|
}
|
|
7310
|
-
function deviceInfoSound(
|
|
7311
|
-
if (typeof
|
|
8716
|
+
function deviceInfoSound(text11) {
|
|
8717
|
+
if (typeof text11 !== "string" || !BASE648.test(text11))
|
|
7312
8718
|
return false;
|
|
7313
|
-
const decoded = base64Text2(
|
|
8719
|
+
const decoded = base64Text2(text11);
|
|
7314
8720
|
if (decoded === null)
|
|
7315
8721
|
return false;
|
|
7316
8722
|
let info;
|
|
@@ -7320,18 +8726,18 @@ function deviceInfoSound(text10) {
|
|
|
7320
8726
|
catch {
|
|
7321
8727
|
return false;
|
|
7322
8728
|
}
|
|
7323
|
-
if (!
|
|
8729
|
+
if (!record41(info) || !Object.keys(info).every((key) => DEVICE_INFO_KEYS.includes(key)))
|
|
7324
8730
|
return false;
|
|
7325
8731
|
for (const key of ["sw", "sh", "cd"])
|
|
7326
|
-
if (
|
|
8732
|
+
if (own23(info, key) && !(count(info[key]) && info[key] <= 1e5))
|
|
7327
8733
|
return false;
|
|
7328
|
-
if (
|
|
8734
|
+
if (own23(info, "tz") && !(Number.isSafeInteger(info.tz) && Math.abs(info.tz) <= 1440))
|
|
7329
8735
|
return false;
|
|
7330
|
-
if (
|
|
8736
|
+
if (own23(info, "lang") && !(typeof info.lang === "string" && /^[A-Za-z]{0,8}$/.test(info.lang)))
|
|
7331
8737
|
return false;
|
|
7332
|
-
if (
|
|
8738
|
+
if (own23(info, "java") && typeof info.java !== "boolean")
|
|
7333
8739
|
return false;
|
|
7334
|
-
return !
|
|
8740
|
+
return !own23(info, "sourceApplication") || typeof info.sourceApplication === "string" && /^[A-Za-z0-9_.-]{1,32}$/.test(info.sourceApplication);
|
|
7335
8741
|
}
|
|
7336
8742
|
function vtexPaymentsCardTarget(url) {
|
|
7337
8743
|
if (typeof url !== "string" || url.length > 8192)
|
|
@@ -7377,8 +8783,8 @@ function isVtexPaymentsCardUrl(url) {
|
|
|
7377
8783
|
const target = vtexPaymentsCardTarget(url);
|
|
7378
8784
|
return target !== null && !target.fallback;
|
|
7379
8785
|
}
|
|
7380
|
-
function
|
|
7381
|
-
if (typeof body !== "string" || body === "" || body.length >
|
|
8786
|
+
function readBody31(body) {
|
|
8787
|
+
if (typeof body !== "string" || body === "" || body.length > BODY_LIMIT48)
|
|
7382
8788
|
return null;
|
|
7383
8789
|
let value;
|
|
7384
8790
|
try {
|
|
@@ -7392,13 +8798,13 @@ function readBody26(body) {
|
|
|
7392
8798
|
return value;
|
|
7393
8799
|
}
|
|
7394
8800
|
function cardLine(line) {
|
|
7395
|
-
if (!
|
|
8801
|
+
if (!record41(line))
|
|
7396
8802
|
return false;
|
|
7397
|
-
const fields =
|
|
7398
|
-
return line.groupName === "creditCardPaymentGroup" || line.groupName === "debitCardPaymentGroup" ||
|
|
8803
|
+
const fields = record41(line.fields) ? line.fields : {};
|
|
8804
|
+
return line.groupName === "creditCardPaymentGroup" || line.groupName === "debitCardPaymentGroup" || own23(line, "accountId") || own23(fields, "accountId") || own23(fields, "cardNumber") || own23(fields, "validationCode") || own23(fields, "dueDate");
|
|
7399
8805
|
}
|
|
7400
8806
|
function addressSound(address2) {
|
|
7401
|
-
if (!
|
|
8807
|
+
if (!record41(address2) || !inOrder10(address2, VTEX_PAYMENTS_ADDRESS_KEYS))
|
|
7402
8808
|
return false;
|
|
7403
8809
|
for (const [key, value] of Object.entries(address2)) {
|
|
7404
8810
|
if (key === "addressType") {
|
|
@@ -7407,60 +8813,60 @@ function addressSound(address2) {
|
|
|
7407
8813
|
continue;
|
|
7408
8814
|
}
|
|
7409
8815
|
if (key === "addressId") {
|
|
7410
|
-
if (!(typeof value === "string" &&
|
|
8816
|
+
if (!(typeof value === "string" && SHORT_ID2.test(value)))
|
|
7411
8817
|
return false;
|
|
7412
8818
|
continue;
|
|
7413
8819
|
}
|
|
7414
8820
|
if (value === null && (key === "complement" || key === "reference"))
|
|
7415
8821
|
continue;
|
|
7416
|
-
if (!(value === "" ||
|
|
8822
|
+
if (!(value === "" || plainText9(value)))
|
|
7417
8823
|
return false;
|
|
7418
8824
|
}
|
|
7419
8825
|
return true;
|
|
7420
8826
|
}
|
|
7421
8827
|
function fieldsSound(fields) {
|
|
7422
|
-
if (!
|
|
8828
|
+
if (!record41(fields) || !inOrder10(fields, VTEX_PAYMENTS_FIELD_KEYS) || own23(fields, "metadata"))
|
|
7423
8829
|
return false;
|
|
7424
|
-
if (!(typeof fields.cardNumber === "string" &&
|
|
8830
|
+
if (!(typeof fields.cardNumber === "string" && CARD_NUMBER24.test(fields.cardNumber)))
|
|
7425
8831
|
return false;
|
|
7426
|
-
if (!(typeof fields.validationCode === "string" &&
|
|
8832
|
+
if (!(typeof fields.validationCode === "string" && SECURITY_CODE28.test(fields.validationCode)))
|
|
7427
8833
|
return false;
|
|
7428
8834
|
if (!(typeof fields.dueDate === "string" && DUE_DATE.test(fields.dueDate)))
|
|
7429
8835
|
return false;
|
|
7430
|
-
if (!
|
|
8836
|
+
if (!plainText9(fields.holderName))
|
|
7431
8837
|
return false;
|
|
7432
|
-
if (
|
|
8838
|
+
if (own23(fields, "document") && !(fields.document === "" || plainText9(fields.document) && fields.document.length <= 32))
|
|
7433
8839
|
return false;
|
|
7434
|
-
if (
|
|
8840
|
+
if (own23(fields, "address") && !addressSound(fields.address))
|
|
7435
8841
|
return false;
|
|
7436
|
-
if (
|
|
8842
|
+
if (own23(fields, "deviceFingerprint") && !(typeof fields.deviceFingerprint === "string" && FINGERPRINT4.test(fields.deviceFingerprint)))
|
|
7437
8843
|
return false;
|
|
7438
|
-
return !
|
|
8844
|
+
return !own23(fields, "addressId") || typeof fields.addressId === "string" && SHORT_ID2.test(fields.addressId);
|
|
7439
8845
|
}
|
|
7440
8846
|
function vtexPaymentsBodyVerdict(body, target) {
|
|
7441
|
-
const lines =
|
|
7442
|
-
if (lines === null || lines.length === 0 || !lines.every(
|
|
7443
|
-
return
|
|
8847
|
+
const lines = readBody31(body);
|
|
8848
|
+
if (lines === null || lines.length === 0 || !lines.every(record41))
|
|
8849
|
+
return refuse49("vtex_payments_body_unsupported");
|
|
7444
8850
|
const cards = lines.filter(cardLine);
|
|
7445
|
-
if (cards.some((line2) =>
|
|
7446
|
-
return
|
|
8851
|
+
if (cards.some((line2) => own23(line2, "accountId") || own23(line2.fields ?? {}, "accountId")))
|
|
8852
|
+
return refuse49("vtex_payments_saved_card");
|
|
7447
8853
|
if (cards.length === 0)
|
|
7448
|
-
return
|
|
7449
|
-
if (lines.length !== 1 ||
|
|
7450
|
-
return
|
|
8854
|
+
return refuse49("vtex_payments_body_unsupported");
|
|
8855
|
+
if (lines.length !== 1 || own23(lines[0], "id"))
|
|
8856
|
+
return refuse49("vtex_payments_split_payment");
|
|
7451
8857
|
const line = lines[0];
|
|
7452
|
-
if (!
|
|
7453
|
-
return
|
|
7454
|
-
if (!(typeof line.currencyCode === "string" &&
|
|
7455
|
-
return
|
|
7456
|
-
if (line.installments !== 1 || line.referenceValue !== line.value ||
|
|
7457
|
-
return
|
|
8858
|
+
if (!inOrder10(line, VTEX_PAYMENTS_LINE_KEYS) || line.groupName !== "creditCardPaymentGroup")
|
|
8859
|
+
return refuse49("vtex_payments_body_unsupported");
|
|
8860
|
+
if (!(typeof line.currencyCode === "string" && CURRENCY7.test(line.currencyCode)) || !own23(VTEX_PAYMENTS_NETWORKS, line.paymentSystem) || !Number.isSafeInteger(line.paymentSystem) || !(count(line.value) && line.value > 0))
|
|
8861
|
+
return refuse49("vtex_payments_body_unsupported");
|
|
8862
|
+
if (line.installments !== 1 || line.referenceValue !== line.value || own23(line, "installmentsInterestRate") && line.installmentsInterestRate !== 0 || own23(line, "installmentsValue") && line.installmentsValue !== line.value)
|
|
8863
|
+
return refuse49("vtex_payments_installments");
|
|
7458
8864
|
const transaction = line.transaction;
|
|
7459
|
-
if (!
|
|
7460
|
-
return
|
|
8865
|
+
if (!record41(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)))
|
|
8866
|
+
return refuse49("vtex_payments_body_unsupported");
|
|
7461
8867
|
if (target && transaction.id.toUpperCase() !== target.transactionId.toUpperCase())
|
|
7462
|
-
return
|
|
7463
|
-
return fieldsSound(line.fields) ?
|
|
8868
|
+
return refuse49("vtex_payments_split_payment");
|
|
8869
|
+
return fieldsSound(line.fields) ? CARD48 : refuse49("vtex_payments_body_unsupported");
|
|
7464
8870
|
}
|
|
7465
8871
|
function vtexPaymentsAmount(body) {
|
|
7466
8872
|
if (vtexPaymentsBodyVerdict(body).verdict !== "card")
|
|
@@ -7505,21 +8911,29 @@ var vtex_payments_default = /* @__PURE__ */ registerProcessor({
|
|
|
7505
8911
|
return vtexPaymentsBodyVerdict(body);
|
|
7506
8912
|
const target = vtexPaymentsCardTarget(url);
|
|
7507
8913
|
if (target === null)
|
|
7508
|
-
return
|
|
7509
|
-
return target.fallback ?
|
|
8914
|
+
return refuse49("vtex_payments_url_refused");
|
|
8915
|
+
return target.fallback ? refuse49("vtex_payments_fallback_refused") : vtexPaymentsBodyVerdict(body, target);
|
|
7510
8916
|
},
|
|
7511
|
-
amount: (template) =>
|
|
8917
|
+
amount: (template) => record41(template) && isVtexPaymentsCardUrl(template.url) ? vtexPaymentsAmount(template.body) : null
|
|
7512
8918
|
});
|
|
7513
8919
|
// src/processors/index.generated.js
|
|
7514
8920
|
var REGISTERED_MODULES = Object.freeze({
|
|
8921
|
+
aurus: aurus_default,
|
|
8922
|
+
bigcommerce: bigcommerce_default,
|
|
7515
8923
|
bluesnap: bluesnap_default,
|
|
8924
|
+
cardlink_vpos: cardlink_vpos_default,
|
|
8925
|
+
eghl: eghl_default,
|
|
8926
|
+
frisbii: frisbii_default,
|
|
7516
8927
|
iyzico: iyzico_default,
|
|
7517
8928
|
midtrans: midtrans_default,
|
|
8929
|
+
monei: monei_default,
|
|
7518
8930
|
oceanpayment: oceanpayment_default,
|
|
7519
8931
|
paymentwall: paymentwall_default,
|
|
7520
8932
|
payplug: payplug_default,
|
|
8933
|
+
paystack: paystack_default,
|
|
7521
8934
|
processout: processout_default,
|
|
7522
8935
|
usaepay: usaepay_default,
|
|
8936
|
+
viva_wallet: viva_wallet_default,
|
|
7523
8937
|
vtex_payments: vtex_payments_default
|
|
7524
8938
|
});
|
|
7525
8939
|
// src/registry.js
|
|
@@ -7708,7 +9122,7 @@ function carriesCardFields(recognizer, body) {
|
|
|
7708
9122
|
if (typeof body !== "string" || body === "")
|
|
7709
9123
|
return false;
|
|
7710
9124
|
const anyCase = recognizer.caseInsensitiveFormKeys === true;
|
|
7711
|
-
const wanted = anyCase ? fields.map((
|
|
9125
|
+
const wanted = anyCase ? fields.map((field5) => String(field5).toLowerCase()) : fields;
|
|
7712
9126
|
for (const chunk of body.split("&")) {
|
|
7713
9127
|
const eq = chunk.indexOf("=");
|
|
7714
9128
|
if (eq <= 0 || eq === chunk.length - 1)
|
|
@@ -7799,20 +9213,20 @@ var KEEP_ON_FILE_REFUSAL = "Refusing to pay: this Primer payment would keep the
|
|
|
7799
9213
|
var UNSUPPORTED_SDK_REFUSAL = "Refusing to pay: this checkout uses a Primer SDK Agentcard does not support yet. Nothing was sent.";
|
|
7800
9214
|
var NETWORK_MISMATCH_REFUSAL = "Refusing to pay: this Primer payment names a card network that is not your card's. Nothing was sent.";
|
|
7801
9215
|
var FILL_REFUSAL = "Could not fill the card fields for Primer. Nothing was sent.";
|
|
7802
|
-
var
|
|
9216
|
+
var BODY_LIMIT49 = 16384;
|
|
7803
9217
|
var RESPONSE_LIMIT = 32768;
|
|
7804
9218
|
var ROOT_KEYS10 = ["paymentInstrument", "userDescription", "tokenType", "paymentFlow"];
|
|
7805
9219
|
var INSTRUMENT_KEYS = ["number", "cvv", "expirationMonth", "expirationYear", "cardholderName", "preferredNetwork"];
|
|
7806
9220
|
var REQUIRED_INSTRUMENT_KEYS = ["number", "cvv", "expirationMonth", "expirationYear"];
|
|
7807
|
-
var
|
|
9221
|
+
var record42 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
7808
9222
|
var owns8 = (value, key) => Object.prototype.hasOwnProperty.call(value, key);
|
|
7809
9223
|
var exact5 = (pattern, value) => typeof value === "string" && pattern.exec(value)?.[0] === value;
|
|
7810
|
-
var
|
|
9224
|
+
var text10 = (value, max) => typeof value === "string" && value.length <= max && !/[\u0000-\u001f\u007f]/.test(value);
|
|
7811
9225
|
var digits3 = (value, min, max) => typeof value === "string" && value.length >= min && value.length <= max && !/[^0-9]/.test(value);
|
|
7812
9226
|
var panLike2 = (value) => /(?:[0-9][ _.:-]*){12,}/.test(value);
|
|
7813
|
-
var plain2 = (value, max) =>
|
|
7814
|
-
var
|
|
7815
|
-
var
|
|
9227
|
+
var plain2 = (value, max) => text10(value, max) && !panLike2(value);
|
|
9228
|
+
var MONTH25 = /^(?:0[1-9]|1[0-2])$/;
|
|
9229
|
+
var YEAR26 = /^20[0-9]{2}$/;
|
|
7816
9230
|
var NETWORK3 = /^[A-Z][A-Z_]{1,31}$/;
|
|
7817
9231
|
function isPrimerTokenizeUrl(url, method = "POST") {
|
|
7818
9232
|
if (method !== "POST" || typeof url !== "string" || url.length > 256 || url.includes("?") || url.includes("#"))
|
|
@@ -7827,7 +9241,7 @@ function isPrimerTokenizeUrl(url, method = "POST") {
|
|
|
7827
9241
|
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
9242
|
}
|
|
7829
9243
|
function judgeBody6(body) {
|
|
7830
|
-
if (typeof body !== "string" || body === "" || body.length >
|
|
9244
|
+
if (typeof body !== "string" || body === "" || body.length > BODY_LIMIT49)
|
|
7831
9245
|
return null;
|
|
7832
9246
|
let value;
|
|
7833
9247
|
try {
|
|
@@ -7836,14 +9250,14 @@ function judgeBody6(body) {
|
|
|
7836
9250
|
catch {
|
|
7837
9251
|
return null;
|
|
7838
9252
|
}
|
|
7839
|
-
if (!
|
|
9253
|
+
if (!record42(value) || !roundTrips(value, body))
|
|
7840
9254
|
return null;
|
|
7841
9255
|
if (!Object.keys(value).every((key) => ROOT_KEYS10.includes(key)) || !owns8(value, "paymentInstrument"))
|
|
7842
9256
|
return null;
|
|
7843
9257
|
const instrument = value.paymentInstrument;
|
|
7844
|
-
if (!
|
|
9258
|
+
if (!record42(instrument) || !Object.keys(instrument).every((key) => INSTRUMENT_KEYS.includes(key)) || !REQUIRED_INSTRUMENT_KEYS.every((key) => owns8(instrument, key)))
|
|
7845
9259
|
return null;
|
|
7846
|
-
if (!digits3(instrument.number, 12, 19) || !digits3(instrument.cvv, 3, 4) || !exact5(
|
|
9260
|
+
if (!digits3(instrument.number, 12, 19) || !digits3(instrument.cvv, 3, 4) || !exact5(MONTH25, instrument.expirationMonth) || !exact5(YEAR26, instrument.expirationYear))
|
|
7847
9261
|
return null;
|
|
7848
9262
|
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
9263
|
return null;
|
|
@@ -7869,7 +9283,7 @@ var CLIENT_TOKEN = /^[A-Za-z0-9._~+/=-]{16,4096}$/;
|
|
|
7869
9283
|
var REQUEST_ID = /^[A-Za-z0-9-]{1,64}$/;
|
|
7870
9284
|
var API_VERSION = /^2\.[0-9]{1,2}$/;
|
|
7871
9285
|
function readHeaders(headers) {
|
|
7872
|
-
if (!
|
|
9286
|
+
if (!record42(headers))
|
|
7873
9287
|
return null;
|
|
7874
9288
|
const folded = /* @__PURE__ */ new Map();
|
|
7875
9289
|
for (const [name, value] of Object.entries(headers)) {
|
|
@@ -7916,7 +9330,7 @@ function onTokenizePath(url) {
|
|
|
7916
9330
|
}
|
|
7917
9331
|
}
|
|
7918
9332
|
function primerTokenizeRefusal(request) {
|
|
7919
|
-
if (!
|
|
9333
|
+
if (!record42(request) || request.method !== "POST" || !isPrimerTokenizeUrl(request.url))
|
|
7920
9334
|
return "unsupported";
|
|
7921
9335
|
return headersRefusal(request.headers) ?? primerBodyRefusal(request.body);
|
|
7922
9336
|
}
|
|
@@ -7931,7 +9345,7 @@ function primerCardOnFileRefusal(url, options, policy = PRIMER_SESSION_CARD_ON_F
|
|
|
7931
9345
|
return "unsupported";
|
|
7932
9346
|
if (new URL(url).hostname !== LIVE_PCI_HOST)
|
|
7933
9347
|
return null;
|
|
7934
|
-
return primerCardOnFileDisclosure(url, policy) &&
|
|
9348
|
+
return primerCardOnFileDisclosure(url, policy) && record42(options) && options.keepOnFile === true ? null : "keep_on_file";
|
|
7935
9349
|
}
|
|
7936
9350
|
function primerRefusalMessage(reason) {
|
|
7937
9351
|
if (reason === "keep_on_file")
|
|
@@ -7992,7 +9406,7 @@ function injectPrimerCard(body, card) {
|
|
|
7992
9406
|
}
|
|
7993
9407
|
var TOKEN4 = /^[A-Za-z0-9_-]{8,256}$/;
|
|
7994
9408
|
var ERROR_ID = /^[A-Za-z][A-Za-z0-9_.-]{0,63}$/;
|
|
7995
|
-
var
|
|
9409
|
+
var CODE10 = /^[A-Z][A-Z0-9_]{0,63}$/;
|
|
7996
9410
|
var NETWORK_NAME2 = /^[A-Za-z][A-Za-z0-9 _-]{0,31}$/;
|
|
7997
9411
|
var RESPONSE_MONTH = /^(?:0?[1-9]|1[0-2])$/;
|
|
7998
9412
|
var RESPONSE_YEAR = /^(?:[0-9]{2}|20[0-9]{2})$/;
|
|
@@ -8015,7 +9429,7 @@ function readAnswer(body) {
|
|
|
8015
9429
|
return null;
|
|
8016
9430
|
try {
|
|
8017
9431
|
const value = JSON.parse(body);
|
|
8018
|
-
return
|
|
9432
|
+
return record42(value) ? value : null;
|
|
8019
9433
|
}
|
|
8020
9434
|
catch {
|
|
8021
9435
|
return null;
|
|
@@ -8024,16 +9438,16 @@ function readAnswer(body) {
|
|
|
8024
9438
|
var tokenValue = (value) => exact5(TOKEN4, value) && !panLike2(value);
|
|
8025
9439
|
var optional = (value, key, check) => !owns8(value, key) || value[key] === null || check(value[key]);
|
|
8026
9440
|
function cardDetails(data) {
|
|
8027
|
-
if (!
|
|
9441
|
+
if (!record42(data) || !exact5(/^[0-9]{4}$/, data.last4Digits))
|
|
8028
9442
|
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",
|
|
9443
|
+
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", record42))
|
|
8030
9444
|
return null;
|
|
8031
9445
|
const safe = { last4Digits: data.last4Digits };
|
|
8032
9446
|
for (const key of ["first6Digits", "expirationMonth", "expirationYear", "cardholderName", "network", "isNetworkTokenized"]) {
|
|
8033
9447
|
if (owns8(data, key) && data[key] !== null)
|
|
8034
9448
|
safe[key] = data[key];
|
|
8035
9449
|
}
|
|
8036
|
-
if (
|
|
9450
|
+
if (record42(data.binData)) {
|
|
8037
9451
|
const bin = {};
|
|
8038
9452
|
for (const key of BIN_KEYS) {
|
|
8039
9453
|
if (!owns8(data.binData, key) || data.binData[key] === null)
|
|
@@ -8051,7 +9465,7 @@ function cardDetails(data) {
|
|
|
8051
9465
|
function threeDsSummary(value) {
|
|
8052
9466
|
if (value === void 0 || value === null)
|
|
8053
9467
|
return null;
|
|
8054
|
-
if (!
|
|
9468
|
+
if (!record42(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
9469
|
return void 0;
|
|
8056
9470
|
const safe = { responseCode: value.responseCode };
|
|
8057
9471
|
for (const key of ["reasonCode", "reasonText", "protocolVersion", "challengeIssued"]) {
|
|
@@ -8079,7 +9493,7 @@ function rebuildToken(value) {
|
|
|
8079
9493
|
}
|
|
8080
9494
|
function primerErrorId(body) {
|
|
8081
9495
|
const value = readAnswer(body);
|
|
8082
|
-
const id = value &&
|
|
9496
|
+
const id = value && record42(value.error) ? value.error.errorId : null;
|
|
8083
9497
|
return exact5(ERROR_ID, id) && !panLike2(id) ? id : null;
|
|
8084
9498
|
}
|
|
8085
9499
|
function matchesCard(details, card) {
|