@agent-cards/sdk 0.23.12 → 0.23.14
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 +38 -1
- package/LICENSE +38 -0
- package/PREFLIGHT.md +1 -1
- package/README.md +53 -14
- package/dist/adyen-merchant-hosted.generated.js +2 -2
- package/dist/builtin-registry.generated.js +1 -1
- package/dist/card-fields.generated.js +843 -3
- package/dist/cdp.js +101 -13
- package/dist/client.d.ts +91 -2
- package/dist/client.js +205 -13
- package/dist/creditguard.generated.d.ts +100 -2
- package/dist/creditguard.generated.js +333 -3
- package/dist/datatrans.generated.d.ts +19 -4
- package/dist/datatrans.generated.js +15 -3
- package/dist/ebanx.d.ts +107 -0
- package/dist/ebanx.generated.d.ts +78 -0
- package/dist/ebanx.generated.js +577 -0
- package/dist/ebanx.js +159 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +2 -0
- package/dist/lifecycle.d.ts +35 -3
- package/dist/lifecycle.js +38 -3
- package/dist/paddle-tokenex.d.ts +56 -0
- package/dist/paddle-tokenex.generated.d.ts +67 -0
- package/dist/paddle-tokenex.generated.js +951 -0
- package/dist/paddle-tokenex.js +95 -0
- package/dist/paddle-vgs-pay.d.ts +55 -0
- package/dist/paddle-vgs-pay.js +115 -0
- package/dist/paddle-vgs.generated.d.ts +29 -1
- package/dist/paddle-vgs.generated.js +124 -5
- package/dist/paysafe.generated.d.ts +5 -7
- package/dist/paysafe.generated.js +50 -18
- package/dist/pre-claim.d.ts +46 -1
- package/dist/pre-claim.js +338 -17
- package/dist/preparation.d.ts +13 -0
- package/dist/preparation.js +22 -0
- package/dist/prepared-processor.js +6 -2
- package/dist/primer.generated.js +878 -38
- package/dist/redsys.d.ts +42 -0
- package/dist/redsys.js +68 -0
- package/dist/stripe-checkout.generated.js +479 -11
- package/package.json +9 -6
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: 7d04123b22f392dd6a11848e8cf59b62efb1669527938a7dd1c83a34cb315621
|
|
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 text3 = typeof value === "number" && Number.isFinite(value) ? String(value) : value;
|
|
113
|
+
const m = typeof text3 === "string" ? AMOUNT.exec(text3) : null;
|
|
114
114
|
if (!m)
|
|
115
115
|
return null;
|
|
116
116
|
const cents = Number(m[1]) * 100 + Number(((m[2] ?? "") + "00").slice(0, 2));
|
|
@@ -414,13 +414,853 @@ var pin2 = (fields) => Object.freeze({
|
|
|
414
414
|
var PADDLE_VGS_MERCHANT_PINS = /* @__PURE__ */ Object.freeze([
|
|
415
415
|
pin2({ id: "rectangle_pro", merchant: "Rectangle Pro", origins: ["https://rectangleapp.com"], sellerClaim: null })
|
|
416
416
|
]);
|
|
417
|
+
var FACT_KEYS = /* @__PURE__ */ Object.freeze(["card_first_six", "card_last_four", "expiry_month", "expiry_year", "card_brand"]);
|
|
418
|
+
var METADATA_KEYS = /* @__PURE__ */ Object.freeze(["cardholder_name", ...FACT_KEYS]);
|
|
419
|
+
// src/payfast.js
|
|
420
|
+
var PAYFAST_PSP = "payfast";
|
|
421
|
+
var PAYFAST_PAY_HOSTS = /* @__PURE__ */ Object.freeze({
|
|
422
|
+
production: Object.freeze(["payment.payfast.io", "www.payfast.co.za"]),
|
|
423
|
+
sandbox: Object.freeze(["sandbox.payfast.co.za"])
|
|
424
|
+
});
|
|
425
|
+
var PAYFAST_BODY_KEYS = /* @__PURE__ */ Object.freeze([
|
|
426
|
+
"card_number",
|
|
427
|
+
"cardholder_name",
|
|
428
|
+
"consent_check",
|
|
429
|
+
"cvv",
|
|
430
|
+
"expiry_month",
|
|
431
|
+
"expiry_year",
|
|
432
|
+
"g-recaptcha-response",
|
|
433
|
+
"captcha_version",
|
|
434
|
+
"captcha_action"
|
|
435
|
+
]);
|
|
436
|
+
var BODY_LIMIT3 = 8192;
|
|
437
|
+
var URL_LIMIT = 256;
|
|
438
|
+
var PAY_PATH = /^\/eng\/method\/CreditCard\/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\/pay$/;
|
|
439
|
+
var VISA = /^4[0-9]{15}$/;
|
|
440
|
+
var MASTERCARD = /^(?:5[1-5][0-9]{14}|2(?:2(?:2[1-9]|[3-9][0-9])|[3-6][0-9]{2}|7(?:[01][0-9]|20))[0-9]{12})$/;
|
|
441
|
+
var AMEX = /^3[47][0-9]{13}$/;
|
|
442
|
+
var SECURITY_CODE3 = /^[0-9]{3,4}$/;
|
|
443
|
+
var MONTH = /^(?:0?[1-9]|1[0-2])$/;
|
|
444
|
+
var YEAR = /^[0-9]{2}$/;
|
|
445
|
+
var HOLDER = /^(?!(?:[^0-9]*[0-9]){3})[a-zA-Z0-9 -]+\.?[a-zA-Z0-9 -]+$/;
|
|
446
|
+
var HOLDER_LIMIT = 256;
|
|
447
|
+
var CAPTCHA_VERSIONS = /* @__PURE__ */ Object.freeze(["v0", "v1", "v2"]);
|
|
448
|
+
var SOLVED_CAPTCHA2 = /^[A-Za-z0-9_-]{1,4096}$/;
|
|
449
|
+
var refuse5 = (code) => Object.freeze({ verdict: "refuse", code });
|
|
450
|
+
var CARD5 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
|
|
451
|
+
var formEncode = (value) => encodeURIComponent(value).replace(/%20/g, "+");
|
|
452
|
+
function payfastEnvironment(url) {
|
|
453
|
+
if (typeof url !== "string" || url.length > URL_LIMIT || url.includes("?") || url.includes("#"))
|
|
454
|
+
return null;
|
|
455
|
+
let parsed;
|
|
456
|
+
try {
|
|
457
|
+
parsed = new URL(url);
|
|
458
|
+
}
|
|
459
|
+
catch {
|
|
460
|
+
return null;
|
|
461
|
+
}
|
|
462
|
+
if (parsed.href !== url || parsed.protocol !== "https:" || parsed.port || parsed.username || parsed.password || !PAY_PATH.test(parsed.pathname))
|
|
463
|
+
return null;
|
|
464
|
+
if (PAYFAST_PAY_HOSTS.production.includes(parsed.hostname))
|
|
465
|
+
return "production";
|
|
466
|
+
if (PAYFAST_PAY_HOSTS.sandbox.includes(parsed.hostname))
|
|
467
|
+
return "sandbox";
|
|
468
|
+
return null;
|
|
469
|
+
}
|
|
470
|
+
function isPayfastPayUrl(url) {
|
|
471
|
+
return payfastEnvironment(url) !== null;
|
|
472
|
+
}
|
|
473
|
+
function readForm(body) {
|
|
474
|
+
if (typeof body !== "string" || body === "" || body.length > BODY_LIMIT3)
|
|
475
|
+
return null;
|
|
476
|
+
try {
|
|
477
|
+
const pairs = body.split("&").map((chunk) => {
|
|
478
|
+
const eq = chunk.indexOf("=");
|
|
479
|
+
if (eq <= 0)
|
|
480
|
+
throw new URIError("not a form pair");
|
|
481
|
+
return [decodeURIComponent(chunk.slice(0, eq).replace(/\+/g, " ")), decodeURIComponent(chunk.slice(eq + 1).replace(/\+/g, " "))];
|
|
482
|
+
});
|
|
483
|
+
return pairs.map(([key, value]) => `${formEncode(key)}=${formEncode(value)}`).join("&") === body ? pairs : null;
|
|
484
|
+
}
|
|
485
|
+
catch {
|
|
486
|
+
return null;
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
function cardNetwork(number) {
|
|
490
|
+
if (typeof number !== "string")
|
|
491
|
+
return null;
|
|
492
|
+
if (VISA.test(number))
|
|
493
|
+
return "visa";
|
|
494
|
+
if (MASTERCARD.test(number))
|
|
495
|
+
return "mastercard";
|
|
496
|
+
return AMEX.test(number) ? "amex" : null;
|
|
497
|
+
}
|
|
498
|
+
function judgeBody(body) {
|
|
499
|
+
const pairs = readForm(body);
|
|
500
|
+
if (pairs === null)
|
|
501
|
+
return { code: "payfast_body_unsupported", pairs: null };
|
|
502
|
+
if (pairs.some(([key]) => key === "cc_key"))
|
|
503
|
+
return { code: "payfast_saved_card", pairs: null };
|
|
504
|
+
if (pairs.length !== PAYFAST_BODY_KEYS.length || !pairs.every(([key], at) => key === PAYFAST_BODY_KEYS[at])) {
|
|
505
|
+
return { code: "payfast_body_unsupported", pairs: null };
|
|
506
|
+
}
|
|
507
|
+
const value = Object.fromEntries(pairs);
|
|
508
|
+
const answer = value["g-recaptcha-response"];
|
|
509
|
+
if (cardNetwork(value.card_number) === null || !SECURITY_CODE3.test(value.cvv) || !MONTH.test(value.expiry_month) || !YEAR.test(value.expiry_year) || value.cardholder_name.length > HOLDER_LIMIT || !HOLDER.test(value.cardholder_name) || !(answer === "" || SOLVED_CAPTCHA2.test(answer)) || !CAPTCHA_VERSIONS.includes(value.captcha_version) || value.captcha_action !== "checkout") {
|
|
510
|
+
return { code: "payfast_body_unsupported", pairs: null };
|
|
511
|
+
}
|
|
512
|
+
if (value.consent_check === "1")
|
|
513
|
+
return { code: "payfast_keep_on_file", pairs: null };
|
|
514
|
+
return value.consent_check === "" ? { code: null, pairs } : { code: "payfast_body_unsupported", pairs: null };
|
|
515
|
+
}
|
|
516
|
+
function payfastBodyVerdict(body) {
|
|
517
|
+
const { code } = judgeBody(body);
|
|
518
|
+
return code === null ? CARD5 : refuse5(code);
|
|
519
|
+
}
|
|
520
|
+
// src/sha256.js
|
|
521
|
+
var K = /* @__PURE__ */ new Uint32Array([
|
|
522
|
+
1116352408,
|
|
523
|
+
1899447441,
|
|
524
|
+
3049323471,
|
|
525
|
+
3921009573,
|
|
526
|
+
961987163,
|
|
527
|
+
1508970993,
|
|
528
|
+
2453635748,
|
|
529
|
+
2870763221,
|
|
530
|
+
3624381080,
|
|
531
|
+
310598401,
|
|
532
|
+
607225278,
|
|
533
|
+
1426881987,
|
|
534
|
+
1925078388,
|
|
535
|
+
2162078206,
|
|
536
|
+
2614888103,
|
|
537
|
+
3248222580,
|
|
538
|
+
3835390401,
|
|
539
|
+
4022224774,
|
|
540
|
+
264347078,
|
|
541
|
+
604807628,
|
|
542
|
+
770255983,
|
|
543
|
+
1249150122,
|
|
544
|
+
1555081692,
|
|
545
|
+
1996064986,
|
|
546
|
+
2554220882,
|
|
547
|
+
2821834349,
|
|
548
|
+
2952996808,
|
|
549
|
+
3210313671,
|
|
550
|
+
3336571891,
|
|
551
|
+
3584528711,
|
|
552
|
+
113926993,
|
|
553
|
+
338241895,
|
|
554
|
+
666307205,
|
|
555
|
+
773529912,
|
|
556
|
+
1294757372,
|
|
557
|
+
1396182291,
|
|
558
|
+
1695183700,
|
|
559
|
+
1986661051,
|
|
560
|
+
2177026350,
|
|
561
|
+
2456956037,
|
|
562
|
+
2730485921,
|
|
563
|
+
2820302411,
|
|
564
|
+
3259730800,
|
|
565
|
+
3345764771,
|
|
566
|
+
3516065817,
|
|
567
|
+
3600352804,
|
|
568
|
+
4094571909,
|
|
569
|
+
275423344,
|
|
570
|
+
430227734,
|
|
571
|
+
506948616,
|
|
572
|
+
659060556,
|
|
573
|
+
883997877,
|
|
574
|
+
958139571,
|
|
575
|
+
1322822218,
|
|
576
|
+
1537002063,
|
|
577
|
+
1747873779,
|
|
578
|
+
1955562222,
|
|
579
|
+
2024104815,
|
|
580
|
+
2227730452,
|
|
581
|
+
2361852424,
|
|
582
|
+
2428436474,
|
|
583
|
+
2756734187,
|
|
584
|
+
3204031479,
|
|
585
|
+
3329325298
|
|
586
|
+
]);
|
|
587
|
+
var rotr = (x, n) => x >>> n | x << 32 - n;
|
|
588
|
+
function utf8(text3) {
|
|
589
|
+
const out = [];
|
|
590
|
+
for (const char of text3) {
|
|
591
|
+
let cp = char.codePointAt(0);
|
|
592
|
+
if (cp >= 55296 && cp <= 57343)
|
|
593
|
+
cp = 65533;
|
|
594
|
+
if (cp < 128)
|
|
595
|
+
out.push(cp);
|
|
596
|
+
else if (cp < 2048)
|
|
597
|
+
out.push(192 | cp >> 6, 128 | cp & 63);
|
|
598
|
+
else if (cp < 65536)
|
|
599
|
+
out.push(224 | cp >> 12, 128 | cp >> 6 & 63, 128 | cp & 63);
|
|
600
|
+
else
|
|
601
|
+
out.push(240 | cp >> 18, 128 | cp >> 12 & 63, 128 | cp >> 6 & 63, 128 | cp & 63);
|
|
602
|
+
}
|
|
603
|
+
return Uint8Array.from(out);
|
|
604
|
+
}
|
|
605
|
+
function sha256Hex(input) {
|
|
606
|
+
const isBytes = Object.prototype.toString.call(input) === "[object Uint8Array]";
|
|
607
|
+
if (typeof input !== "string" && !isBytes)
|
|
608
|
+
throw new TypeError("sha256Hex takes a string or a Uint8Array.");
|
|
609
|
+
const bytes = typeof input === "string" ? utf8(input) : input;
|
|
610
|
+
const length = bytes.length;
|
|
611
|
+
const padded = new Uint8Array((length + 8 >> 6) + 1 << 6);
|
|
612
|
+
padded.set(bytes);
|
|
613
|
+
padded[length] = 128;
|
|
614
|
+
const view = new DataView(padded.buffer);
|
|
615
|
+
view.setUint32(padded.length - 8, Math.floor(length / 536870912));
|
|
616
|
+
view.setUint32(padded.length - 4, length << 3 >>> 0);
|
|
617
|
+
const H = new Uint32Array([1779033703, 3144134277, 1013904242, 2773480762, 1359893119, 2600822924, 528734635, 1541459225]);
|
|
618
|
+
const W = new Uint32Array(64);
|
|
619
|
+
for (let offset = 0; offset < padded.length; offset += 64) {
|
|
620
|
+
for (let t = 0; t < 16; t++)
|
|
621
|
+
W[t] = view.getUint32(offset + t * 4);
|
|
622
|
+
for (let t = 16; t < 64; t++) {
|
|
623
|
+
const s0 = rotr(W[t - 15], 7) ^ rotr(W[t - 15], 18) ^ W[t - 15] >>> 3;
|
|
624
|
+
const s1 = rotr(W[t - 2], 17) ^ rotr(W[t - 2], 19) ^ W[t - 2] >>> 10;
|
|
625
|
+
W[t] = W[t - 16] + s0 + W[t - 7] + s1 >>> 0;
|
|
626
|
+
}
|
|
627
|
+
let a = H[0], b = H[1], c = H[2], d = H[3], e = H[4], f = H[5], g = H[6], h = H[7];
|
|
628
|
+
for (let t = 0; t < 64; t++) {
|
|
629
|
+
const t1 = h + (rotr(e, 6) ^ rotr(e, 11) ^ rotr(e, 25)) + (e & f ^ ~e & g) + K[t] + W[t] >>> 0;
|
|
630
|
+
const t2 = (rotr(a, 2) ^ rotr(a, 13) ^ rotr(a, 22)) + (a & b ^ a & c ^ b & c) >>> 0;
|
|
631
|
+
h = g;
|
|
632
|
+
g = f;
|
|
633
|
+
f = e;
|
|
634
|
+
e = d + t1 >>> 0;
|
|
635
|
+
d = c;
|
|
636
|
+
c = b;
|
|
637
|
+
b = a;
|
|
638
|
+
a = t1 + t2 >>> 0;
|
|
639
|
+
}
|
|
640
|
+
H[0] += a;
|
|
641
|
+
H[1] += b;
|
|
642
|
+
H[2] += c;
|
|
643
|
+
H[3] += d;
|
|
644
|
+
H[4] += e;
|
|
645
|
+
H[5] += f;
|
|
646
|
+
H[6] += g;
|
|
647
|
+
H[7] += h;
|
|
648
|
+
}
|
|
649
|
+
return Array.from(H, (word) => word.toString(16).padStart(8, "0")).join("");
|
|
650
|
+
}
|
|
651
|
+
// src/rsa-pkcs1v15.js
|
|
652
|
+
var RsaPkcs1v15Error = class extends Error {
|
|
653
|
+
constructor(reason) {
|
|
654
|
+
super("RSA PKCS#1 v1.5 encryption refused.");
|
|
655
|
+
this.name = "RsaPkcs1v15Error";
|
|
656
|
+
this.code = "rsa_pkcs1v15_refused";
|
|
657
|
+
this.reason = reason;
|
|
658
|
+
}
|
|
659
|
+
};
|
|
660
|
+
var refuse6 = (reason) => new RsaPkcs1v15Error(reason);
|
|
661
|
+
var BASE64 = /^[A-Za-z0-9+/]+={0,2}$/;
|
|
662
|
+
var SHA256_HEX = /^[0-9a-f]{64}$/;
|
|
663
|
+
var RSA_ALGORITHM = [48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 1, 5, 0];
|
|
664
|
+
var MODULUS_BYTES = [128, 256, 384, 512];
|
|
665
|
+
var TYPED_ARRAY = Object.getPrototypeOf(Uint8Array.prototype);
|
|
666
|
+
var typedArrayName = Object.getOwnPropertyDescriptor(TYPED_ARRAY, Symbol.toStringTag).get;
|
|
667
|
+
function parseRsaPublicKey(key) {
|
|
668
|
+
const spki = key && typeof key === "object" ? key.spki : void 0;
|
|
669
|
+
const pin3 = key && typeof key === "object" ? key.sha256 : void 0;
|
|
670
|
+
if (typeof spki !== "string" || spki.length > 1024 || spki.length % 4 !== 0 || !BASE64.test(spki))
|
|
671
|
+
throw refuse6("key");
|
|
672
|
+
if (typeof pin3 !== "string" || !SHA256_HEX.test(pin3))
|
|
673
|
+
throw refuse6("key");
|
|
674
|
+
let binary;
|
|
675
|
+
try {
|
|
676
|
+
binary = atob(spki);
|
|
677
|
+
}
|
|
678
|
+
catch {
|
|
679
|
+
throw refuse6("key");
|
|
680
|
+
}
|
|
681
|
+
if (btoa(binary) !== spki)
|
|
682
|
+
throw refuse6("key");
|
|
683
|
+
const der = Uint8Array.from(binary, (c) => c.charCodeAt(0));
|
|
684
|
+
if (sha256Hex(der) !== pin3)
|
|
685
|
+
throw refuse6("key");
|
|
686
|
+
const outer = readElement(der, 0, 48);
|
|
687
|
+
if (outer.end !== der.length || outer.start + RSA_ALGORITHM.length > der.length)
|
|
688
|
+
throw refuse6("key");
|
|
689
|
+
if (!RSA_ALGORITHM.every((byte, i) => der[outer.start + i] === byte))
|
|
690
|
+
throw refuse6("key");
|
|
691
|
+
const bits = readElement(der, outer.start + RSA_ALGORITHM.length, 3);
|
|
692
|
+
if (bits.end !== outer.end || bits.start === bits.end || der[bits.start] !== 0)
|
|
693
|
+
throw refuse6("key");
|
|
694
|
+
const rsa = readElement(der, bits.start + 1, 48);
|
|
695
|
+
if (rsa.end !== bits.end)
|
|
696
|
+
throw refuse6("key");
|
|
697
|
+
const modulus = readPositiveInteger(der, rsa.start);
|
|
698
|
+
const exponent = readPositiveInteger(der, modulus.end);
|
|
699
|
+
if (exponent.end !== rsa.end)
|
|
700
|
+
throw refuse6("key");
|
|
701
|
+
const n = modulus.bytes;
|
|
702
|
+
if (!MODULUS_BYTES.includes(n.length) || !(n[0] & 128) || !(n[n.length - 1] & 1))
|
|
703
|
+
throw refuse6("key");
|
|
704
|
+
const e = exponent.bytes;
|
|
705
|
+
if (e.length !== 3 || e[0] !== 1 || e[1] !== 0 || e[2] !== 1)
|
|
706
|
+
throw refuse6("key");
|
|
707
|
+
return Object.freeze({ n: toBigInt(n), e: 65537n, size: n.length });
|
|
708
|
+
}
|
|
709
|
+
function readElement(der, at, tag) {
|
|
710
|
+
if (at + 2 > der.length || der[at] !== tag)
|
|
711
|
+
throw refuse6("key");
|
|
712
|
+
let length = der[at + 1];
|
|
713
|
+
let start = at + 2;
|
|
714
|
+
if (length & 128) {
|
|
715
|
+
const count = length & 127;
|
|
716
|
+
if (count === 0 || count > 2 || start + count > der.length || der[start] === 0)
|
|
717
|
+
throw refuse6("key");
|
|
718
|
+
length = count === 1 ? der[start] : der[start] * 256 + der[start + 1];
|
|
719
|
+
if (length < 128)
|
|
720
|
+
throw refuse6("key");
|
|
721
|
+
start += count;
|
|
722
|
+
}
|
|
723
|
+
if (start + length > der.length)
|
|
724
|
+
throw refuse6("key");
|
|
725
|
+
return { start, end: start + length };
|
|
726
|
+
}
|
|
727
|
+
function readPositiveInteger(der, at) {
|
|
728
|
+
const { start, end } = readElement(der, at, 2);
|
|
729
|
+
if (end === start || der[start] & 128)
|
|
730
|
+
throw refuse6("key");
|
|
731
|
+
if (der[start] === 0 && (end - start === 1 || !(der[start + 1] & 128)))
|
|
732
|
+
throw refuse6("key");
|
|
733
|
+
return { bytes: der.subarray(der[start] === 0 ? start + 1 : start, end), end };
|
|
734
|
+
}
|
|
735
|
+
function toBigInt(bytes) {
|
|
736
|
+
let hex = "";
|
|
737
|
+
for (let i = 0; i < bytes.length; i++)
|
|
738
|
+
hex += (bytes[i] < 16 ? "0" : "") + bytes[i].toString(16);
|
|
739
|
+
return BigInt(`0x${hex}`);
|
|
740
|
+
}
|
|
741
|
+
// src/paddle-keys.js
|
|
742
|
+
var PADDLE_TOKENEX_KEYS = /* @__PURE__ */ Object.freeze({
|
|
743
|
+
sandbox: Object.freeze({
|
|
744
|
+
spki: "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvWpIQFjQQCPpaIlJKpegirp5kLkzLB1AxHmnLk73D3TJbAGqr1QmlsWDBtMPMRpdzzUM7ZwX3kzhIuATV4Pe7RKp3nZlVmcrT0YCQXBrTwqZNh775z58GP2kZs+gVfNqBampJPzSB/hB62KkByhECn6grrRjiAVwJyZVEvs/2vrxaEpO+aE16emtX12RgI5JdzdOiNyZEQteU6zRBRJEocPWVxExaOpVVVJ5+UnW0LcalzA+lRGRTrQJ5JguAPiAOzRPTK/lYFFpCAl/F8wtoAVG1c8zO2NcQ0Pko+fmeidRFxJ/did2btV+9Mkze3mBphwFmvnxa35LF+Cs/XJHDwIDAQAB",
|
|
745
|
+
sha256: "877d29a008ed9998d6035032870c63dcc4cbf37ca22cb50b0cc9fe2250a9e3dc"
|
|
746
|
+
}),
|
|
747
|
+
production: Object.freeze({
|
|
748
|
+
spki: "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA8gGPMwBRPuVyJReZGIkWH/+Bf5pnpDN1bSR2cLYLXVT8CaSnTw74qeboSnktgYCi1D9R3Bj2fYzTIwGGZb8KinLdxwbqZmHwrE9cFhCaHbG/E0PbqQGhXP2vbniZTT4M0i0Cbi7ES3Bw5zqNbIZZnX041QEpxLvIyWPKZCX+fBogNMhWfCF779aclChjHkwZMsufThVWE9xklWGxXiytx5aL4I5JPxq0I7cAkZGGs4aF/GxWwPaq7R3wPikJQ0YHnCMfcURzl2Hnw/inqyMy+JB6djTq2/BdzMAhWTh3cDWq9Xu+gEkb/QCd0n1yYIdKuDISlk/AfHdWe34IvzhVyQIDAQAB",
|
|
749
|
+
sha256: "92529bd289bb24d52a1bdcc42edc9ac0bb1dacbb58f7568573d44771e1287762"
|
|
750
|
+
})
|
|
751
|
+
});
|
|
752
|
+
function paddleTokenexKey(environment) {
|
|
753
|
+
if (environment !== "sandbox" && environment !== "production")
|
|
754
|
+
return null;
|
|
755
|
+
return PADDLE_TOKENEX_KEYS[environment] ?? null;
|
|
756
|
+
}
|
|
757
|
+
function paddleTokenexKeyBytes(environment) {
|
|
758
|
+
const key = paddleTokenexKey(environment);
|
|
759
|
+
if (!key)
|
|
760
|
+
return null;
|
|
761
|
+
try {
|
|
762
|
+
return parseRsaPublicKey(key).size;
|
|
763
|
+
}
|
|
764
|
+
catch {
|
|
765
|
+
return null;
|
|
766
|
+
}
|
|
767
|
+
}
|
|
768
|
+
// src/paddle-tokenex.js
|
|
769
|
+
var PADDLE_TOKENEX_PSP = "paddle_tokenex";
|
|
770
|
+
var PADDLE_TOKENEX_FACT_KEYS = /* @__PURE__ */ Object.freeze(["card_first_six", "card_last_four", "expiry_month", "expiry_year", "card_brand"]);
|
|
771
|
+
var record4 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
772
|
+
var sameKeys2 = (value, keys) => {
|
|
773
|
+
const own = Object.keys(value);
|
|
774
|
+
return own.length === keys.length && own.every((key, at) => key === keys[at]);
|
|
775
|
+
};
|
|
776
|
+
var refuse7 = (code) => Object.freeze({ verdict: "refuse", code });
|
|
777
|
+
var CARD6 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
|
|
778
|
+
var CONTINUE2 = /* @__PURE__ */ Object.freeze({ verdict: "continue" });
|
|
779
|
+
var PAY_URL = /^https:\/\/(sandbox-)?checkout-service\.paddle\.com\/(checkout|transaction-checkout)\/[A-Za-z0-9_-]{1,64}\/pay$/;
|
|
780
|
+
function paddleTokenexPayTarget(url) {
|
|
781
|
+
const match = typeof url === "string" ? PAY_URL.exec(url) : null;
|
|
782
|
+
return match ? Object.freeze({ environment: match[1] ? "sandbox" : "production", line: match[2] === "checkout" ? "classic" : "billing" }) : null;
|
|
783
|
+
}
|
|
784
|
+
function paddleTokenexPayCarriesCard(body) {
|
|
785
|
+
if (typeof body !== "string")
|
|
786
|
+
return true;
|
|
787
|
+
try {
|
|
788
|
+
return JSON.stringify(JSON.parse(body)).includes('"tokenex_card"');
|
|
789
|
+
}
|
|
790
|
+
catch {
|
|
791
|
+
return true;
|
|
792
|
+
}
|
|
793
|
+
}
|
|
794
|
+
var FRAME_BRANDS = /* @__PURE__ */ Object.freeze(["visa", "master", "american_express", "discover", "diners_club", "jcb", "maestro", "dankort", "unionpay", "unknown"]);
|
|
795
|
+
var NAME_LIMIT2 = 256;
|
|
796
|
+
var CONTROL2 = /[\u0000-\u001f\u007f]/;
|
|
797
|
+
var FIRST_SIX = /^[0-9]{6}$/;
|
|
798
|
+
var LAST_FOUR = /^[0-9]{4}$/;
|
|
799
|
+
var BASE642 = /^[A-Za-z0-9+/]+={0,2}$/;
|
|
800
|
+
var cardLikeName2 = (name) => (name.match(/[0-9]/g) ?? []).length >= 12;
|
|
801
|
+
var expiryMonth = (month) => Number.isInteger(month) && month >= 1 && month <= 12;
|
|
802
|
+
var expiryYear = (year) => Number.isInteger(year) && year >= 2e3 && year <= 2099;
|
|
803
|
+
var PAY_BODY_LIMIT = 16384;
|
|
804
|
+
var PAY_DATA_KEYS = /* @__PURE__ */ Object.freeze(["payment_method_type", "payment_method_data"]);
|
|
805
|
+
var PAY_CARD_KEYS = /* @__PURE__ */ Object.freeze(["metadata", "three_d_s", "tokenex_card"]);
|
|
806
|
+
var METADATA_KEYS2 = /* @__PURE__ */ Object.freeze(["cardholder_name", ...PADDLE_TOKENEX_FACT_KEYS]);
|
|
807
|
+
var CARD_KEYS3 = /* @__PURE__ */ Object.freeze(["encrypted_card_number", "encrypted_cvv"]);
|
|
808
|
+
var BROWSER_INFO = /^[A-Za-z0-9+/]{1,4096}={0,2}$/;
|
|
809
|
+
var RADAR_TOKEN = /^[\x21-\x7e]{1,512}$/;
|
|
810
|
+
var COUNTRY_CODE = /^[A-Za-z]{2}$/;
|
|
811
|
+
var FRONTEND_HOST = /^https:\/\/[\x21-\x7e]{1,1024}$/;
|
|
812
|
+
var radarKeys = (value) => sameKeys2(value, ["token", "country_code"]) || sameKeys2(value, ["country_code", "token"]);
|
|
813
|
+
function isBase64OfBytes(value, bytes) {
|
|
814
|
+
if (typeof value !== "string" || value.length !== Math.ceil(bytes / 3) * 4 || !BASE642.test(value))
|
|
815
|
+
return false;
|
|
816
|
+
const pad = value.endsWith("==") ? 2 : value.endsWith("=") ? 1 : 0;
|
|
817
|
+
return value.length / 4 * 3 - pad === bytes && btoa(atob(value)) === value;
|
|
818
|
+
}
|
|
819
|
+
function isPaddleTokenexCiphertext(value, environment) {
|
|
820
|
+
const bytes = paddleTokenexKeyBytes(environment);
|
|
821
|
+
return bytes !== null && isBase64OfBytes(value, bytes);
|
|
822
|
+
}
|
|
823
|
+
function readPay(body, line, environment) {
|
|
824
|
+
if (typeof body !== "string" || body === "" || body.length > PAY_BODY_LIMIT)
|
|
825
|
+
return null;
|
|
826
|
+
let value;
|
|
827
|
+
try {
|
|
828
|
+
value = JSON.parse(body);
|
|
829
|
+
if (!record4(value) || JSON.stringify(value) !== body)
|
|
830
|
+
return null;
|
|
831
|
+
}
|
|
832
|
+
catch {
|
|
833
|
+
return null;
|
|
834
|
+
}
|
|
835
|
+
const data = value.data;
|
|
836
|
+
if (!sameKeys2(value, ["data"]) || !record4(data) || !(sameKeys2(data, PAY_DATA_KEYS) || sameKeys2(data, [...PAY_DATA_KEYS, "checkout"])) || data.payment_method_type !== (line === "classic" ? "CARD" : "card"))
|
|
837
|
+
return null;
|
|
838
|
+
if (data.checkout !== void 0 && !(record4(data.checkout) && sameKeys2(data.checkout, ["frontend_host"]) && typeof data.checkout.frontend_host === "string" && FRONTEND_HOST.test(data.checkout.frontend_host)))
|
|
839
|
+
return null;
|
|
840
|
+
const method = data.payment_method_data;
|
|
841
|
+
const card = record4(method) && sameKeys2(method, ["card"]) ? method.card : null;
|
|
842
|
+
if (!record4(card) || !(sameKeys2(card, PAY_CARD_KEYS) || sameKeys2(card, [...PAY_CARD_KEYS, "session_tracking"])))
|
|
843
|
+
return null;
|
|
844
|
+
const metadata = card.metadata;
|
|
845
|
+
if (!record4(metadata) || !sameKeys2(metadata, METADATA_KEYS2) || typeof metadata.cardholder_name !== "string" || metadata.cardholder_name.length > NAME_LIMIT2 || CONTROL2.test(metadata.cardholder_name) || cardLikeName2(metadata.cardholder_name) || typeof metadata.card_first_six !== "string" || !FIRST_SIX.test(metadata.card_first_six) || typeof metadata.card_last_four !== "string" || !LAST_FOUR.test(metadata.card_last_four) || !expiryMonth(metadata.expiry_month) || !expiryYear(metadata.expiry_year) || !FRAME_BRANDS.includes(metadata.card_brand))
|
|
846
|
+
return null;
|
|
847
|
+
const details = card.three_d_s;
|
|
848
|
+
if (!record4(details) || !sameKeys2(details, ["browser_info"]) || typeof details.browser_info !== "string" || !BROWSER_INFO.test(details.browser_info))
|
|
849
|
+
return null;
|
|
850
|
+
const tokenex = card.tokenex_card;
|
|
851
|
+
if (!record4(tokenex) || !sameKeys2(tokenex, CARD_KEYS3))
|
|
852
|
+
return null;
|
|
853
|
+
for (const name of CARD_KEYS3) {
|
|
854
|
+
const blob = tokenex[name];
|
|
855
|
+
if (environment === void 0) {
|
|
856
|
+
if (typeof blob !== "string" || !BASE642.test(blob) || blob.length < 4 || blob.length > 4096)
|
|
857
|
+
return null;
|
|
858
|
+
}
|
|
859
|
+
else if (!isPaddleTokenexCiphertext(blob, environment))
|
|
860
|
+
return null;
|
|
861
|
+
}
|
|
862
|
+
if (tokenex.encrypted_card_number === tokenex.encrypted_cvv)
|
|
863
|
+
return null;
|
|
864
|
+
if (card.session_tracking !== void 0) {
|
|
865
|
+
const tracking = card.session_tracking;
|
|
866
|
+
const radar = record4(tracking) && sameKeys2(tracking, ["stripe_radar"]) ? tracking.stripe_radar : null;
|
|
867
|
+
if (!record4(radar) || !radarKeys(radar) || typeof radar.token !== "string" || !RADAR_TOKEN.test(radar.token) || typeof radar.country_code !== "string" || !COUNTRY_CODE.test(radar.country_code))
|
|
868
|
+
return null;
|
|
869
|
+
}
|
|
870
|
+
return value;
|
|
871
|
+
}
|
|
872
|
+
function paddleTokenexBodyVerdict(body, line) {
|
|
873
|
+
if (!paddleTokenexPayCarriesCard(body))
|
|
874
|
+
return CONTINUE2;
|
|
875
|
+
for (const candidate of line === "classic" || line === "billing" ? [line] : ["classic", "billing"]) {
|
|
876
|
+
if (readPay(body, candidate) !== null)
|
|
877
|
+
return CARD6;
|
|
878
|
+
}
|
|
879
|
+
return refuse7("paddle_tokenex_pay_unsupported");
|
|
880
|
+
}
|
|
881
|
+
var CARD_PATH = /* @__PURE__ */ Object.freeze(["data", "payment_method_data", "card"]);
|
|
882
|
+
var TOKENEX_PATH = /* @__PURE__ */ Object.freeze([...CARD_PATH, "tokenex_card"]);
|
|
883
|
+
// src/lyra.js
|
|
884
|
+
var LYRA_PSP = "lyra";
|
|
885
|
+
var LYRA_PROCESS_PATH = "/api-payment/V4/Charge/Public/ProcessPayment/2";
|
|
886
|
+
var LYRA_HOSTS = /* @__PURE__ */ Object.freeze({
|
|
887
|
+
"api.payzen.eu": Object.freeze({ staticOrigin: "https://static.payzen.eu", prefixes: Object.freeze(["01", "02"]) }),
|
|
888
|
+
"api.systempay.fr": Object.freeze({ staticOrigin: "https://static.systempay.fr", prefixes: Object.freeze(["24", "25"]) }),
|
|
889
|
+
"api-sogecommerce.societegenerale.eu": Object.freeze({ staticOrigin: "https://static-sogecommerce.societegenerale.eu", prefixes: Object.freeze(["06", "07"]) }),
|
|
890
|
+
"api.lyra.com": Object.freeze({ staticOrigin: "https://static.lyra.com", prefixes: Object.freeze(["10", "11"]) })
|
|
891
|
+
});
|
|
892
|
+
var BODY_LIMIT4 = 32768;
|
|
893
|
+
var TOKEN = /^([0-9a-z]{2})[0-9A-Za-z]([A-Za-z0-9_-]{64,16384})$/;
|
|
894
|
+
var SESSION = /^[A-Za-z0-9._-]{1,128}$/;
|
|
895
|
+
var PUBLIC_KEY = /^([0-9]{4,12}):(testpublickey|publickey)_[A-Za-z0-9]{1,128}$/;
|
|
896
|
+
var REMOTE_ID = /^[0-9a-f]{32}$/;
|
|
897
|
+
var CARD_NUMBER5 = /^[0-9]{12,19}$/;
|
|
898
|
+
var SECURITY_CODE4 = /^[0-9]{3,4}$/;
|
|
899
|
+
var MONTH2 = /^(?:0[1-9]|1[0-2])$/;
|
|
900
|
+
var YEAR2 = /^20[0-9]{2}$/;
|
|
901
|
+
var BRAND = /^[A-Z][A-Z0-9_-]{1,31}$/;
|
|
902
|
+
var CONTROL3 = /[\u0000-\u001f\u007f]/;
|
|
903
|
+
var PAN_LIKE2 = /(?:[0-9][ _.:-]*){12,}/;
|
|
904
|
+
var CARD_KEYS4 = /* @__PURE__ */ Object.freeze([
|
|
905
|
+
"formToken",
|
|
906
|
+
"clientVersion",
|
|
907
|
+
"kryptonCallbackUrl",
|
|
908
|
+
"language",
|
|
909
|
+
"paymentForm",
|
|
910
|
+
"postUrl",
|
|
911
|
+
"publicKey",
|
|
912
|
+
"remoteId",
|
|
913
|
+
"wsUser",
|
|
914
|
+
"refererUrl",
|
|
915
|
+
"challengePreference",
|
|
916
|
+
"device",
|
|
917
|
+
"partialPaymentsAllowed",
|
|
918
|
+
"paymentMethodCloseButton",
|
|
919
|
+
"skipPaymentTicket"
|
|
920
|
+
]);
|
|
921
|
+
var CARD_REQUIRED = /* @__PURE__ */ Object.freeze(["formToken", "paymentForm", "publicKey", "remoteId"]);
|
|
922
|
+
var PAYMENT_FORM_KEYS = /* @__PURE__ */ Object.freeze(["pan", "securityCode", "cardHolderName", "expiryMonth", "expiryYear", "brand"]);
|
|
923
|
+
var FOLLOW_UP_KEYS = /* @__PURE__ */ Object.freeze([
|
|
924
|
+
"formToken",
|
|
925
|
+
"publicKey",
|
|
926
|
+
"instructionResult",
|
|
927
|
+
"remoteId",
|
|
928
|
+
"clientVersion",
|
|
929
|
+
"device",
|
|
930
|
+
"wsUser",
|
|
931
|
+
"partialPaymentsAllowed",
|
|
932
|
+
"paymentMethodCloseButton",
|
|
933
|
+
"skipPaymentTicket"
|
|
934
|
+
]);
|
|
935
|
+
var FOLLOW_UP_REQUIRED = /* @__PURE__ */ Object.freeze(["formToken", "publicKey", "instructionResult", "remoteId"]);
|
|
936
|
+
var INSTRUCTION_RESULT_KEYS = /* @__PURE__ */ Object.freeze(["name", "value", "protocol"]);
|
|
937
|
+
var DEVICE_KEYS = /* @__PURE__ */ Object.freeze([
|
|
938
|
+
"deviceType",
|
|
939
|
+
"acceptHeader",
|
|
940
|
+
"userAgent",
|
|
941
|
+
"javaEnabled",
|
|
942
|
+
"language",
|
|
943
|
+
"colorDepth",
|
|
944
|
+
"screenHeight",
|
|
945
|
+
"screenWidth",
|
|
946
|
+
"timeZoneOffset"
|
|
947
|
+
]);
|
|
948
|
+
var TEXT_MEMBERS = /* @__PURE__ */ Object.freeze({
|
|
949
|
+
clientVersion: 64,
|
|
950
|
+
language: 16,
|
|
951
|
+
postUrl: 2048,
|
|
952
|
+
wsUser: 32,
|
|
953
|
+
refererUrl: 2048,
|
|
954
|
+
challengePreference: 64,
|
|
955
|
+
paymentMethodCloseButton: 32
|
|
956
|
+
});
|
|
957
|
+
var BOOLEAN_MEMBERS = /* @__PURE__ */ Object.freeze(["partialPaymentsAllowed", "skipPaymentTicket"]);
|
|
958
|
+
var CALLBACK_PATH = "/static/js/krypton-client/V4.0/done/done.html";
|
|
959
|
+
var record5 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
960
|
+
var owns4 = (value, key) => Object.prototype.hasOwnProperty.call(value, key);
|
|
961
|
+
var keysWithin = (value, allowed) => record5(value) && Object.keys(value).every((key) => allowed.includes(key));
|
|
962
|
+
var text = (value, max) => typeof value === "string" && value.length <= max && !CONTROL3.test(value);
|
|
963
|
+
var refuse8 = (code) => Object.freeze({ verdict: "refuse", code });
|
|
964
|
+
var CARD7 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
|
|
965
|
+
var CONTINUE3 = /* @__PURE__ */ Object.freeze({ verdict: "continue" });
|
|
966
|
+
function lyraProcessPaymentUrl(url) {
|
|
967
|
+
if (typeof url !== "string" || url.length > 512 || url.includes("?") || url.includes("#"))
|
|
968
|
+
return null;
|
|
969
|
+
let parsed;
|
|
970
|
+
try {
|
|
971
|
+
parsed = new URL(url);
|
|
972
|
+
}
|
|
973
|
+
catch {
|
|
974
|
+
return null;
|
|
975
|
+
}
|
|
976
|
+
if (parsed.href !== url || parsed.protocol !== "https:" || parsed.port || parsed.username || parsed.password || !owns4(LYRA_HOSTS, parsed.hostname))
|
|
977
|
+
return null;
|
|
978
|
+
const path = parsed.pathname;
|
|
979
|
+
if (path === LYRA_PROCESS_PATH)
|
|
980
|
+
return Object.freeze({ host: parsed.hostname, session: null });
|
|
981
|
+
const marker = `${LYRA_PROCESS_PATH};jsessionid=`;
|
|
982
|
+
if (!path.startsWith(marker))
|
|
983
|
+
return null;
|
|
984
|
+
const session = path.slice(marker.length);
|
|
985
|
+
return SESSION.test(session) ? Object.freeze({ host: parsed.hostname, session }) : null;
|
|
986
|
+
}
|
|
987
|
+
function base64UrlBytes(input) {
|
|
988
|
+
const alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
|
|
989
|
+
const bytes = [];
|
|
990
|
+
let bits = 0;
|
|
991
|
+
let value = 0;
|
|
992
|
+
for (const character of input) {
|
|
993
|
+
const sextet = alphabet.indexOf(character);
|
|
994
|
+
if (sextet < 0)
|
|
995
|
+
return null;
|
|
996
|
+
value = value << 6 | sextet;
|
|
997
|
+
bits += 6;
|
|
998
|
+
if (bits >= 8) {
|
|
999
|
+
bits -= 8;
|
|
1000
|
+
bytes.push(value >> bits & 255);
|
|
1001
|
+
value &= (1 << bits) - 1;
|
|
1002
|
+
}
|
|
1003
|
+
}
|
|
1004
|
+
return bytes;
|
|
1005
|
+
}
|
|
1006
|
+
function jsonObjectText(bytes, start) {
|
|
1007
|
+
let depth = 0;
|
|
1008
|
+
let inString = false;
|
|
1009
|
+
let escaped = false;
|
|
1010
|
+
for (let at = start; at < bytes.length; at += 1) {
|
|
1011
|
+
const byte = bytes[at];
|
|
1012
|
+
if (inString) {
|
|
1013
|
+
if (escaped)
|
|
1014
|
+
escaped = false;
|
|
1015
|
+
else if (byte === 92)
|
|
1016
|
+
escaped = true;
|
|
1017
|
+
else if (byte === 34)
|
|
1018
|
+
inString = false;
|
|
1019
|
+
continue;
|
|
1020
|
+
}
|
|
1021
|
+
if (byte === 34)
|
|
1022
|
+
inString = true;
|
|
1023
|
+
else if (byte === 123)
|
|
1024
|
+
depth += 1;
|
|
1025
|
+
else if (byte === 125) {
|
|
1026
|
+
depth -= 1;
|
|
1027
|
+
if (depth === 0) {
|
|
1028
|
+
try {
|
|
1029
|
+
return decodeURIComponent(bytes.slice(start, at + 1).map((b) => "%" + b.toString(16).padStart(2, "0")).join(""));
|
|
1030
|
+
}
|
|
1031
|
+
catch {
|
|
1032
|
+
return null;
|
|
1033
|
+
}
|
|
1034
|
+
}
|
|
1035
|
+
}
|
|
1036
|
+
}
|
|
1037
|
+
return null;
|
|
1038
|
+
}
|
|
1039
|
+
function lyraFormTokenFacts(token) {
|
|
1040
|
+
const match = typeof token === "string" ? TOKEN.exec(token) : null;
|
|
1041
|
+
const bytes = match ? base64UrlBytes(match[2]) : null;
|
|
1042
|
+
if (!bytes || bytes.length < 20 || bytes[18] !== 123)
|
|
1043
|
+
return null;
|
|
1044
|
+
const json = jsonObjectText(bytes, 18);
|
|
1045
|
+
let dna;
|
|
1046
|
+
try {
|
|
1047
|
+
dna = json === null ? null : JSON.parse(json);
|
|
1048
|
+
}
|
|
1049
|
+
catch {
|
|
1050
|
+
return null;
|
|
1051
|
+
}
|
|
1052
|
+
if (!record5(dna) || !Number.isSafeInteger(dna.amount) || dna.amount < 0 || typeof dna.currency !== "string" || !/^[A-Z]{3}$/.test(dna.currency) || dna.mode !== "TEST" && dna.mode !== "PRODUCTION" || typeof dna.formAction !== "string" || !/^[A-Z_]{1,32}$/.test(dna.formAction) || owns4(dna, "jSessionId") && (typeof dna.jSessionId !== "string" || !SESSION.test(dna.jSessionId)))
|
|
1053
|
+
return null;
|
|
1054
|
+
return Object.freeze({
|
|
1055
|
+
prefix: match[1],
|
|
1056
|
+
amount: dna.amount,
|
|
1057
|
+
currency: dna.currency,
|
|
1058
|
+
mode: dna.mode,
|
|
1059
|
+
formAction: dna.formAction,
|
|
1060
|
+
session: owns4(dna, "jSessionId") ? dna.jSessionId : null
|
|
1061
|
+
});
|
|
1062
|
+
}
|
|
1063
|
+
function readJson(body) {
|
|
1064
|
+
if (typeof body !== "string" || body === "" || body.length > BODY_LIMIT4)
|
|
1065
|
+
return null;
|
|
1066
|
+
let at = 0;
|
|
1067
|
+
let nodes = 0;
|
|
1068
|
+
const fail = () => {
|
|
1069
|
+
throw new Error("invalid_lyra_json");
|
|
1070
|
+
};
|
|
1071
|
+
const space = () => {
|
|
1072
|
+
while (" \r\n".includes(body[at] ?? "\0"))
|
|
1073
|
+
at += 1;
|
|
1074
|
+
};
|
|
1075
|
+
const string = () => {
|
|
1076
|
+
space();
|
|
1077
|
+
const start = at;
|
|
1078
|
+
if (body[at++] !== '"')
|
|
1079
|
+
fail();
|
|
1080
|
+
while (at < body.length) {
|
|
1081
|
+
const character = body[at++];
|
|
1082
|
+
if (character === "\\") {
|
|
1083
|
+
at += 1;
|
|
1084
|
+
continue;
|
|
1085
|
+
}
|
|
1086
|
+
if (character === '"')
|
|
1087
|
+
return JSON.parse(body.slice(start, at));
|
|
1088
|
+
}
|
|
1089
|
+
return fail();
|
|
1090
|
+
};
|
|
1091
|
+
const value = (depth) => {
|
|
1092
|
+
if (depth > 6 || ++nodes > 256)
|
|
1093
|
+
fail();
|
|
1094
|
+
space();
|
|
1095
|
+
const character = body[at];
|
|
1096
|
+
if (character === '"')
|
|
1097
|
+
return string();
|
|
1098
|
+
if (character === "{") {
|
|
1099
|
+
at += 1;
|
|
1100
|
+
const result = /* @__PURE__ */ Object.create(null);
|
|
1101
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1102
|
+
space();
|
|
1103
|
+
if (body[at] === "}") {
|
|
1104
|
+
at += 1;
|
|
1105
|
+
return result;
|
|
1106
|
+
}
|
|
1107
|
+
for (;;) {
|
|
1108
|
+
const key = string();
|
|
1109
|
+
if (seen.has(key) || ["__proto__", "prototype", "constructor"].includes(key))
|
|
1110
|
+
fail();
|
|
1111
|
+
seen.add(key);
|
|
1112
|
+
space();
|
|
1113
|
+
if (body[at++] !== ":")
|
|
1114
|
+
fail();
|
|
1115
|
+
result[key] = value(depth + 1);
|
|
1116
|
+
space();
|
|
1117
|
+
const next = body[at++];
|
|
1118
|
+
if (next === "}")
|
|
1119
|
+
return result;
|
|
1120
|
+
if (next !== ",")
|
|
1121
|
+
fail();
|
|
1122
|
+
}
|
|
1123
|
+
}
|
|
1124
|
+
if (character === "[") {
|
|
1125
|
+
at += 1;
|
|
1126
|
+
const result = [];
|
|
1127
|
+
space();
|
|
1128
|
+
if (body[at] === "]") {
|
|
1129
|
+
at += 1;
|
|
1130
|
+
return result;
|
|
1131
|
+
}
|
|
1132
|
+
for (;;) {
|
|
1133
|
+
result.push(value(depth + 1));
|
|
1134
|
+
space();
|
|
1135
|
+
const next = body[at++];
|
|
1136
|
+
if (next === "]")
|
|
1137
|
+
return result;
|
|
1138
|
+
if (next !== ",")
|
|
1139
|
+
fail();
|
|
1140
|
+
}
|
|
1141
|
+
}
|
|
1142
|
+
for (const literal of ["true", "false", "null"]) {
|
|
1143
|
+
if (body.startsWith(literal, at)) {
|
|
1144
|
+
at += literal.length;
|
|
1145
|
+
return JSON.parse(literal);
|
|
1146
|
+
}
|
|
1147
|
+
}
|
|
1148
|
+
const number = /^-?(?:0|[1-9][0-9]*)(?:\.[0-9]+)?(?:[eE][+-]?[0-9]+)?/.exec(body.slice(at, at + 32));
|
|
1149
|
+
if (!number)
|
|
1150
|
+
fail();
|
|
1151
|
+
at += number[0].length;
|
|
1152
|
+
const parsed = Number(number[0]);
|
|
1153
|
+
if (!Number.isFinite(parsed))
|
|
1154
|
+
fail();
|
|
1155
|
+
return parsed;
|
|
1156
|
+
};
|
|
1157
|
+
try {
|
|
1158
|
+
const parsed = value(0);
|
|
1159
|
+
space();
|
|
1160
|
+
return at === body.length && record5(parsed) ? parsed : null;
|
|
1161
|
+
}
|
|
1162
|
+
catch {
|
|
1163
|
+
return null;
|
|
1164
|
+
}
|
|
1165
|
+
}
|
|
1166
|
+
function namesCard(root) {
|
|
1167
|
+
const pending = [root];
|
|
1168
|
+
while (pending.length > 0) {
|
|
1169
|
+
const node = pending.pop();
|
|
1170
|
+
for (const key of Object.keys(node)) {
|
|
1171
|
+
if (!Array.isArray(node) && /^(?:pan|cardnumber|card_number|number|securitycode|cvv|cvc|paymentform|paymentmethodtoken)$/i.test(key))
|
|
1172
|
+
return true;
|
|
1173
|
+
const child = node[key];
|
|
1174
|
+
if (child !== null && typeof child === "object")
|
|
1175
|
+
pending.push(child);
|
|
1176
|
+
}
|
|
1177
|
+
}
|
|
1178
|
+
return false;
|
|
1179
|
+
}
|
|
1180
|
+
function sharedMembersReadable(value) {
|
|
1181
|
+
for (const [key, max] of Object.entries(TEXT_MEMBERS))
|
|
1182
|
+
if (owns4(value, key) && value[key] !== null && !text(value[key], max))
|
|
1183
|
+
return false;
|
|
1184
|
+
for (const key of BOOLEAN_MEMBERS)
|
|
1185
|
+
if (owns4(value, key) && value[key] !== null && typeof value[key] !== "boolean")
|
|
1186
|
+
return false;
|
|
1187
|
+
if (owns4(value, "device")) {
|
|
1188
|
+
const device = value.device;
|
|
1189
|
+
if (!keysWithin(device, DEVICE_KEYS))
|
|
1190
|
+
return false;
|
|
1191
|
+
for (const member of Object.values(device)) {
|
|
1192
|
+
if (!(member === null || text(member, 512) || typeof member === "boolean" || Number.isSafeInteger(member) && member >= 0 && member <= 1e5))
|
|
1193
|
+
return false;
|
|
1194
|
+
}
|
|
1195
|
+
}
|
|
1196
|
+
return true;
|
|
1197
|
+
}
|
|
1198
|
+
function followUpReadable(value) {
|
|
1199
|
+
const result = value.instructionResult;
|
|
1200
|
+
return keysWithin(value, FOLLOW_UP_KEYS) && FOLLOW_UP_REQUIRED.every((key) => owns4(value, key)) && text(value.formToken, 16384) && value.formToken !== "" && text(value.publicKey, 160) && value.publicKey !== "" && typeof value.remoteId === "string" && REMOTE_ID.test(value.remoteId) && sharedMembersReadable(value) && keysWithin(result, INSTRUCTION_RESULT_KEYS) && typeof result.name === "string" && /^[A-Z_]{1,32}$/.test(result.name) && (!owns4(result, "value") || result.value === null || text(result.value, 16384)) && (!owns4(result, "protocol") || result.protocol === null || record5(result.protocol)) && !namesCard(value);
|
|
1201
|
+
}
|
|
1202
|
+
function bindingHolds(facts, publicKey, target) {
|
|
1203
|
+
const key = PUBLIC_KEY.exec(publicKey);
|
|
1204
|
+
if (!key || facts.mode === "TEST" !== (key[2] === "testpublickey"))
|
|
1205
|
+
return false;
|
|
1206
|
+
if (target === void 0)
|
|
1207
|
+
return true;
|
|
1208
|
+
return LYRA_HOSTS[target.host].prefixes.includes(facts.prefix) && facts.session === target.session;
|
|
1209
|
+
}
|
|
1210
|
+
function lyraBodyVerdict(body, url) {
|
|
1211
|
+
let target;
|
|
1212
|
+
if (url !== void 0) {
|
|
1213
|
+
target = lyraProcessPaymentUrl(url);
|
|
1214
|
+
if (target === null)
|
|
1215
|
+
return refuse8("lyra_url_refused");
|
|
1216
|
+
}
|
|
1217
|
+
const value = readJson(body);
|
|
1218
|
+
if (value === null)
|
|
1219
|
+
return refuse8("lyra_body_unsupported");
|
|
1220
|
+
if (!owns4(value, "paymentForm"))
|
|
1221
|
+
return followUpReadable(value) ? CONTINUE3 : refuse8("lyra_body_unsupported");
|
|
1222
|
+
const form = value.paymentForm;
|
|
1223
|
+
if (!keysWithin(value, CARD_KEYS4) || !CARD_REQUIRED.every((key) => owns4(value, key)) || !sharedMembersReadable(value) || !keysWithin(form, PAYMENT_FORM_KEYS) || typeof form.pan !== "string" || !CARD_NUMBER5.test(form.pan) || typeof form.expiryMonth !== "string" || !MONTH2.test(form.expiryMonth) || typeof form.expiryYear !== "string" || !YEAR2.test(form.expiryYear) || owns4(form, "securityCode") && (typeof form.securityCode !== "string" || !SECURITY_CODE4.test(form.securityCode)) || owns4(form, "cardHolderName") && (!text(form.cardHolderName, 256) || PAN_LIKE2.test(form.cardHolderName)) || owns4(form, "brand") && (typeof form.brand !== "string" || !BRAND.test(form.brand)) || typeof value.remoteId !== "string" || !REMOTE_ID.test(value.remoteId) || typeof value.publicKey !== "string" || owns4(value, "kryptonCallbackUrl") && !Object.values(LYRA_HOSTS).some((entry) => value.kryptonCallbackUrl === `${entry.staticOrigin}${CALLBACK_PATH}`)) {
|
|
1224
|
+
return refuse8("lyra_body_unsupported");
|
|
1225
|
+
}
|
|
1226
|
+
const facts = lyraFormTokenFacts(value.formToken);
|
|
1227
|
+
if (facts === null)
|
|
1228
|
+
return refuse8("lyra_body_unsupported");
|
|
1229
|
+
if (facts.formAction !== "PAYMENT")
|
|
1230
|
+
return refuse8("lyra_keeps_card");
|
|
1231
|
+
if (!bindingHolds(facts, value.publicKey, target))
|
|
1232
|
+
return refuse8("lyra_session_mismatch");
|
|
1233
|
+
return CARD7;
|
|
1234
|
+
}
|
|
1235
|
+
var LYRA_MERCHANT_PINS = /* @__PURE__ */ Object.freeze([
|
|
1236
|
+
Object.freeze({
|
|
1237
|
+
id: "le_mas_lyon",
|
|
1238
|
+
merchant: "Association Le MAS",
|
|
1239
|
+
origins: Object.freeze(["https://www.mas-asso.fr"]),
|
|
1240
|
+
shopIds: Object.freeze(["95120524"]),
|
|
1241
|
+
hosts: Object.freeze(["api.systempay.fr"])
|
|
1242
|
+
})
|
|
1243
|
+
]);
|
|
417
1244
|
// src/card-fields.js
|
|
418
1245
|
function processorGate(recognizer, url, body) {
|
|
1246
|
+
if (recognizer && recognizer.psp === LYRA_PSP)
|
|
1247
|
+
return lyraBodyVerdict(body, url);
|
|
419
1248
|
if (recognizer && recognizer.psp === PADDLE_VGS_PSP) {
|
|
420
1249
|
if (url !== void 0 && !isPaddleVgsCardsUrl(url))
|
|
421
1250
|
return { verdict: "refuse", code: "paddle_vgs_url_refused" };
|
|
422
1251
|
return paddleVgsBodyVerdict(body);
|
|
423
1252
|
}
|
|
1253
|
+
if (recognizer && recognizer.psp === PAYFAST_PSP) {
|
|
1254
|
+
if (url !== void 0 && !isPayfastPayUrl(url))
|
|
1255
|
+
return { verdict: "refuse", code: "payfast_url_refused" };
|
|
1256
|
+
return payfastBodyVerdict(body);
|
|
1257
|
+
}
|
|
1258
|
+
if (recognizer && recognizer.psp === PADDLE_TOKENEX_PSP) {
|
|
1259
|
+
const target = url !== void 0 ? paddleTokenexPayTarget(url) : null;
|
|
1260
|
+
if (url !== void 0 && target === null)
|
|
1261
|
+
return { verdict: "refuse", code: "paddle_tokenex_pay_unsupported" };
|
|
1262
|
+
return paddleTokenexBodyVerdict(body, target ? target.line : void 0);
|
|
1263
|
+
}
|
|
424
1264
|
if (recognizer && recognizer.psp === GRAVY_PSP)
|
|
425
1265
|
return gravyBodyVerdict(body);
|
|
426
1266
|
if (recognizer && recognizer.psp === MONERIS_PSP) {
|
|
@@ -541,20 +1381,20 @@ var KEEP_ON_FILE_REFUSAL = "Refusing to pay: this Primer payment would keep the
|
|
|
541
1381
|
var UNSUPPORTED_SDK_REFUSAL = "Refusing to pay: this checkout uses a Primer SDK Agentcard does not support yet. Nothing was sent.";
|
|
542
1382
|
var NETWORK_MISMATCH_REFUSAL = "Refusing to pay: this Primer payment names a card network that is not your card's. Nothing was sent.";
|
|
543
1383
|
var FILL_REFUSAL = "Could not fill the card fields for Primer. Nothing was sent.";
|
|
544
|
-
var
|
|
1384
|
+
var BODY_LIMIT5 = 16384;
|
|
545
1385
|
var RESPONSE_LIMIT = 32768;
|
|
546
1386
|
var ROOT_KEYS3 = ["paymentInstrument", "userDescription", "tokenType", "paymentFlow"];
|
|
547
1387
|
var INSTRUMENT_KEYS = ["number", "cvv", "expirationMonth", "expirationYear", "cardholderName", "preferredNetwork"];
|
|
548
1388
|
var REQUIRED_INSTRUMENT_KEYS = ["number", "cvv", "expirationMonth", "expirationYear"];
|
|
549
|
-
var
|
|
550
|
-
var
|
|
1389
|
+
var record6 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
1390
|
+
var owns5 = (value, key) => Object.prototype.hasOwnProperty.call(value, key);
|
|
551
1391
|
var exact = (pattern, value) => typeof value === "string" && pattern.exec(value)?.[0] === value;
|
|
552
|
-
var
|
|
1392
|
+
var text2 = (value, max) => typeof value === "string" && value.length <= max && !/[\u0000-\u001f\u007f]/.test(value);
|
|
553
1393
|
var digits = (value, min, max) => typeof value === "string" && value.length >= min && value.length <= max && !/[^0-9]/.test(value);
|
|
554
1394
|
var panLike = (value) => /(?:[0-9][ _.:-]*){12,}/.test(value);
|
|
555
|
-
var plain = (value, max) =>
|
|
556
|
-
var
|
|
557
|
-
var
|
|
1395
|
+
var plain = (value, max) => text2(value, max) && !panLike(value);
|
|
1396
|
+
var MONTH3 = /^(?:0[1-9]|1[0-2])$/;
|
|
1397
|
+
var YEAR3 = /^20[0-9]{2}$/;
|
|
558
1398
|
var NETWORK = /^[A-Z][A-Z_]{1,31}$/;
|
|
559
1399
|
function isPrimerTokenizeUrl(url, method = "POST") {
|
|
560
1400
|
if (method !== "POST" || typeof url !== "string" || url.length > 256 || url.includes("?") || url.includes("#"))
|
|
@@ -568,8 +1408,8 @@ function isPrimerTokenizeUrl(url, method = "POST") {
|
|
|
568
1408
|
}
|
|
569
1409
|
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;
|
|
570
1410
|
}
|
|
571
|
-
function
|
|
572
|
-
if (typeof body !== "string" || body === "" || body.length >
|
|
1411
|
+
function judgeBody2(body) {
|
|
1412
|
+
if (typeof body !== "string" || body === "" || body.length > BODY_LIMIT5)
|
|
573
1413
|
return null;
|
|
574
1414
|
let value;
|
|
575
1415
|
try {
|
|
@@ -578,21 +1418,21 @@ function judgeBody(body) {
|
|
|
578
1418
|
catch {
|
|
579
1419
|
return null;
|
|
580
1420
|
}
|
|
581
|
-
if (!
|
|
1421
|
+
if (!record6(value) || !roundTrips(value, body))
|
|
582
1422
|
return null;
|
|
583
|
-
if (!Object.keys(value).every((key) => ROOT_KEYS3.includes(key)) || !
|
|
1423
|
+
if (!Object.keys(value).every((key) => ROOT_KEYS3.includes(key)) || !owns5(value, "paymentInstrument"))
|
|
584
1424
|
return null;
|
|
585
1425
|
const instrument = value.paymentInstrument;
|
|
586
|
-
if (!
|
|
1426
|
+
if (!record6(instrument) || !Object.keys(instrument).every((key) => INSTRUMENT_KEYS.includes(key)) || !REQUIRED_INSTRUMENT_KEYS.every((key) => owns5(instrument, key)))
|
|
587
1427
|
return null;
|
|
588
|
-
if (!digits(instrument.number, 12, 19) || !digits(instrument.cvv, 3, 4) || !exact(
|
|
1428
|
+
if (!digits(instrument.number, 12, 19) || !digits(instrument.cvv, 3, 4) || !exact(MONTH3, instrument.expirationMonth) || !exact(YEAR3, instrument.expirationYear))
|
|
589
1429
|
return null;
|
|
590
|
-
if (
|
|
1430
|
+
if (owns5(instrument, "cardholderName") && instrument.cardholderName !== null && !plain(instrument.cardholderName, 256) || owns5(instrument, "preferredNetwork") && instrument.preferredNetwork !== null && !exact(NETWORK, instrument.preferredNetwork) || owns5(value, "userDescription") && value.userDescription !== null && !plain(value.userDescription, 256) || owns5(value, "tokenType") && value.tokenType !== "MULTI_USE" || owns5(value, "paymentFlow") && value.paymentFlow !== "VAULT")
|
|
591
1431
|
return null;
|
|
592
|
-
return { value, keepOnFile:
|
|
1432
|
+
return { value, keepOnFile: owns5(value, "tokenType") || owns5(value, "paymentFlow") };
|
|
593
1433
|
}
|
|
594
1434
|
function primerBodyRefusal(body) {
|
|
595
|
-
const judged =
|
|
1435
|
+
const judged = judgeBody2(body);
|
|
596
1436
|
if (!judged)
|
|
597
1437
|
return "unsupported";
|
|
598
1438
|
return judged.keepOnFile ? "keep_on_file" : null;
|
|
@@ -601,7 +1441,7 @@ function isPrimerNewCardBody(body) {
|
|
|
601
1441
|
return primerBodyRefusal(body) === null;
|
|
602
1442
|
}
|
|
603
1443
|
function primerKeepOnFileRequested(body) {
|
|
604
|
-
const judged =
|
|
1444
|
+
const judged = judgeBody2(body);
|
|
605
1445
|
return judged ? judged.keepOnFile : null;
|
|
606
1446
|
}
|
|
607
1447
|
var CARD_GATE = /* @__PURE__ */ Object.freeze({ psp: "primer", encoding: "json", jsonCardFields: [["paymentInstrument", "number"]] });
|
|
@@ -611,7 +1451,7 @@ var CLIENT_TOKEN = /^[A-Za-z0-9._~+/=-]{16,4096}$/;
|
|
|
611
1451
|
var REQUEST_ID = /^[A-Za-z0-9-]{1,64}$/;
|
|
612
1452
|
var API_VERSION = /^2\.[0-9]{1,2}$/;
|
|
613
1453
|
function readHeaders(headers) {
|
|
614
|
-
if (!
|
|
1454
|
+
if (!record6(headers))
|
|
615
1455
|
return null;
|
|
616
1456
|
const folded = /* @__PURE__ */ new Map();
|
|
617
1457
|
for (const [name, value] of Object.entries(headers)) {
|
|
@@ -658,7 +1498,7 @@ function onTokenizePath(url) {
|
|
|
658
1498
|
}
|
|
659
1499
|
}
|
|
660
1500
|
function primerTokenizeRefusal(request) {
|
|
661
|
-
if (!
|
|
1501
|
+
if (!record6(request) || request.method !== "POST" || !isPrimerTokenizeUrl(request.url))
|
|
662
1502
|
return "unsupported";
|
|
663
1503
|
return headersRefusal(request.headers) ?? primerBodyRefusal(request.body);
|
|
664
1504
|
}
|
|
@@ -673,7 +1513,7 @@ function primerCardOnFileRefusal(url, options, policy = PRIMER_SESSION_CARD_ON_F
|
|
|
673
1513
|
return "unsupported";
|
|
674
1514
|
if (new URL(url).hostname !== LIVE_PCI_HOST)
|
|
675
1515
|
return null;
|
|
676
|
-
return primerCardOnFileDisclosure(url, policy) &&
|
|
1516
|
+
return primerCardOnFileDisclosure(url, policy) && record6(options) && options.keepOnFile === true ? null : "keep_on_file";
|
|
677
1517
|
}
|
|
678
1518
|
function primerRefusalMessage(reason) {
|
|
679
1519
|
if (reason === "keep_on_file")
|
|
@@ -698,7 +1538,7 @@ function primerCardNetwork(number) {
|
|
|
698
1538
|
return null;
|
|
699
1539
|
}
|
|
700
1540
|
function primerNetworkRefusal(body, card) {
|
|
701
|
-
const judged =
|
|
1541
|
+
const judged = judgeBody2(body);
|
|
702
1542
|
if (!judged)
|
|
703
1543
|
return "unsupported";
|
|
704
1544
|
const preferred = judged.value.paymentInstrument.preferredNetwork;
|
|
@@ -708,7 +1548,7 @@ function primerNetworkRefusal(body, card) {
|
|
|
708
1548
|
return network !== null && network === preferred ? null : "network_mismatch";
|
|
709
1549
|
}
|
|
710
1550
|
function injectPrimerCard(body, card) {
|
|
711
|
-
const judged =
|
|
1551
|
+
const judged = judgeBody2(body);
|
|
712
1552
|
if (!judged)
|
|
713
1553
|
throw new Error(UNSUPPORTED_REFUSAL);
|
|
714
1554
|
if (judged.keepOnFile)
|
|
@@ -732,7 +1572,7 @@ function injectPrimerCard(body, card) {
|
|
|
732
1572
|
}
|
|
733
1573
|
return { body: JSON.stringify(judged.value), where };
|
|
734
1574
|
}
|
|
735
|
-
var
|
|
1575
|
+
var TOKEN2 = /^[A-Za-z0-9_-]{8,256}$/;
|
|
736
1576
|
var ERROR_ID = /^[A-Za-z][A-Za-z0-9_.-]{0,63}$/;
|
|
737
1577
|
var CODE = /^[A-Z][A-Z0-9_]{0,63}$/;
|
|
738
1578
|
var NETWORK_NAME = /^[A-Za-z][A-Za-z0-9 _-]{0,31}$/;
|
|
@@ -757,28 +1597,28 @@ function readAnswer(body) {
|
|
|
757
1597
|
return null;
|
|
758
1598
|
try {
|
|
759
1599
|
const value = JSON.parse(body);
|
|
760
|
-
return
|
|
1600
|
+
return record6(value) ? value : null;
|
|
761
1601
|
}
|
|
762
1602
|
catch {
|
|
763
1603
|
return null;
|
|
764
1604
|
}
|
|
765
1605
|
}
|
|
766
|
-
var tokenValue = (value) => exact(
|
|
767
|
-
var optional = (value, key, check) => !
|
|
1606
|
+
var tokenValue = (value) => exact(TOKEN2, value) && !panLike(value);
|
|
1607
|
+
var optional = (value, key, check) => !owns5(value, key) || value[key] === null || check(value[key]);
|
|
768
1608
|
function cardDetails(data) {
|
|
769
|
-
if (!
|
|
1609
|
+
if (!record6(data) || !exact(/^[0-9]{4}$/, data.last4Digits))
|
|
770
1610
|
return null;
|
|
771
|
-
if (!optional(data, "first6Digits", (v) => exact(/^[0-9]{6}$/, v)) || !optional(data, "expirationMonth", (v) => exact(RESPONSE_MONTH, v)) || !optional(data, "expirationYear", (v) => exact(RESPONSE_YEAR, v)) || !optional(data, "cardholderName", (v) => plain(v, 256)) || !optional(data, "network", (v) => exact(NETWORK_NAME, v)) || !optional(data, "isNetworkTokenized", (v) => typeof v === "boolean") || !optional(data, "binData",
|
|
1611
|
+
if (!optional(data, "first6Digits", (v) => exact(/^[0-9]{6}$/, v)) || !optional(data, "expirationMonth", (v) => exact(RESPONSE_MONTH, v)) || !optional(data, "expirationYear", (v) => exact(RESPONSE_YEAR, v)) || !optional(data, "cardholderName", (v) => plain(v, 256)) || !optional(data, "network", (v) => exact(NETWORK_NAME, v)) || !optional(data, "isNetworkTokenized", (v) => typeof v === "boolean") || !optional(data, "binData", record6))
|
|
772
1612
|
return null;
|
|
773
1613
|
const safe = { last4Digits: data.last4Digits };
|
|
774
1614
|
for (const key of ["first6Digits", "expirationMonth", "expirationYear", "cardholderName", "network", "isNetworkTokenized"]) {
|
|
775
|
-
if (
|
|
1615
|
+
if (owns5(data, key) && data[key] !== null)
|
|
776
1616
|
safe[key] = data[key];
|
|
777
1617
|
}
|
|
778
|
-
if (
|
|
1618
|
+
if (record6(data.binData)) {
|
|
779
1619
|
const bin = {};
|
|
780
1620
|
for (const key of BIN_KEYS) {
|
|
781
|
-
if (!
|
|
1621
|
+
if (!owns5(data.binData, key) || data.binData[key] === null)
|
|
782
1622
|
continue;
|
|
783
1623
|
if (!plain(data.binData[key], 128))
|
|
784
1624
|
return null;
|
|
@@ -791,11 +1631,11 @@ function cardDetails(data) {
|
|
|
791
1631
|
function threeDsSummary(value) {
|
|
792
1632
|
if (value === void 0 || value === null)
|
|
793
1633
|
return null;
|
|
794
|
-
if (!
|
|
1634
|
+
if (!record6(value) || !exact(CODE, value.responseCode) || !optional(value, "reasonCode", (v) => exact(CODE, v)) || !optional(value, "reasonText", (v) => plain(v, 256)) || !optional(value, "protocolVersion", (v) => v === "" || exact(PROTOCOL, v)) || !optional(value, "challengeIssued", (v) => typeof v === "boolean"))
|
|
795
1635
|
return void 0;
|
|
796
1636
|
const safe = { responseCode: value.responseCode };
|
|
797
1637
|
for (const key of ["reasonCode", "reasonText", "protocolVersion", "challengeIssued"]) {
|
|
798
|
-
if (
|
|
1638
|
+
if (owns5(value, key) && value[key] !== null)
|
|
799
1639
|
safe[key] = value[key];
|
|
800
1640
|
}
|
|
801
1641
|
return safe;
|
|
@@ -808,7 +1648,7 @@ function rebuildToken(value) {
|
|
|
808
1648
|
if (!details || threeDs === void 0)
|
|
809
1649
|
return null;
|
|
810
1650
|
const safe = { token: value.token };
|
|
811
|
-
if (
|
|
1651
|
+
if (owns5(value, "analyticsId") && value.analyticsId !== null)
|
|
812
1652
|
safe.analyticsId = value.analyticsId;
|
|
813
1653
|
safe.tokenType = "SINGLE_USE";
|
|
814
1654
|
safe.paymentInstrumentType = "PAYMENT_CARD";
|
|
@@ -819,7 +1659,7 @@ function rebuildToken(value) {
|
|
|
819
1659
|
}
|
|
820
1660
|
function primerErrorId(body) {
|
|
821
1661
|
const value = readAnswer(body);
|
|
822
|
-
const id = value &&
|
|
1662
|
+
const id = value && record6(value.error) ? value.error.errorId : null;
|
|
823
1663
|
return exact(ERROR_ID, id) && !panLike(id) ? id : null;
|
|
824
1664
|
}
|
|
825
1665
|
function matchesCard(details, card) {
|