@agent-cards/sdk 0.23.18 → 0.23.20
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 +30 -0
- package/PREFLIGHT.md +2 -0
- package/README.md +46 -7
- package/dist/aci.d.ts +0 -7
- package/dist/aci.js +0 -19
- package/dist/amadeus.d.ts +4 -2
- package/dist/amadeus.js +16 -3
- package/dist/buy.d.ts +84 -2
- package/dist/buy.js +16 -1
- package/dist/card-endpoint-facts.d.ts +2 -1
- package/dist/card-endpoint-facts.js +18 -9
- package/dist/card-endpoint.d.ts +20 -4
- package/dist/card-endpoint.js +38 -4
- package/dist/card-fields.generated.js +974 -45
- package/dist/cdp.d.ts +29 -0
- package/dist/cdp.js +302 -18
- package/dist/client.d.ts +43 -5
- package/dist/client.js +237 -43
- package/dist/datatrans.d.ts +2 -2
- package/dist/datatrans.generated.js +16 -11
- package/dist/datatrans.js +2 -2
- package/dist/hipay.generated.d.ts +56 -0
- package/dist/hipay.generated.js +389 -0
- package/dist/hold.d.ts +180 -0
- package/dist/hold.js +264 -0
- package/dist/index.d.ts +3 -1
- package/dist/index.js +1 -0
- package/dist/lifecycle.d.ts +10 -0
- package/dist/lifecycle.js +21 -0
- package/dist/merchant-card-endpoints.generated.js +102 -11
- package/dist/paddle-vgs.generated.d.ts +3 -2
- package/dist/paddle-vgs.generated.js +9 -5
- package/dist/pelecard.generated.d.ts +2 -1
- package/dist/pelecard.generated.js +14 -5
- package/dist/pre-claim.d.ts +14 -0
- package/dist/pre-claim.js +76 -3
- package/dist/prepared-processor.d.ts +6 -2
- package/dist/prepared-processor.js +18 -2
- package/dist/primer.generated.js +998 -69
- package/dist/quickpay.d.ts +44 -0
- package/dist/quickpay.js +65 -0
- package/dist/stripe-checkout.generated.js +320 -2
- package/dist/twoc2p.d.ts +54 -0
- package/dist/twoc2p.generated.d.ts +33 -0
- package/dist/twoc2p.generated.js +1145 -0
- package/dist/twoc2p.js +85 -0
- package/dist/voice.d.ts +16 -13
- package/dist/voice.js +13 -10
- package/package.json +3 -3
package/dist/primer.generated.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// @ts-nocheck
|
|
2
2
|
// Generated from @agent-cards/payment-core. Do not edit.
|
|
3
|
-
// artifact-sha256:
|
|
3
|
+
// artifact-sha256: 04a99605d111c45486d6e77e4e9f55e04217690d33f5ddbfcffa4950c6754c17
|
|
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 text4 = typeof value === "number" && Number.isFinite(value) ? String(value) : value;
|
|
113
|
+
const m = typeof text4 === "string" ? AMOUNT.exec(text4) : null;
|
|
114
114
|
if (!m)
|
|
115
115
|
return null;
|
|
116
116
|
const cents = Number(m[1]) * 100 + Number(((m[2] ?? "") + "00").slice(0, 2));
|
|
@@ -310,11 +310,11 @@ var MONERIS_TOKENIZE_PATH = "/HPPtoken/request.php";
|
|
|
310
310
|
function monerisTokenizeEnvironment(url) {
|
|
311
311
|
if (typeof url !== "string")
|
|
312
312
|
return null;
|
|
313
|
-
for (const
|
|
313
|
+
for (const environment2 of
|
|
314
314
|
/** @type {const} */
|
|
315
315
|
["production", "sandbox"]) {
|
|
316
|
-
if (MONERIS_TOKENIZE_HOSTS[
|
|
317
|
-
return
|
|
316
|
+
if (MONERIS_TOKENIZE_HOSTS[environment2].some((host) => url === `https://${host}${MONERIS_TOKENIZE_PATH}`))
|
|
317
|
+
return environment2;
|
|
318
318
|
}
|
|
319
319
|
return null;
|
|
320
320
|
}
|
|
@@ -365,8 +365,8 @@ var CONTROL = /[\u0000-\u001f\u007f]/;
|
|
|
365
365
|
var cardLikeName = (name) => (name.match(/[0-9]/g) ?? []).length >= 12;
|
|
366
366
|
var record3 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
367
367
|
var sameKeys = (value, keys) => {
|
|
368
|
-
const
|
|
369
|
-
return
|
|
368
|
+
const own3 = Object.keys(value);
|
|
369
|
+
return own3.length === keys.length && own3.every((key, at) => key === keys[at]);
|
|
370
370
|
};
|
|
371
371
|
var refuse4 = (code) => Object.freeze({ verdict: "refuse", code });
|
|
372
372
|
var CARD4 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
|
|
@@ -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(text4) {
|
|
594
594
|
const out = [];
|
|
595
|
-
for (const char of
|
|
595
|
+
for (const char of text4) {
|
|
596
596
|
let cp = char.codePointAt(0);
|
|
597
597
|
if (cp >= 55296 && cp <= 57343)
|
|
598
598
|
cp = 65533;
|
|
@@ -754,13 +754,13 @@ var PADDLE_TOKENEX_KEYS = /* @__PURE__ */ Object.freeze({
|
|
|
754
754
|
sha256: "92529bd289bb24d52a1bdcc42edc9ac0bb1dacbb58f7568573d44771e1287762"
|
|
755
755
|
})
|
|
756
756
|
});
|
|
757
|
-
function paddleTokenexKey(
|
|
758
|
-
if (
|
|
757
|
+
function paddleTokenexKey(environment2) {
|
|
758
|
+
if (environment2 !== "sandbox" && environment2 !== "production")
|
|
759
759
|
return null;
|
|
760
|
-
return PADDLE_TOKENEX_KEYS[
|
|
760
|
+
return PADDLE_TOKENEX_KEYS[environment2] ?? null;
|
|
761
761
|
}
|
|
762
|
-
function paddleTokenexKeyBytes(
|
|
763
|
-
const key = paddleTokenexKey(
|
|
762
|
+
function paddleTokenexKeyBytes(environment2) {
|
|
763
|
+
const key = paddleTokenexKey(environment2);
|
|
764
764
|
if (!key)
|
|
765
765
|
return null;
|
|
766
766
|
try {
|
|
@@ -775,8 +775,8 @@ var PADDLE_TOKENEX_PSP = "paddle_tokenex";
|
|
|
775
775
|
var PADDLE_TOKENEX_FACT_KEYS = /* @__PURE__ */ Object.freeze(["card_first_six", "card_last_four", "expiry_month", "expiry_year", "card_brand"]);
|
|
776
776
|
var record4 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
777
777
|
var sameKeys2 = (value, keys) => {
|
|
778
|
-
const
|
|
779
|
-
return
|
|
778
|
+
const own3 = Object.keys(value);
|
|
779
|
+
return own3.length === keys.length && own3.every((key, at) => key === keys[at]);
|
|
780
780
|
};
|
|
781
781
|
var refuse7 = (code) => Object.freeze({ verdict: "refuse", code });
|
|
782
782
|
var CARD6 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
|
|
@@ -821,11 +821,11 @@ function isBase64OfBytes(value, bytes) {
|
|
|
821
821
|
const pad = value.endsWith("==") ? 2 : value.endsWith("=") ? 1 : 0;
|
|
822
822
|
return value.length / 4 * 3 - pad === bytes && btoa(atob(value)) === value;
|
|
823
823
|
}
|
|
824
|
-
function isPaddleTokenexCiphertext(value,
|
|
825
|
-
const bytes = paddleTokenexKeyBytes(
|
|
824
|
+
function isPaddleTokenexCiphertext(value, environment2) {
|
|
825
|
+
const bytes = paddleTokenexKeyBytes(environment2);
|
|
826
826
|
return bytes !== null && isBase64OfBytes(value, bytes);
|
|
827
827
|
}
|
|
828
|
-
function readPay(body, line,
|
|
828
|
+
function readPay(body, line, environment2) {
|
|
829
829
|
if (typeof body !== "string" || body === "" || body.length > PAY_BODY_LIMIT)
|
|
830
830
|
return null;
|
|
831
831
|
let value;
|
|
@@ -857,11 +857,11 @@ function readPay(body, line, environment) {
|
|
|
857
857
|
return null;
|
|
858
858
|
for (const name of CARD_KEYS3) {
|
|
859
859
|
const blob = tokenex[name];
|
|
860
|
-
if (
|
|
860
|
+
if (environment2 === void 0) {
|
|
861
861
|
if (typeof blob !== "string" || !BASE642.test(blob) || blob.length < 4 || blob.length > 4096)
|
|
862
862
|
return null;
|
|
863
863
|
}
|
|
864
|
-
else if (!isPaddleTokenexCiphertext(blob,
|
|
864
|
+
else if (!isPaddleTokenexCiphertext(blob, environment2))
|
|
865
865
|
return null;
|
|
866
866
|
}
|
|
867
867
|
if (tokenex.encrypted_card_number === tokenex.encrypted_cvv)
|
|
@@ -1265,8 +1265,8 @@ var TEXT_LIMIT = 256;
|
|
|
1265
1265
|
var CONTROL4 = /[\u0000-\u001f\u007f]/;
|
|
1266
1266
|
var record6 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
1267
1267
|
var sameKeys3 = (value, keys) => {
|
|
1268
|
-
const
|
|
1269
|
-
return
|
|
1268
|
+
const own3 = Object.keys(value);
|
|
1269
|
+
return own3.length === keys.length && own3.every((key, at) => key === keys[at]);
|
|
1270
1270
|
};
|
|
1271
1271
|
var plainText = (value) => typeof value === "string" && value.length <= TEXT_LIMIT && !CONTROL4.test(value) && (value.match(/[0-9]/g) ?? []).length < 12;
|
|
1272
1272
|
var refuse9 = (code) => Object.freeze({ verdict: "refuse", code });
|
|
@@ -1376,14 +1376,14 @@ function readJson2(body) {
|
|
|
1376
1376
|
catch {
|
|
1377
1377
|
return { parsed: null, exact: false };
|
|
1378
1378
|
}
|
|
1379
|
-
let
|
|
1379
|
+
let exact3 = false;
|
|
1380
1380
|
try {
|
|
1381
|
-
|
|
1381
|
+
exact3 = body.length <= BODY_LIMIT6 && JSON.stringify(parsed) === body;
|
|
1382
1382
|
}
|
|
1383
1383
|
catch {
|
|
1384
|
-
|
|
1384
|
+
exact3 = false;
|
|
1385
1385
|
}
|
|
1386
|
-
return { parsed, exact:
|
|
1386
|
+
return { parsed, exact: exact3 };
|
|
1387
1387
|
}
|
|
1388
1388
|
function billingValue(value) {
|
|
1389
1389
|
if (value === UNDEFINED)
|
|
@@ -1438,14 +1438,14 @@ function attachType(parsed) {
|
|
|
1438
1438
|
return typeof type === "string" ? type : null;
|
|
1439
1439
|
}
|
|
1440
1440
|
function paymongoBodyVerdict(body, session) {
|
|
1441
|
-
const { parsed, exact:
|
|
1441
|
+
const { parsed, exact: exact3 } = readJson2(body);
|
|
1442
1442
|
const type = parsed === null ? null : attachType(parsed);
|
|
1443
1443
|
if (type !== "card") {
|
|
1444
1444
|
if (parsed === null)
|
|
1445
1445
|
return body === void 0 || body === null || body === "" ? CONTINUE4 : refuse10("paymongo_body_unsupported");
|
|
1446
1446
|
return namesCardValue(parsed) ? refuse10("paymongo_body_unsupported") : CONTINUE4;
|
|
1447
1447
|
}
|
|
1448
|
-
if (!
|
|
1448
|
+
if (!exact3)
|
|
1449
1449
|
return refuse10("paymongo_body_unsupported");
|
|
1450
1450
|
const code = judgeCardAttach(parsed, session);
|
|
1451
1451
|
return code === null ? CARD9 : refuse10(code);
|
|
@@ -1468,8 +1468,8 @@ var EXPIRATION = /^[0-9]{2}(?:0[1-9]|1[0-2])$/;
|
|
|
1468
1468
|
var CARD_PAYMENT = "PAYMENT_CARD";
|
|
1469
1469
|
var record8 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
1470
1470
|
var sameKeys4 = (value, keys) => {
|
|
1471
|
-
const
|
|
1472
|
-
return
|
|
1471
|
+
const own3 = Object.keys(value);
|
|
1472
|
+
return own3.length === keys.length && own3.every((key, at) => key === keys[at]);
|
|
1473
1473
|
};
|
|
1474
1474
|
var refuse11 = (code) => Object.freeze({ verdict: "refuse", code });
|
|
1475
1475
|
var CARD10 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
|
|
@@ -1498,8 +1498,8 @@ function gopayCardFormUrl(url) {
|
|
|
1498
1498
|
}
|
|
1499
1499
|
if (parsed.href !== url || parsed.protocol !== "https:" || parsed.port || parsed.username || parsed.password)
|
|
1500
1500
|
return null;
|
|
1501
|
-
const
|
|
1502
|
-
if (
|
|
1501
|
+
const environment2 = Object.prototype.hasOwnProperty.call(GOPAY_CARD_FORM_HOSTS, parsed.hostname) ? GOPAY_CARD_FORM_HOSTS[parsed.hostname] : null;
|
|
1502
|
+
if (environment2 === null || !parsed.pathname.startsWith(GOPAY_CARD_FORM_PATH))
|
|
1503
1503
|
return null;
|
|
1504
1504
|
if (!TOKEN2.test(parsed.pathname.slice(GOPAY_CARD_FORM_PATH.length)))
|
|
1505
1505
|
return null;
|
|
@@ -1511,7 +1511,7 @@ function gopayCardFormUrl(url) {
|
|
|
1511
1511
|
const version = parsed.searchParams.get("ver");
|
|
1512
1512
|
if (signature === null || !SIGNATURE.test(signature) || language !== null && !LANGUAGE.test(language) || version !== null && !VERSION.test(version))
|
|
1513
1513
|
return null;
|
|
1514
|
-
return Object.freeze({ host: parsed.hostname, environment, signature });
|
|
1514
|
+
return Object.freeze({ host: parsed.hostname, environment: environment2, signature });
|
|
1515
1515
|
}
|
|
1516
1516
|
function readBody4(body) {
|
|
1517
1517
|
if (typeof body !== "string" || body === "" || body.length > BODY_LIMIT7)
|
|
@@ -1666,6 +1666,9 @@ function payrexxGateVerdict(url, body) {
|
|
|
1666
1666
|
const verdict = payrexxBodyVerdict(body);
|
|
1667
1667
|
return verdict.verdict === "card" && target.pspId !== PAYREXX_PAY_PSP_ID ? refuse12("payrexx_other_provider") : verdict;
|
|
1668
1668
|
}
|
|
1669
|
+
var PAYREXX_FOLLOW_UP_WINDOW_MS = 15 * 60 * 1e3;
|
|
1670
|
+
var PAYREXX_FOLLOW_UP_IDLE_MS = 60 * 1e3;
|
|
1671
|
+
var PAYREXX_FOLLOW_UP_CHALLENGE_MS = 11 * 60 * 1e3;
|
|
1669
1672
|
// src/komoju.js
|
|
1670
1673
|
var KOMOJU_PSP = "komoju";
|
|
1671
1674
|
var KOMOJU_HOST = "komoju.com";
|
|
@@ -1693,8 +1696,8 @@ var LOCALE = /^[a-z]{2}(?:-[A-Za-z]{2,4})?$/;
|
|
|
1693
1696
|
var PAN_LIKE3 = /(?:[0-9][ _.:-]*){12,}/;
|
|
1694
1697
|
var record9 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
1695
1698
|
var sameKeys5 = (value, keys) => {
|
|
1696
|
-
const
|
|
1697
|
-
return
|
|
1699
|
+
const own3 = Object.keys(value);
|
|
1700
|
+
return own3.length === keys.length && own3.every((key, at) => key === keys[at]);
|
|
1698
1701
|
};
|
|
1699
1702
|
var refuse13 = (code) => Object.freeze({ verdict: "refuse", code });
|
|
1700
1703
|
var CARD12 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
|
|
@@ -1851,14 +1854,14 @@ function paygentBodyVerdict(body) {
|
|
|
1851
1854
|
return code === null ? CARD13 : refuse14(code);
|
|
1852
1855
|
}
|
|
1853
1856
|
function paygentRequestVerdict(url, body) {
|
|
1854
|
-
const
|
|
1855
|
-
if (
|
|
1857
|
+
const environment2 = paygentEnvironment(url);
|
|
1858
|
+
if (environment2 === null)
|
|
1856
1859
|
return refuse14("paygent_url_refused");
|
|
1857
1860
|
const { code, pairs } = judgeBody3(body);
|
|
1858
1861
|
if (code !== null)
|
|
1859
1862
|
return refuse14(code);
|
|
1860
1863
|
const key = pairs[1][1];
|
|
1861
|
-
return (
|
|
1864
|
+
return (environment2 === "production" ? LIVE_KEY : SANDBOX_KEY).test(key) ? CARD13 : refuse14("paygent_key_environment");
|
|
1862
1865
|
}
|
|
1863
1866
|
// src/multipart-form.js
|
|
1864
1867
|
var BODY_LIMIT11 = 65536;
|
|
@@ -2002,6 +2005,907 @@ function payNlBodyVerdict(body, contentType) {
|
|
|
2002
2005
|
}
|
|
2003
2006
|
var ERROR_KEYS = /* @__PURE__ */ Object.freeze(["errorId", "errorTag", "errorMessage", "errorFieldName"]);
|
|
2004
2007
|
var REQUEST_KEYS = /* @__PURE__ */ Object.freeze(["result", ...ERROR_KEYS]);
|
|
2008
|
+
// src/revolut.js
|
|
2009
|
+
var REVOLUT_PSP = "revolut";
|
|
2010
|
+
var REVOLUT_HOSTS = /* @__PURE__ */ Object.freeze(["merchant.revolut.com", "sandbox-merchant.revolut.com"]);
|
|
2011
|
+
var REVOLUT_BODY_KEYS = /* @__PURE__ */ Object.freeze(["payment_method", "customer", "amount", "channel"]);
|
|
2012
|
+
var REVOLUT_CARD_FIELD_KEYS = /* @__PURE__ */ Object.freeze([
|
|
2013
|
+
"type",
|
|
2014
|
+
"number",
|
|
2015
|
+
"expiry_month",
|
|
2016
|
+
"expiry_year",
|
|
2017
|
+
"cvv",
|
|
2018
|
+
"kount_session_id",
|
|
2019
|
+
"billing_address",
|
|
2020
|
+
"cardholder_name",
|
|
2021
|
+
"shipping_address",
|
|
2022
|
+
"save_for",
|
|
2023
|
+
"environment"
|
|
2024
|
+
]);
|
|
2025
|
+
var REVOLUT_CARD_POPUP_KEYS = /* @__PURE__ */ Object.freeze([
|
|
2026
|
+
"type",
|
|
2027
|
+
"number",
|
|
2028
|
+
"expiry_month",
|
|
2029
|
+
"expiry_year",
|
|
2030
|
+
"cvv",
|
|
2031
|
+
"kount_session_id",
|
|
2032
|
+
"cardholder_name",
|
|
2033
|
+
"billing_address",
|
|
2034
|
+
"shipping_address",
|
|
2035
|
+
"save_for",
|
|
2036
|
+
"environment"
|
|
2037
|
+
]);
|
|
2038
|
+
var REVOLUT_CHANNELS = /* @__PURE__ */ Object.freeze(["WEB_SDK", "REV_CHECKOUT", "HOSTED_PAYMENT_PAGE"]);
|
|
2039
|
+
var BODY_LIMIT12 = 16384;
|
|
2040
|
+
var URL_LIMIT6 = 128;
|
|
2041
|
+
var UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;
|
|
2042
|
+
var PAYMENTS_PATH = /^\/api\/public\/orders\/([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})\/payments$/;
|
|
2043
|
+
var CARD_NUMBER8 = /^[0-9]{12,19}$/;
|
|
2044
|
+
var SECURITY_CODE11 = /^[0-9]{3,4}$/;
|
|
2045
|
+
var KOUNT_SESSION = /^[0-9a-f]{32}$/;
|
|
2046
|
+
var AMOUNT_LIMIT = 1e11;
|
|
2047
|
+
var ADDRESS_KEYS = /* @__PURE__ */ Object.freeze(["country", "region", "city", "postcode", "street_line_1", "street_line_2"]);
|
|
2048
|
+
var ENVIRONMENT_KEYS = /* @__PURE__ */ Object.freeze([
|
|
2049
|
+
"type",
|
|
2050
|
+
"color_depth",
|
|
2051
|
+
"screen_width",
|
|
2052
|
+
"screen_height",
|
|
2053
|
+
"java_enabled",
|
|
2054
|
+
"time_zone_utc_offset",
|
|
2055
|
+
"challenge_window_width",
|
|
2056
|
+
"browser_url",
|
|
2057
|
+
"referrer_url"
|
|
2058
|
+
]);
|
|
2059
|
+
var NEW_CUSTOMER_KEYS = /* @__PURE__ */ Object.freeze(["type", "email", "name", "phone"]);
|
|
2060
|
+
var COUNTRY = /^[A-Z]{2}$/;
|
|
2061
|
+
var PHONE = /^\+?[0-9 \u00a0\/().-]{6,32}$/;
|
|
2062
|
+
var EMAIL3 = /^[^\s@]{1,64}@[^\s@]{1,255}$/;
|
|
2063
|
+
var TEXT_LIMIT2 = 256;
|
|
2064
|
+
var CONTROL5 = /[\u0000-\u001f\u007f]/;
|
|
2065
|
+
var CARD_MEMBER2 = /^(?:number|card_?number|cardnumber|cardnum|card_num|pan|cvv|cvc|cvv2)$/i;
|
|
2066
|
+
var record10 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
2067
|
+
var own2 = (value, key) => Object.prototype.hasOwnProperty.call(value, key);
|
|
2068
|
+
var inOrder = (value, keys) => {
|
|
2069
|
+
let at = 0;
|
|
2070
|
+
for (const name of Object.keys(value)) {
|
|
2071
|
+
while (at < keys.length && keys[at] !== name)
|
|
2072
|
+
at += 1;
|
|
2073
|
+
if (at === keys.length)
|
|
2074
|
+
return false;
|
|
2075
|
+
at += 1;
|
|
2076
|
+
}
|
|
2077
|
+
return true;
|
|
2078
|
+
};
|
|
2079
|
+
var wellFormed = (value) => {
|
|
2080
|
+
try {
|
|
2081
|
+
encodeURIComponent(value);
|
|
2082
|
+
return true;
|
|
2083
|
+
}
|
|
2084
|
+
catch {
|
|
2085
|
+
return false;
|
|
2086
|
+
}
|
|
2087
|
+
};
|
|
2088
|
+
var plainText2 = (value) => typeof value === "string" && value.length >= 1 && value.length <= TEXT_LIMIT2 && !CONTROL5.test(value) && (value.match(/[0-9]/g) ?? []).length < 12 && wellFormed(value);
|
|
2089
|
+
var between = (value, min, max) => Number.isSafeInteger(value) && value >= min && value <= max;
|
|
2090
|
+
var NETWORK = /^(?:4[0-9]{15}|4[0-9]{12}|5[1-5][0-9]{14}|2(?:2(?:2[1-9]|[3-9][0-9])|[3-6][0-9]{2}|7(?:[01][0-9]|20))[0-9]{12}|3[47][0-9]{13})$/;
|
|
2091
|
+
var luhn2 = (digits2) => {
|
|
2092
|
+
let sum = 0;
|
|
2093
|
+
for (let at = 0; at < digits2.length; at += 1) {
|
|
2094
|
+
let d = digits2.charCodeAt(digits2.length - 1 - at) - 48;
|
|
2095
|
+
if (at % 2 === 1) {
|
|
2096
|
+
d *= 2;
|
|
2097
|
+
if (d > 9)
|
|
2098
|
+
d -= 9;
|
|
2099
|
+
}
|
|
2100
|
+
sum += d;
|
|
2101
|
+
}
|
|
2102
|
+
return sum % 10 === 0;
|
|
2103
|
+
};
|
|
2104
|
+
var ANY_NETWORK = /^[2-6][0-9]{12,18}$/;
|
|
2105
|
+
var holdsCardShape = (text4, shape = NETWORK) => (text4.match(/[0-9]{13,}/g) ?? []).some((run) => run.length > 19 || shape.test(run) && luhn2(run));
|
|
2106
|
+
var phone = (value) => typeof value === "string" && PHONE.test(value) && (value.match(/[0-9]/g) ?? []).length >= 6 && (value.match(/[0-9]/g) ?? []).length <= 15;
|
|
2107
|
+
var refuse16 = (code) => Object.freeze({ verdict: "refuse", code });
|
|
2108
|
+
var CARD15 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
|
|
2109
|
+
var CONTINUE7 = /* @__PURE__ */ Object.freeze({ verdict: "continue" });
|
|
2110
|
+
function revolutPaymentsTarget(url) {
|
|
2111
|
+
if (typeof url !== "string" || url.length > URL_LIMIT6 || url.includes("?") || url.includes("#"))
|
|
2112
|
+
return null;
|
|
2113
|
+
let parsed;
|
|
2114
|
+
try {
|
|
2115
|
+
parsed = new URL(url);
|
|
2116
|
+
}
|
|
2117
|
+
catch {
|
|
2118
|
+
return null;
|
|
2119
|
+
}
|
|
2120
|
+
if (parsed.href !== url || parsed.protocol !== "https:" || parsed.port || parsed.username || parsed.password || !REVOLUT_HOSTS.includes(parsed.hostname))
|
|
2121
|
+
return null;
|
|
2122
|
+
const match = PAYMENTS_PATH.exec(parsed.pathname);
|
|
2123
|
+
return match ? Object.freeze({ host: parsed.hostname, order: match[1] }) : null;
|
|
2124
|
+
}
|
|
2125
|
+
function isRevolutPaymentsUrl(url) {
|
|
2126
|
+
return revolutPaymentsTarget(url) !== null;
|
|
2127
|
+
}
|
|
2128
|
+
function readBody7(body) {
|
|
2129
|
+
if (typeof body !== "string" || body === "" || body.length > BODY_LIMIT12)
|
|
2130
|
+
return null;
|
|
2131
|
+
let value;
|
|
2132
|
+
try {
|
|
2133
|
+
value = JSON.parse(body);
|
|
2134
|
+
if (!record10(value) || JSON.stringify(value) !== body)
|
|
2135
|
+
return null;
|
|
2136
|
+
}
|
|
2137
|
+
catch {
|
|
2138
|
+
return null;
|
|
2139
|
+
}
|
|
2140
|
+
return value;
|
|
2141
|
+
}
|
|
2142
|
+
function address(value) {
|
|
2143
|
+
if (!record10(value) || !inOrder(value, ADDRESS_KEYS))
|
|
2144
|
+
return false;
|
|
2145
|
+
const names = Object.keys(value);
|
|
2146
|
+
if (!names.some((key) => typeof value[key] === "string" && value[key].trim() !== ""))
|
|
2147
|
+
return false;
|
|
2148
|
+
return names.every((key) => value[key] === "" || (key === "country" ? typeof value[key] === "string" && COUNTRY.test(value[key]) : plainText2(value[key])));
|
|
2149
|
+
}
|
|
2150
|
+
function pageUrl(value) {
|
|
2151
|
+
if (typeof value !== "string" || value.length > 2048 || CONTROL5.test(value) || holdsCardShape(value, ANY_NETWORK) || !wellFormed(value))
|
|
2152
|
+
return false;
|
|
2153
|
+
let parsed;
|
|
2154
|
+
try {
|
|
2155
|
+
parsed = new URL(value);
|
|
2156
|
+
}
|
|
2157
|
+
catch {
|
|
2158
|
+
return false;
|
|
2159
|
+
}
|
|
2160
|
+
return parsed.protocol === "https:" || parsed.protocol === "http:";
|
|
2161
|
+
}
|
|
2162
|
+
function referrerOrigin(value) {
|
|
2163
|
+
if (value === "" || value === "null")
|
|
2164
|
+
return true;
|
|
2165
|
+
if (typeof value !== "string" || value.length > 512 || holdsCardShape(value, ANY_NETWORK))
|
|
2166
|
+
return false;
|
|
2167
|
+
let parsed;
|
|
2168
|
+
try {
|
|
2169
|
+
parsed = new URL(value);
|
|
2170
|
+
}
|
|
2171
|
+
catch {
|
|
2172
|
+
return false;
|
|
2173
|
+
}
|
|
2174
|
+
return (parsed.protocol === "https:" || parsed.protocol === "http:") && parsed.origin === value;
|
|
2175
|
+
}
|
|
2176
|
+
function environment(value) {
|
|
2177
|
+
if (!record10(value) || !inOrder(value, ENVIRONMENT_KEYS))
|
|
2178
|
+
return false;
|
|
2179
|
+
return value.type === "browser" && between(value.color_depth, 0, 256) && between(value.screen_width, 0, 1e5) && between(value.screen_height, 0, 1e5) && typeof value.java_enabled === "boolean" && between(value.time_zone_utc_offset, -1440, 1440) && between(value.challenge_window_width, 1, 1e4) && (!own2(value, "browser_url") || pageUrl(value.browser_url)) && (!own2(value, "referrer_url") || referrerOrigin(value.referrer_url));
|
|
2180
|
+
}
|
|
2181
|
+
function customer(value) {
|
|
2182
|
+
if (!record10(value))
|
|
2183
|
+
return false;
|
|
2184
|
+
if (value.type === "existing") {
|
|
2185
|
+
const names = Object.keys(value);
|
|
2186
|
+
return names.length === 2 && names[0] === "type" && names[1] === "id" && typeof value.id === "string" && UUID.test(value.id);
|
|
2187
|
+
}
|
|
2188
|
+
if (value.type !== "new" || !inOrder(value, NEW_CUSTOMER_KEYS) || !own2(value, "email"))
|
|
2189
|
+
return false;
|
|
2190
|
+
if (typeof value.email !== "string" || !EMAIL3.test(value.email) || !plainText2(value.email))
|
|
2191
|
+
return false;
|
|
2192
|
+
if (own2(value, "name") && !plainText2(value.name))
|
|
2193
|
+
return false;
|
|
2194
|
+
return !own2(value, "phone") || phone(value.phone);
|
|
2195
|
+
}
|
|
2196
|
+
function cardMethod(value) {
|
|
2197
|
+
if (!record10(value) || value.type !== "card")
|
|
2198
|
+
return "revolut_body_unsupported";
|
|
2199
|
+
if (!inOrder(value, REVOLUT_CARD_FIELD_KEYS) && !inOrder(value, REVOLUT_CARD_POPUP_KEYS))
|
|
2200
|
+
return "revolut_body_unsupported";
|
|
2201
|
+
if (typeof value.number !== "string" || !CARD_NUMBER8.test(value.number) || !between(value.expiry_month, 1, 12) || !between(value.expiry_year, 2e3, 2099) || typeof value.cvv !== "string" || !SECURITY_CODE11.test(value.cvv))
|
|
2202
|
+
return "revolut_body_unsupported";
|
|
2203
|
+
if (!own2(value, "environment") || !environment(value.environment))
|
|
2204
|
+
return "revolut_body_unsupported";
|
|
2205
|
+
if (own2(value, "kount_session_id") && (typeof value.kount_session_id !== "string" || !KOUNT_SESSION.test(value.kount_session_id))) {
|
|
2206
|
+
return "revolut_body_unsupported";
|
|
2207
|
+
}
|
|
2208
|
+
for (const key of ["billing_address", "shipping_address"]) {
|
|
2209
|
+
if (own2(value, key) && !address(value[key]))
|
|
2210
|
+
return "revolut_body_unsupported";
|
|
2211
|
+
}
|
|
2212
|
+
if (own2(value, "cardholder_name") && !plainText2(value.cardholder_name))
|
|
2213
|
+
return "revolut_body_unsupported";
|
|
2214
|
+
if (own2(value, "save_for")) {
|
|
2215
|
+
if (value.save_for === "CUSTOMER" || value.save_for === "MERCHANT")
|
|
2216
|
+
return "revolut_card_on_file";
|
|
2217
|
+
if (value.save_for !== "NONE")
|
|
2218
|
+
return "revolut_body_unsupported";
|
|
2219
|
+
}
|
|
2220
|
+
return null;
|
|
2221
|
+
}
|
|
2222
|
+
function namesCardValue2(parsed) {
|
|
2223
|
+
const pending = record10(parsed) || Array.isArray(parsed) ? [parsed] : [];
|
|
2224
|
+
while (pending.length > 0) {
|
|
2225
|
+
const node = pending.pop();
|
|
2226
|
+
for (const key of Object.keys(node)) {
|
|
2227
|
+
if (!Array.isArray(node) && CARD_MEMBER2.test(key))
|
|
2228
|
+
return true;
|
|
2229
|
+
const value = node[key];
|
|
2230
|
+
if (value !== null && typeof value === "object")
|
|
2231
|
+
pending.push(value);
|
|
2232
|
+
}
|
|
2233
|
+
}
|
|
2234
|
+
return false;
|
|
2235
|
+
}
|
|
2236
|
+
function revolutBodyVerdict(body) {
|
|
2237
|
+
const value = readBody7(body);
|
|
2238
|
+
if (value === null) {
|
|
2239
|
+
return body === void 0 || body === null || body === "" ? CONTINUE7 : refuse16("revolut_body_unsupported");
|
|
2240
|
+
}
|
|
2241
|
+
const method = record10(value.payment_method) ? value.payment_method.type : void 0;
|
|
2242
|
+
if (method !== "card")
|
|
2243
|
+
return namesCardValue2(value) ? refuse16("revolut_body_unsupported") : CONTINUE7;
|
|
2244
|
+
if (!inOrder(value, REVOLUT_BODY_KEYS) || Object.keys(value).length !== REVOLUT_BODY_KEYS.length)
|
|
2245
|
+
return refuse16("revolut_body_unsupported");
|
|
2246
|
+
const code = cardMethod(value.payment_method);
|
|
2247
|
+
if (code !== null)
|
|
2248
|
+
return refuse16(code);
|
|
2249
|
+
if (!customer(value.customer) || !between(value.amount, 1, AMOUNT_LIMIT) || !REVOLUT_CHANNELS.includes(value.channel)) {
|
|
2250
|
+
return refuse16("revolut_body_unsupported");
|
|
2251
|
+
}
|
|
2252
|
+
return CARD15;
|
|
2253
|
+
}
|
|
2254
|
+
// src/sumup.js
|
|
2255
|
+
var SUMUP_PSP = "sumup";
|
|
2256
|
+
var SUMUP_API_HOST = "api.sumup.com";
|
|
2257
|
+
var SUMUP_CHECKOUT_PATH = "/v0.2/checkouts/";
|
|
2258
|
+
var BODY_LIMIT13 = 16384;
|
|
2259
|
+
var CHECKOUT_ID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-5][0-9a-f]{3}-[089ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
2260
|
+
var ROOT_KEYS5 = /* @__PURE__ */ Object.freeze([
|
|
2261
|
+
"payment_type",
|
|
2262
|
+
"device_information",
|
|
2263
|
+
"method_details",
|
|
2264
|
+
"personal_details",
|
|
2265
|
+
"card",
|
|
2266
|
+
"installments",
|
|
2267
|
+
"mandate",
|
|
2268
|
+
"lxn_session_token",
|
|
2269
|
+
"customer_details",
|
|
2270
|
+
"sca_experience"
|
|
2271
|
+
]);
|
|
2272
|
+
var CARD_KEYS7 = /* @__PURE__ */ Object.freeze(["zip_code", "name", "number", "expiry_month", "expiry_year", "cvv"]);
|
|
2273
|
+
var PERSONAL_KEYS = /* @__PURE__ */ Object.freeze(["first_name", "last_name", "email", "address", "birth_date", "phone"]);
|
|
2274
|
+
var ADDRESS_KEYS2 = /* @__PURE__ */ Object.freeze(["country", "city", "line1", "line2", "postal_code", "state"]);
|
|
2275
|
+
var CUSTOMER_KEYS = /* @__PURE__ */ Object.freeze(["first_name", "last_name", "email", "note_for_merchant"]);
|
|
2276
|
+
var CARD_NUMBER9 = /^[0-9]{12,19}$/;
|
|
2277
|
+
var MONTH7 = /^(?:0[1-9]|1[0-2])$/;
|
|
2278
|
+
var YEAR7 = /^(?:[0-9]{2}|[0-9]{4})$/;
|
|
2279
|
+
var CODE2 = /^[0-9]{3,4}$/;
|
|
2280
|
+
var BASE643 = /^[A-Za-z0-9+/]{4,4096}={0,2}$/;
|
|
2281
|
+
var BASE64_ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
2282
|
+
var DEVICE_KEYS2 = /* @__PURE__ */ Object.freeze([
|
|
2283
|
+
"user_agent",
|
|
2284
|
+
"language",
|
|
2285
|
+
"timezone_offset",
|
|
2286
|
+
"screen_width",
|
|
2287
|
+
"screen_height",
|
|
2288
|
+
"color_depth",
|
|
2289
|
+
"modal_width",
|
|
2290
|
+
"modal_height",
|
|
2291
|
+
"adblock",
|
|
2292
|
+
"realIp",
|
|
2293
|
+
"route"
|
|
2294
|
+
]);
|
|
2295
|
+
var RISK_TOKEN = /^[A-Za-z0-9_+/=-]+\.[A-Za-z0-9_+/=-]+\.[A-Za-z0-9_+/=-]*$/;
|
|
2296
|
+
var RISK_TOKEN_LIMIT = 4096;
|
|
2297
|
+
var PAN_LIKE4 = /(?:[0-9][ _.:-]*){12,}/;
|
|
2298
|
+
var DATE = /^[0-9]{4}-[0-9]{2}-[0-9]{2}$/;
|
|
2299
|
+
var COUNTRY2 = /^[A-Z]{2}$/;
|
|
2300
|
+
var PHONE2 = /^[ #0-9_+\/().-]{1,32}$/;
|
|
2301
|
+
var CARD_PAYMENT2 = "card";
|
|
2302
|
+
var SCA_EXPERIENCE = "iframe";
|
|
2303
|
+
var record11 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
2304
|
+
var refuse17 = (code) => Object.freeze({ verdict: "refuse", code });
|
|
2305
|
+
var CARD16 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
|
|
2306
|
+
function orderedSubset(value, keys) {
|
|
2307
|
+
let at = -1;
|
|
2308
|
+
for (const key of Object.keys(value)) {
|
|
2309
|
+
const next = keys.indexOf(key);
|
|
2310
|
+
if (next <= at)
|
|
2311
|
+
return false;
|
|
2312
|
+
at = next;
|
|
2313
|
+
}
|
|
2314
|
+
return true;
|
|
2315
|
+
}
|
|
2316
|
+
function luhn3(digits2) {
|
|
2317
|
+
let sum = 0;
|
|
2318
|
+
for (let at = 0; at < digits2.length; at += 1) {
|
|
2319
|
+
let digit = Number(digits2[digits2.length - 1 - at]);
|
|
2320
|
+
if (at % 2 === 1) {
|
|
2321
|
+
digit *= 2;
|
|
2322
|
+
if (digit > 9)
|
|
2323
|
+
digit -= 9;
|
|
2324
|
+
}
|
|
2325
|
+
sum += digit;
|
|
2326
|
+
}
|
|
2327
|
+
return sum % 10 === 0 && sum > 0;
|
|
2328
|
+
}
|
|
2329
|
+
var printable = (value) => [...value].every((ch) => ch.charCodeAt(0) >= 32 && ch.charCodeAt(0) !== 127);
|
|
2330
|
+
function typed(value, limit = 256) {
|
|
2331
|
+
return typeof value === "string" && value.length >= 1 && value.length <= limit && !PAN_LIKE4.test(value) && printable(value);
|
|
2332
|
+
}
|
|
2333
|
+
function decodeBase64(text4) {
|
|
2334
|
+
if (typeof text4 !== "string" || !BASE643.test(text4) || text4.length % 4 !== 0)
|
|
2335
|
+
return null;
|
|
2336
|
+
let bits = 0;
|
|
2337
|
+
let value = 0;
|
|
2338
|
+
let out = "";
|
|
2339
|
+
for (const ch of text4.replace(/=+$/, "")) {
|
|
2340
|
+
value = (value << 6 | BASE64_ALPHABET.indexOf(ch)) & 16777215;
|
|
2341
|
+
bits += 6;
|
|
2342
|
+
if (bits >= 8) {
|
|
2343
|
+
bits -= 8;
|
|
2344
|
+
out += String.fromCharCode(value >> bits & 255);
|
|
2345
|
+
}
|
|
2346
|
+
}
|
|
2347
|
+
return out;
|
|
2348
|
+
}
|
|
2349
|
+
function soundDevice(text4) {
|
|
2350
|
+
const json = decodeBase64(text4);
|
|
2351
|
+
if (json === null)
|
|
2352
|
+
return false;
|
|
2353
|
+
let value;
|
|
2354
|
+
try {
|
|
2355
|
+
value = JSON.parse(json);
|
|
2356
|
+
if (JSON.stringify(value) !== json)
|
|
2357
|
+
return false;
|
|
2358
|
+
}
|
|
2359
|
+
catch {
|
|
2360
|
+
return false;
|
|
2361
|
+
}
|
|
2362
|
+
if (!record11(value) || Object.keys(value).join() !== "deviceId,components" || typeof value.deviceId !== "string" || value.deviceId.length > 256 || PAN_LIKE4.test(value.deviceId) || !printable(value.deviceId) || !Array.isArray(value.components) || value.components.length !== DEVICE_KEYS2.length) {
|
|
2363
|
+
return false;
|
|
2364
|
+
}
|
|
2365
|
+
return value.components.every((component, at) => record11(component) && Object.keys(component).join() === "key,value" && component.key === DEVICE_KEYS2[at] && typeof component.value === "string" && component.value.length <= 1024 && !PAN_LIKE4.test(component.value) && printable(component.value));
|
|
2366
|
+
}
|
|
2367
|
+
var soundRiskToken = (token) => typeof token === "string" && token.length <= RISK_TOKEN_LIMIT && RISK_TOKEN.test(token) && !PAN_LIKE4.test(token);
|
|
2368
|
+
function sumupCheckoutUrl(url) {
|
|
2369
|
+
if (typeof url !== "string" || url.length > 256 || url.includes("#") || url.includes("?"))
|
|
2370
|
+
return null;
|
|
2371
|
+
let parsed;
|
|
2372
|
+
try {
|
|
2373
|
+
parsed = new URL(url);
|
|
2374
|
+
}
|
|
2375
|
+
catch {
|
|
2376
|
+
return null;
|
|
2377
|
+
}
|
|
2378
|
+
if (parsed.href !== url || parsed.protocol !== "https:" || parsed.port || parsed.username || parsed.password)
|
|
2379
|
+
return null;
|
|
2380
|
+
if (parsed.hostname !== SUMUP_API_HOST || !parsed.pathname.startsWith(SUMUP_CHECKOUT_PATH))
|
|
2381
|
+
return null;
|
|
2382
|
+
const checkoutId = parsed.pathname.slice(SUMUP_CHECKOUT_PATH.length);
|
|
2383
|
+
return CHECKOUT_ID.test(checkoutId) ? Object.freeze({ checkoutId }) : null;
|
|
2384
|
+
}
|
|
2385
|
+
function readBody8(body) {
|
|
2386
|
+
if (typeof body !== "string" || body === "" || body.length > BODY_LIMIT13)
|
|
2387
|
+
return null;
|
|
2388
|
+
let value;
|
|
2389
|
+
try {
|
|
2390
|
+
value = JSON.parse(body);
|
|
2391
|
+
if (!record11(value) || JSON.stringify(value) !== body)
|
|
2392
|
+
return null;
|
|
2393
|
+
}
|
|
2394
|
+
catch {
|
|
2395
|
+
return null;
|
|
2396
|
+
}
|
|
2397
|
+
return value;
|
|
2398
|
+
}
|
|
2399
|
+
function soundCard(card) {
|
|
2400
|
+
if (!record11(card) || !orderedSubset(card, CARD_KEYS7))
|
|
2401
|
+
return false;
|
|
2402
|
+
if (typeof card.number !== "string" || !CARD_NUMBER9.test(card.number) || !luhn3(card.number))
|
|
2403
|
+
return false;
|
|
2404
|
+
if (typeof card.expiry_month !== "string" || !MONTH7.test(card.expiry_month))
|
|
2405
|
+
return false;
|
|
2406
|
+
if (typeof card.expiry_year !== "string" || !YEAR7.test(card.expiry_year))
|
|
2407
|
+
return false;
|
|
2408
|
+
if (typeof card.cvv !== "string" || !CODE2.test(card.cvv))
|
|
2409
|
+
return false;
|
|
2410
|
+
if (card.name !== void 0 && (!typed(card.name, 129) || /[0-9]/.test(card.name)))
|
|
2411
|
+
return false;
|
|
2412
|
+
if (card.zip_code !== void 0 && !typed(card.zip_code, 10))
|
|
2413
|
+
return false;
|
|
2414
|
+
return true;
|
|
2415
|
+
}
|
|
2416
|
+
function soundPersonal(details) {
|
|
2417
|
+
if (!record11(details) || !orderedSubset(details, PERSONAL_KEYS) || Object.keys(details).length === 0)
|
|
2418
|
+
return false;
|
|
2419
|
+
for (const key of ["first_name", "last_name", "email"]) {
|
|
2420
|
+
if (details[key] !== void 0 && !typed(details[key]))
|
|
2421
|
+
return false;
|
|
2422
|
+
}
|
|
2423
|
+
if (details.birth_date !== void 0 && (typeof details.birth_date !== "string" || !DATE.test(details.birth_date)))
|
|
2424
|
+
return false;
|
|
2425
|
+
if (details.phone !== void 0 && (typeof details.phone !== "string" || !PHONE2.test(details.phone) || (details.phone.match(/[0-9]/g) ?? []).length > 15))
|
|
2426
|
+
return false;
|
|
2427
|
+
if (details.address === void 0)
|
|
2428
|
+
return true;
|
|
2429
|
+
const address2 = details.address;
|
|
2430
|
+
if (!record11(address2) || !orderedSubset(address2, ADDRESS_KEYS2) || Object.keys(address2).length === 0)
|
|
2431
|
+
return false;
|
|
2432
|
+
if (address2.country !== void 0 && (typeof address2.country !== "string" || !COUNTRY2.test(address2.country)))
|
|
2433
|
+
return false;
|
|
2434
|
+
return ["city", "line1", "line2", "postal_code", "state"].every((key) => address2[key] === void 0 || typed(address2[key]));
|
|
2435
|
+
}
|
|
2436
|
+
function soundCustomer(details) {
|
|
2437
|
+
if (!record11(details) || !orderedSubset(details, CUSTOMER_KEYS) || Object.keys(details).length === 0)
|
|
2438
|
+
return false;
|
|
2439
|
+
return CUSTOMER_KEYS.every((key) => details[key] === void 0 || typed(details[key], key === "note_for_merchant" ? 1024 : 256));
|
|
2440
|
+
}
|
|
2441
|
+
function sumupBodyVerdict(body, url) {
|
|
2442
|
+
if (url !== void 0 && sumupCheckoutUrl(url) === null)
|
|
2443
|
+
return refuse17("sumup_url_refused");
|
|
2444
|
+
const value = readBody8(body);
|
|
2445
|
+
if (value === null || !orderedSubset(value, ROOT_KEYS5))
|
|
2446
|
+
return refuse17("sumup_body_unsupported");
|
|
2447
|
+
if (value.payment_type !== CARD_PAYMENT2 || !soundDevice(value.device_information) || !soundCard(value.card) || value.installments !== 1) {
|
|
2448
|
+
return refuse17("sumup_body_unsupported");
|
|
2449
|
+
}
|
|
2450
|
+
if (value.method_details !== void 0 && !(record11(value.method_details) && orderedSubset(value.method_details, ["zip_code"]) && typed(value.method_details.zip_code, 10)))
|
|
2451
|
+
return refuse17("sumup_body_unsupported");
|
|
2452
|
+
if (value.personal_details !== void 0 && !soundPersonal(value.personal_details))
|
|
2453
|
+
return refuse17("sumup_body_unsupported");
|
|
2454
|
+
if (value.customer_details !== void 0 && !soundCustomer(value.customer_details))
|
|
2455
|
+
return refuse17("sumup_body_unsupported");
|
|
2456
|
+
if (value.lxn_session_token !== void 0 && !soundRiskToken(value.lxn_session_token))
|
|
2457
|
+
return refuse17("sumup_body_unsupported");
|
|
2458
|
+
if (value.sca_experience !== void 0 && value.sca_experience !== SCA_EXPERIENCE)
|
|
2459
|
+
return refuse17("sumup_body_unsupported");
|
|
2460
|
+
if (value.mandate !== void 0)
|
|
2461
|
+
return refuse17("sumup_card_saving_refused");
|
|
2462
|
+
return CARD16;
|
|
2463
|
+
}
|
|
2464
|
+
// src/twoc2p-secure-pay.js
|
|
2465
|
+
var SALTED = /* @__PURE__ */ Object.freeze([83, 97, 108, 116, 101, 100, 95, 95]);
|
|
2466
|
+
var B64 = /^[A-Za-z0-9+/]+={0,2}$/;
|
|
2467
|
+
var FIELD_LIMIT = 1024;
|
|
2468
|
+
function decodeCanonical(text4) {
|
|
2469
|
+
if (typeof text4 !== "string" || text4.length === 0 || text4.length % 4 !== 0 || !B64.test(text4))
|
|
2470
|
+
return null;
|
|
2471
|
+
let binary;
|
|
2472
|
+
try {
|
|
2473
|
+
binary = atob(text4);
|
|
2474
|
+
}
|
|
2475
|
+
catch {
|
|
2476
|
+
return null;
|
|
2477
|
+
}
|
|
2478
|
+
if (btoa(binary) !== text4)
|
|
2479
|
+
return null;
|
|
2480
|
+
return Uint8Array.from(binary, (char) => char.charCodeAt(0));
|
|
2481
|
+
}
|
|
2482
|
+
function twoC2pSecurePayParts(value) {
|
|
2483
|
+
if (typeof value !== "string" || value.length > FIELD_LIMIT || !/^[0-9a-f]{4}/.test(value))
|
|
2484
|
+
return null;
|
|
2485
|
+
const length = parseInt(value.slice(0, 4), 16);
|
|
2486
|
+
if (length < 4 || 4 + length >= value.length)
|
|
2487
|
+
return null;
|
|
2488
|
+
const rsaText = value.slice(4, 4 + length);
|
|
2489
|
+
const rsa = decodeCanonical(rsaText);
|
|
2490
|
+
const cipher = decodeCanonical(value.slice(4 + length));
|
|
2491
|
+
if (!rsa || !cipher || cipher.length < 32 || cipher.length > 80 || cipher.length % 16 !== 0)
|
|
2492
|
+
return null;
|
|
2493
|
+
if (!SALTED.every((byte, at) => cipher[at] === byte))
|
|
2494
|
+
return null;
|
|
2495
|
+
return { rsaText, rsa, salt: cipher.slice(8, 16), blocks: (cipher.length - 16) / 16 };
|
|
2496
|
+
}
|
|
2497
|
+
function isTwoC2pPageField(value, keyBytes) {
|
|
2498
|
+
const parts = twoC2pSecurePayParts(value);
|
|
2499
|
+
if (!parts || !Number.isInteger(keyBytes) || keyBytes < 128)
|
|
2500
|
+
return false;
|
|
2501
|
+
const expected = Math.ceil(keyBytes / 3) * 4;
|
|
2502
|
+
return parts.rsaText.length === expected && (parts.rsa.length === keyBytes || parts.rsa.length === keyBytes - 1);
|
|
2503
|
+
}
|
|
2504
|
+
// src/twoc2p-keys.js
|
|
2505
|
+
var TWOC2P_KEYS = /* @__PURE__ */ Object.freeze({
|
|
2506
|
+
production: Object.freeze({
|
|
2507
|
+
spki: "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC/1ljsxI+r6qQraTFrHfWNrV41vxumBF+4ILAG3WsN6HEBQU2wSUv/IyQmZkiys1ilOb+OOuQTH8OXMnqQg9E4epyePW3L7IeOieSbIIDeSX6UpTWmT/Fs7moWZkN8RpuCV0u87n3AY2tQbtcSqwEKi2sxzWLFwscoGn6N5yVIpQIDAQAB",
|
|
2508
|
+
sha256: "bb8f27929ce140c6ef0ec9c4a20d7ca0b83376bc35a501985dc40d16669384fe",
|
|
2509
|
+
script: Object.freeze({ url: "https://t.2c2p.com/SecurePayment/api/my2c2p.1.7.6.min.js", sha256: "4a745a37765a2e28e299d64f6ea5811aab27b176da61db6f840fa85d6a47e763" })
|
|
2510
|
+
}),
|
|
2511
|
+
sandbox: Object.freeze({
|
|
2512
|
+
spki: "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDKakJC+2MSZikKoPzlNqXvJCuWNLhejg3gMRePSetYNNgnhyqFwwAR7t7i/B2QFZoixSYc2/23cJz0jA5O+q+Cu3fycqKlf1L9966+X3B9nyHe2eKQZr8KrcS/8+sEKcd0pLATY4AleW1iktuN+2oghrDKuv+aDNztWcOy+PTofwIDAQAB",
|
|
2513
|
+
sha256: "7f80c07f1d72db28ede10dae942940657c72dfa789836c9fdf283cba6feff2e6",
|
|
2514
|
+
script: Object.freeze({ url: "https://demo2.2c2p.com/2C2PFrontEnd/SecurePayment/api/my2c2p.1.7.6.min.js", sha256: "435723d92bfefb00607a56851967e0b745d52b8d49443de5f0000f0583fde5cc" })
|
|
2515
|
+
})
|
|
2516
|
+
});
|
|
2517
|
+
function twoC2pKey(environment2) {
|
|
2518
|
+
if (environment2 !== "production" && environment2 !== "sandbox")
|
|
2519
|
+
return null;
|
|
2520
|
+
return TWOC2P_KEYS[environment2] ?? null;
|
|
2521
|
+
}
|
|
2522
|
+
function twoC2pKeyBytes(environment2) {
|
|
2523
|
+
const key = twoC2pKey(environment2);
|
|
2524
|
+
if (!key)
|
|
2525
|
+
return null;
|
|
2526
|
+
try {
|
|
2527
|
+
return parseRsaPublicKey(key).size;
|
|
2528
|
+
}
|
|
2529
|
+
catch {
|
|
2530
|
+
return null;
|
|
2531
|
+
}
|
|
2532
|
+
}
|
|
2533
|
+
// src/twoc2p.js
|
|
2534
|
+
var TWOC2P_PSP = "twoc2p";
|
|
2535
|
+
var TWOC2P_FIELD = "securePayToken";
|
|
2536
|
+
var TWOC2P_REVIEWED_BUILDS = /* @__PURE__ */ Object.freeze(["4.1", "4.2", "4.3", "4.4", "4.5"]);
|
|
2537
|
+
var record12 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
2538
|
+
var refuse18 = (code) => Object.freeze({ verdict: "refuse", code });
|
|
2539
|
+
var CARD17 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
|
|
2540
|
+
var CONTINUE8 = /* @__PURE__ */ Object.freeze({ verdict: "continue" });
|
|
2541
|
+
var PAYMENT_URL = /^https:\/\/(sandbox-)?pgwv4\.2c2p\.com\/payment\/(4\.[0-9]{1,2})\/Payment$/;
|
|
2542
|
+
function twoC2pPaymentTarget(url) {
|
|
2543
|
+
const match = typeof url === "string" ? PAYMENT_URL.exec(url) : null;
|
|
2544
|
+
if (!match)
|
|
2545
|
+
return null;
|
|
2546
|
+
return Object.freeze({ environment: match[1] ? "sandbox" : "production", version: match[2], reviewed: TWOC2P_REVIEWED_BUILDS.includes(match[2]) });
|
|
2547
|
+
}
|
|
2548
|
+
function twoC2pPaymentCarriesCard(body) {
|
|
2549
|
+
if (typeof body !== "string")
|
|
2550
|
+
return true;
|
|
2551
|
+
try {
|
|
2552
|
+
return JSON.stringify(JSON.parse(body)).includes(`"${TWOC2P_FIELD}"`);
|
|
2553
|
+
}
|
|
2554
|
+
catch {
|
|
2555
|
+
return true;
|
|
2556
|
+
}
|
|
2557
|
+
}
|
|
2558
|
+
var ROOT_KEYS6 = /* @__PURE__ */ Object.freeze(["paymentToken", "clientIP", "locale", "responseReturnUrl", "clientID", "payment"]);
|
|
2559
|
+
var CODE_KEYS = /* @__PURE__ */ Object.freeze(["channelCode", "agentCode", "agentChannelCode"]);
|
|
2560
|
+
var DATA_KEYS2 = /* @__PURE__ */ Object.freeze([
|
|
2561
|
+
"name",
|
|
2562
|
+
"isIppChosen",
|
|
2563
|
+
"cardDetails",
|
|
2564
|
+
"loyaltyPoints",
|
|
2565
|
+
"fxRateID",
|
|
2566
|
+
"email",
|
|
2567
|
+
"mobileNo",
|
|
2568
|
+
"mobileNoPrefix",
|
|
2569
|
+
"customerNote",
|
|
2570
|
+
"paymentExpiry",
|
|
2571
|
+
"securePayToken",
|
|
2572
|
+
"cardTokenize",
|
|
2573
|
+
"accountTokenization",
|
|
2574
|
+
"token",
|
|
2575
|
+
"customerToken",
|
|
2576
|
+
"accountNo",
|
|
2577
|
+
"installmentPeriod",
|
|
2578
|
+
"interestType",
|
|
2579
|
+
"payLaterPeriod",
|
|
2580
|
+
"billingAddress1",
|
|
2581
|
+
"billingAddress2",
|
|
2582
|
+
"billingCity",
|
|
2583
|
+
"billingState",
|
|
2584
|
+
"billingCountryCode",
|
|
2585
|
+
"billingPostalCode",
|
|
2586
|
+
"riskInfo"
|
|
2587
|
+
]);
|
|
2588
|
+
var RISK_KEYS = /* @__PURE__ */ Object.freeze(["customer_id", "shipping_method", "deviceSessionId", "customData"]);
|
|
2589
|
+
var BODY_LIMIT14 = 16384;
|
|
2590
|
+
var CONTROL6 = /[\u0000-\u001f\u007f]/;
|
|
2591
|
+
var CARD_LIKE = /(?:[0-9][ _.:/-]*){12,}/;
|
|
2592
|
+
var PAYMENT_TOKEN = /^[A-Za-z0-9+/]{16,1000}={0,2}$/;
|
|
2593
|
+
var UUID2 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
2594
|
+
var IP = /^[0-9A-Fa-f.:]{2,45}$/;
|
|
2595
|
+
var LOCALE2 = /^[A-Za-z]{2,3}(?:[-_][A-Za-z0-9]{2,8})?$/;
|
|
2596
|
+
var AGENT = /^[A-Za-z0-9_]{1,32}$/;
|
|
2597
|
+
var RISK_TOKEN2 = /^[\x21-\x7e]{1,512}$/;
|
|
2598
|
+
var RETURN_URL = /^https:\/\/((?:sandbox-)?pgw-ui\.2c2p\.com)\/payment\/4\.[0-9]{1,2}(?:\/|\/index\.html)?#\/(?:info|mobile\/process)\/([A-Za-z0-9+/]{16,1000}={0,2})?$/;
|
|
2599
|
+
var PAGE_HOSTS = /* @__PURE__ */ Object.freeze({ production: "pgw-ui.2c2p.com", sandbox: "sandbox-pgw-ui.2c2p.com" });
|
|
2600
|
+
var returnUrlTaken = (value, paymentToken, environment2) => {
|
|
2601
|
+
if (value === void 0)
|
|
2602
|
+
return true;
|
|
2603
|
+
const match = typeof value === "string" ? RETURN_URL.exec(value) : null;
|
|
2604
|
+
return !!match && (match[2] === void 0 || match[2] === paymentToken) && (environment2 === void 0 || match[1] === PAGE_HOSTS[environment2]);
|
|
2605
|
+
};
|
|
2606
|
+
var inOrder2 = (value, order) => {
|
|
2607
|
+
let at = -1;
|
|
2608
|
+
for (const key of Object.keys(value)) {
|
|
2609
|
+
const next = order.indexOf(key);
|
|
2610
|
+
if (next <= at)
|
|
2611
|
+
return false;
|
|
2612
|
+
at = next;
|
|
2613
|
+
}
|
|
2614
|
+
return true;
|
|
2615
|
+
};
|
|
2616
|
+
var text2 = (value, limit) => typeof value === "string" && value.length <= limit && !CONTROL6.test(value) && !CARD_LIKE.test(value);
|
|
2617
|
+
var optionalText = (value, limit) => value === void 0 || text2(value, limit);
|
|
2618
|
+
function twoC2pBodyVerdict(body, keyBytes = 128, environment2 = void 0) {
|
|
2619
|
+
if (!twoC2pPaymentCarriesCard(body))
|
|
2620
|
+
return CONTINUE8;
|
|
2621
|
+
if (typeof body !== "string" || body.length > BODY_LIMIT14)
|
|
2622
|
+
return refuse18("twoc2p_body_unsupported");
|
|
2623
|
+
let value;
|
|
2624
|
+
try {
|
|
2625
|
+
value = JSON.parse(body);
|
|
2626
|
+
}
|
|
2627
|
+
catch {
|
|
2628
|
+
return refuse18("twoc2p_body_unsupported");
|
|
2629
|
+
}
|
|
2630
|
+
if (!record12(value) || JSON.stringify(value) !== body || !inOrder2(value, ROOT_KEYS6))
|
|
2631
|
+
return refuse18("twoc2p_body_unsupported");
|
|
2632
|
+
if (typeof value.paymentToken !== "string" || !PAYMENT_TOKEN.test(value.paymentToken) || value.clientIP !== void 0 && !(typeof value.clientIP === "string" && IP.test(value.clientIP)) || value.locale !== void 0 && !(typeof value.locale === "string" && LOCALE2.test(value.locale)) || !returnUrlTaken(value.responseReturnUrl, value.paymentToken, environment2) || value.clientID !== void 0 && !(typeof value.clientID === "string" && UUID2.test(value.clientID)))
|
|
2633
|
+
return refuse18("twoc2p_body_unsupported");
|
|
2634
|
+
const payment = value.payment;
|
|
2635
|
+
if (!record12(payment) || Object.keys(payment).join(",") !== "code,data")
|
|
2636
|
+
return refuse18("twoc2p_body_unsupported");
|
|
2637
|
+
const code = payment.code;
|
|
2638
|
+
const data = payment.data;
|
|
2639
|
+
if (!record12(code) || !record12(data))
|
|
2640
|
+
return refuse18("twoc2p_body_unsupported");
|
|
2641
|
+
if (Object.prototype.hasOwnProperty.call(code, "subChannelCode"))
|
|
2642
|
+
return refuse18("twoc2p_stored_card");
|
|
2643
|
+
if (code.channelCode === "IPP" || code.channelCode === "LIPP")
|
|
2644
|
+
return refuse18("twoc2p_installments");
|
|
2645
|
+
if (!inOrder2(code, CODE_KEYS) || code.channelCode === void 0)
|
|
2646
|
+
return refuse18("twoc2p_body_unsupported");
|
|
2647
|
+
if (code.channelCode !== "CC")
|
|
2648
|
+
return refuse18("twoc2p_channel_unsupported");
|
|
2649
|
+
if ([code.agentCode, code.agentChannelCode].some((part) => part !== void 0 && !(typeof part === "string" && AGENT.test(part))))
|
|
2650
|
+
return refuse18("twoc2p_body_unsupported");
|
|
2651
|
+
return dataVerdict(data, keyBytes, body);
|
|
2652
|
+
}
|
|
2653
|
+
function dataVerdict(data, keyBytes, body) {
|
|
2654
|
+
if (data.cardTokenize !== void 0 || data.accountTokenization !== void 0)
|
|
2655
|
+
return refuse18("twoc2p_keeps_card");
|
|
2656
|
+
if (data.token !== void 0 || data.customerToken !== void 0)
|
|
2657
|
+
return refuse18("twoc2p_stored_card");
|
|
2658
|
+
if (data.accountNo !== void 0)
|
|
2659
|
+
return refuse18("twoc2p_card_in_clear");
|
|
2660
|
+
const details = data.cardDetails;
|
|
2661
|
+
if (record12(details) && (details.cardNo !== void 0 || details.accountNo !== void 0))
|
|
2662
|
+
return refuse18("twoc2p_card_in_clear");
|
|
2663
|
+
if (record12(details) && Object.keys(details).some((key) => key !== "email"))
|
|
2664
|
+
return refuse18("twoc2p_stored_card");
|
|
2665
|
+
if (data.isIppChosen === true || data.installmentPeriod !== void 0 || data.interestType !== void 0 || data.payLaterPeriod !== void 0) {
|
|
2666
|
+
return refuse18("twoc2p_installments");
|
|
2667
|
+
}
|
|
2668
|
+
if (data.fxRateID !== void 0)
|
|
2669
|
+
return refuse18("twoc2p_currency_conversion");
|
|
2670
|
+
if (data.loyaltyPoints !== void 0 && !(Array.isArray(data.loyaltyPoints) && data.loyaltyPoints.length === 0)) {
|
|
2671
|
+
return refuse18("twoc2p_loyalty_redemption");
|
|
2672
|
+
}
|
|
2673
|
+
if (!inOrder2(data, DATA_KEYS2) || data.paymentExpiry !== void 0)
|
|
2674
|
+
return refuse18("twoc2p_body_unsupported");
|
|
2675
|
+
if (typeof data.securePayToken !== "string" || !isTwoC2pPageField(data.securePayToken, keyBytes))
|
|
2676
|
+
return refuse18("twoc2p_field_unreviewed");
|
|
2677
|
+
if (body.split(data.securePayToken).length !== 2)
|
|
2678
|
+
return refuse18("twoc2p_body_unsupported");
|
|
2679
|
+
if (data.isIppChosen !== void 0 && data.isIppChosen !== false)
|
|
2680
|
+
return refuse18("twoc2p_body_unsupported");
|
|
2681
|
+
if (details !== void 0 && !(record12(details) && (details.email === void 0 || text2(details.email, 254))))
|
|
2682
|
+
return refuse18("twoc2p_body_unsupported");
|
|
2683
|
+
if (!optionalText(data.name, 128) || !optionalText(data.email, 254) || !optionalText(data.customerNote, 255) || !(data.mobileNo === void 0 || typeof data.mobileNo === "string" && /^[0-9]{4,11}$/.test(data.mobileNo)) || !(data.mobileNoPrefix === void 0 || typeof data.mobileNoPrefix === "string" && /^\+?[0-9]{1,4}$/.test(data.mobileNoPrefix))) {
|
|
2684
|
+
return refuse18("twoc2p_body_unsupported");
|
|
2685
|
+
}
|
|
2686
|
+
for (const key of ["billingAddress1", "billingAddress2", "billingCity", "billingState", "billingPostalCode"]) {
|
|
2687
|
+
if (!optionalText(data[key], 128))
|
|
2688
|
+
return refuse18("twoc2p_body_unsupported");
|
|
2689
|
+
}
|
|
2690
|
+
if (data.billingCountryCode !== void 0 && !(typeof data.billingCountryCode === "string" && /^[A-Za-z]{2}$/.test(data.billingCountryCode))) {
|
|
2691
|
+
return refuse18("twoc2p_body_unsupported");
|
|
2692
|
+
}
|
|
2693
|
+
const risk = data.riskInfo;
|
|
2694
|
+
if (risk !== void 0 && risk !== null && !(record12(risk) && Object.keys(risk).join(",") === RISK_KEYS.join(",") && risk.customer_id === "" && risk.shipping_method === "" && typeof risk.deviceSessionId === "string" && RISK_TOKEN2.test(risk.deviceSessionId) && record12(risk.customData) && Object.keys(risk.customData).length === 0)) {
|
|
2695
|
+
return refuse18("twoc2p_body_unsupported");
|
|
2696
|
+
}
|
|
2697
|
+
return CARD17;
|
|
2698
|
+
}
|
|
2699
|
+
// src/hipay.js
|
|
2700
|
+
var HIPAY_PSP = "hipay";
|
|
2701
|
+
var HIPAY_TOKEN_URLS = /* @__PURE__ */ Object.freeze({
|
|
2702
|
+
production: "https://secure2-vault.hipay-tpp.com/rest/v2/token",
|
|
2703
|
+
sandbox: "https://stage-secure2-vault.hipay-tpp.com/rest/v2/token"
|
|
2704
|
+
});
|
|
2705
|
+
var BODY_LIMIT15 = 2048;
|
|
2706
|
+
var HOSTED_KEYS = /* @__PURE__ */ Object.freeze(["multi_use", "card_expiry_month", "card_expiry_year", "card_number", "card_holder", "cvc"]);
|
|
2707
|
+
var HOSTED_KEYS_NO_HOLDER = /* @__PURE__ */ Object.freeze(["multi_use", "card_expiry_month", "card_expiry_year", "card_number", "cvc"]);
|
|
2708
|
+
var DIRECT_KEYS = /* @__PURE__ */ Object.freeze(["card_expiry_month", "card_expiry_year", "card_number", "card_holder", "cvc", "multi_use"]);
|
|
2709
|
+
var DIRECT_KEYS_NO_HOLDER = /* @__PURE__ */ Object.freeze(["card_expiry_month", "card_expiry_year", "card_number", "cvc", "multi_use"]);
|
|
2710
|
+
var CARD_SHAPES = /* @__PURE__ */ Object.freeze([HOSTED_KEYS, HOSTED_KEYS_NO_HOLDER, DIRECT_KEYS, DIRECT_KEYS_NO_HOLDER]);
|
|
2711
|
+
var NUMBER_ONLY_KEYS = /* @__PURE__ */ Object.freeze(["multi_use", "card_expiry_month", "card_expiry_year", "card_number"]);
|
|
2712
|
+
var CARD_NUMBER10 = /^[0-9]{12,19}$/;
|
|
2713
|
+
var SECURITY_CODE12 = /^[0-9]{3,4}$/;
|
|
2714
|
+
var MONTH8 = /^(?:0[1-9]|1[0-2])$/;
|
|
2715
|
+
var YEAR8 = /^20[0-9]{2}$/;
|
|
2716
|
+
var TEXT_LIMIT3 = 256;
|
|
2717
|
+
var CONTROL7 = /[\u0000-\u001f\u007f]/;
|
|
2718
|
+
var record13 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
2719
|
+
var sameKeys7 = (value, keys) => {
|
|
2720
|
+
const own3 = Object.keys(value);
|
|
2721
|
+
return own3.length === keys.length && own3.every((key, at) => key === keys[at]);
|
|
2722
|
+
};
|
|
2723
|
+
var plainText3 = (value) => typeof value === "string" && value.length <= TEXT_LIMIT3 && !CONTROL7.test(value) && (value.match(/[0-9]/g) ?? []).length < 12;
|
|
2724
|
+
var refuse19 = (code) => Object.freeze({ verdict: "refuse", code });
|
|
2725
|
+
var CARD18 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
|
|
2726
|
+
function hipayTokenEnvironment(url) {
|
|
2727
|
+
if (url === HIPAY_TOKEN_URLS.production)
|
|
2728
|
+
return "production";
|
|
2729
|
+
if (url === HIPAY_TOKEN_URLS.sandbox)
|
|
2730
|
+
return "sandbox";
|
|
2731
|
+
return null;
|
|
2732
|
+
}
|
|
2733
|
+
function isHipayTokenUrl(url) {
|
|
2734
|
+
return hipayTokenEnvironment(url) !== null;
|
|
2735
|
+
}
|
|
2736
|
+
function readBody9(body) {
|
|
2737
|
+
if (typeof body !== "string" || body === "" || body.length > BODY_LIMIT15)
|
|
2738
|
+
return null;
|
|
2739
|
+
let value;
|
|
2740
|
+
try {
|
|
2741
|
+
value = JSON.parse(body);
|
|
2742
|
+
if (!record13(value) || JSON.stringify(value) !== body)
|
|
2743
|
+
return null;
|
|
2744
|
+
}
|
|
2745
|
+
catch {
|
|
2746
|
+
return null;
|
|
2747
|
+
}
|
|
2748
|
+
return value;
|
|
2749
|
+
}
|
|
2750
|
+
function hipayBodyVerdict(body) {
|
|
2751
|
+
const value = readBody9(body);
|
|
2752
|
+
if (value === null)
|
|
2753
|
+
return refuse19("hipay_body_unsupported");
|
|
2754
|
+
if (sameKeys7(value, NUMBER_ONLY_KEYS))
|
|
2755
|
+
return refuse19("hipay_number_only");
|
|
2756
|
+
if (!CARD_SHAPES.some((keys) => sameKeys7(value, keys)))
|
|
2757
|
+
return refuse19("hipay_body_unsupported");
|
|
2758
|
+
if (typeof value.card_number !== "string" || !CARD_NUMBER10.test(value.card_number) || typeof value.cvc !== "string" || !SECURITY_CODE12.test(value.cvc) || typeof value.card_expiry_month !== "string" || !MONTH8.test(value.card_expiry_month) || typeof value.card_expiry_year !== "string" || !YEAR8.test(value.card_expiry_year) || "card_holder" in value && !plainText3(value.card_holder)) {
|
|
2759
|
+
return refuse19("hipay_body_unsupported");
|
|
2760
|
+
}
|
|
2761
|
+
if (value.multi_use === 1)
|
|
2762
|
+
return refuse19("hipay_keeps_card");
|
|
2763
|
+
return value.multi_use === 0 ? CARD18 : refuse19("hipay_body_unsupported");
|
|
2764
|
+
}
|
|
2765
|
+
// src/amazon-payment-services.js
|
|
2766
|
+
var APS_PSP = "amazon_payment_services";
|
|
2767
|
+
var APS_HOSTS = /* @__PURE__ */ Object.freeze({ "checkout.payfort.com": "production", "sbcheckout.payfort.com": "sandbox" });
|
|
2768
|
+
var APS_TOKENIZATION_PATH = "/FortAPI/paymentPage";
|
|
2769
|
+
var APS_SIGNED_FIELDS = /* @__PURE__ */ Object.freeze([
|
|
2770
|
+
"service_command",
|
|
2771
|
+
"access_code",
|
|
2772
|
+
"merchant_identifier",
|
|
2773
|
+
"merchant_reference",
|
|
2774
|
+
"language",
|
|
2775
|
+
"return_url",
|
|
2776
|
+
"signature"
|
|
2777
|
+
]);
|
|
2778
|
+
var APS_CARD_FIELDS = /* @__PURE__ */ Object.freeze(["card_number", "expiry_date", "card_security_code"]);
|
|
2779
|
+
var APS_OPTIONAL_FIELDS = /* @__PURE__ */ Object.freeze(["card_holder_name", "remember_me"]);
|
|
2780
|
+
var URL_LIMIT7 = 2048;
|
|
2781
|
+
var BODY_LIMIT16 = 32 * 1024;
|
|
2782
|
+
var exact = (pattern, value) => typeof value === "string" && pattern.exec(value)?.[0] === value;
|
|
2783
|
+
var controlFree = (value, max) => typeof value === "string" && value.length <= max && !/[\u0000-\u001f\u007f]/.test(value);
|
|
2784
|
+
var SHAPES = /* @__PURE__ */ new Map([
|
|
2785
|
+
["service_command", (v) => v === "TOKENIZATION"],
|
|
2786
|
+
["access_code", (v) => exact(/^[A-Za-z0-9]{1,20}$/, v)],
|
|
2787
|
+
["merchant_identifier", (v) => exact(/^[A-Za-z0-9]{1,20}$/, v)],
|
|
2788
|
+
["merchant_reference", (v) => exact(/^[A-Za-z0-9._-]{1,40}$/, v)],
|
|
2789
|
+
["language", (v) => v === "en" || v === "ar"],
|
|
2790
|
+
// Hex SHA-256 (APS's default), SHA-512, or the 40 characters of the SHA-1 APS calls SHA-128.
|
|
2791
|
+
["signature", (v) => exact(/^(?:[0-9A-Fa-f]{40}|[0-9A-Fa-f]{64}|[0-9A-Fa-f]{128})$/, v)],
|
|
2792
|
+
["card_number", (v) => exact(/^[0-9]{12,19}$/, v)],
|
|
2793
|
+
["expiry_date", (v) => exact(/^[0-9]{2}(?:0[1-9]|1[0-2])$/, v)],
|
|
2794
|
+
["card_security_code", (v) => exact(/^[0-9]{3,4}$/, v)],
|
|
2795
|
+
["card_holder_name", (v) => controlFree(v, 255)],
|
|
2796
|
+
["remember_me", (v) => v === "YES" || v === "NO"]
|
|
2797
|
+
]);
|
|
2798
|
+
function apsTokenizationUrl(url) {
|
|
2799
|
+
if (typeof url !== "string" || url.length > URL_LIMIT7 || url.includes("?") || url.includes("#"))
|
|
2800
|
+
return null;
|
|
2801
|
+
let parsed;
|
|
2802
|
+
try {
|
|
2803
|
+
parsed = new URL(url);
|
|
2804
|
+
}
|
|
2805
|
+
catch {
|
|
2806
|
+
return null;
|
|
2807
|
+
}
|
|
2808
|
+
if (parsed.href !== url || parsed.protocol !== "https:" || parsed.port || parsed.username || parsed.password || parsed.pathname !== APS_TOKENIZATION_PATH || !Object.prototype.hasOwnProperty.call(APS_HOSTS, parsed.hostname))
|
|
2809
|
+
return null;
|
|
2810
|
+
return Object.freeze({ host: parsed.hostname, environment: APS_HOSTS[parsed.hostname] });
|
|
2811
|
+
}
|
|
2812
|
+
function formEncode2(value) {
|
|
2813
|
+
let encoded;
|
|
2814
|
+
try {
|
|
2815
|
+
encoded = encodeURIComponent(value);
|
|
2816
|
+
}
|
|
2817
|
+
catch {
|
|
2818
|
+
return null;
|
|
2819
|
+
}
|
|
2820
|
+
return encoded.replace(/[!'()~]/g, (ch) => `%${ch.charCodeAt(0).toString(16).toUpperCase()}`).replace(/%20/g, "+");
|
|
2821
|
+
}
|
|
2822
|
+
function formDecode(raw) {
|
|
2823
|
+
if (!/^(?:[A-Za-z0-9*._+-]|%[0-9A-F]{2})*$/.test(raw))
|
|
2824
|
+
return null;
|
|
2825
|
+
let value;
|
|
2826
|
+
try {
|
|
2827
|
+
value = decodeURIComponent(raw.replace(/\+/g, "%20"));
|
|
2828
|
+
}
|
|
2829
|
+
catch {
|
|
2830
|
+
return null;
|
|
2831
|
+
}
|
|
2832
|
+
return formEncode2(value) === raw ? value : null;
|
|
2833
|
+
}
|
|
2834
|
+
function parseForm(body) {
|
|
2835
|
+
if (typeof body !== "string" || body === "" || body.length > BODY_LIMIT16)
|
|
2836
|
+
return null;
|
|
2837
|
+
const pairs = [];
|
|
2838
|
+
const values = /* @__PURE__ */ new Map();
|
|
2839
|
+
for (const chunk of body.split("&")) {
|
|
2840
|
+
const separator = chunk.indexOf("=");
|
|
2841
|
+
if (separator < 1)
|
|
2842
|
+
return null;
|
|
2843
|
+
const rawName = chunk.slice(0, separator), raw = chunk.slice(separator + 1);
|
|
2844
|
+
const name = formDecode(rawName), value = formDecode(raw);
|
|
2845
|
+
if (name === null || value === null || values.has(name))
|
|
2846
|
+
return null;
|
|
2847
|
+
pairs.push({ name, rawName, raw, value });
|
|
2848
|
+
values.set(name, value);
|
|
2849
|
+
}
|
|
2850
|
+
return { pairs, values };
|
|
2851
|
+
}
|
|
2852
|
+
function returnUrlAdmitted(value) {
|
|
2853
|
+
if (typeof value !== "string" || value.length > 400 || value.includes("#") || /[\u0000- \u007f]/.test(value))
|
|
2854
|
+
return false;
|
|
2855
|
+
let parsed;
|
|
2856
|
+
try {
|
|
2857
|
+
parsed = new URL(value);
|
|
2858
|
+
}
|
|
2859
|
+
catch {
|
|
2860
|
+
return false;
|
|
2861
|
+
}
|
|
2862
|
+
return parsed.protocol === "https:" && !parsed.username && !parsed.password && parsed.href === value;
|
|
2863
|
+
}
|
|
2864
|
+
function apsBodyRefusal(body) {
|
|
2865
|
+
const form = parseForm(body);
|
|
2866
|
+
if (!form)
|
|
2867
|
+
return "aps_body_unsupported";
|
|
2868
|
+
const has = (name) => form.values.has(name);
|
|
2869
|
+
if (has("token_name"))
|
|
2870
|
+
return "aps_saved_card_refused";
|
|
2871
|
+
if ([...form.values.keys()].some((name) => /^merchant_extra[1-5]?$|^agreement_id$|^recurring_/.test(name)))
|
|
2872
|
+
return "aps_recurring_refused";
|
|
2873
|
+
if (has("service_command") && form.values.get("service_command") !== "TOKENIZATION")
|
|
2874
|
+
return "aps_service_command_refused";
|
|
2875
|
+
const allowed = /* @__PURE__ */ new Set([...APS_SIGNED_FIELDS, ...APS_CARD_FIELDS, ...APS_OPTIONAL_FIELDS]);
|
|
2876
|
+
if (form.pairs.some(({ name }) => !allowed.has(name)))
|
|
2877
|
+
return "aps_body_unsupported";
|
|
2878
|
+
if (!returnUrlAdmitted(form.values.get("return_url")))
|
|
2879
|
+
return "aps_return_url_refused";
|
|
2880
|
+
for (const name of [...APS_SIGNED_FIELDS, ...APS_CARD_FIELDS]) {
|
|
2881
|
+
if (name !== "return_url" && !SHAPES.get(name)(form.values.get(name)))
|
|
2882
|
+
return "aps_body_unsupported";
|
|
2883
|
+
}
|
|
2884
|
+
for (const name of APS_OPTIONAL_FIELDS) {
|
|
2885
|
+
if (has(name) && !SHAPES.get(name)(form.values.get(name)))
|
|
2886
|
+
return "aps_body_unsupported";
|
|
2887
|
+
}
|
|
2888
|
+
return null;
|
|
2889
|
+
}
|
|
2890
|
+
function apsBodyVerdict(body, url) {
|
|
2891
|
+
if (url !== void 0 && !apsTokenizationUrl(url))
|
|
2892
|
+
return { verdict: "refuse", code: "aps_url_refused" };
|
|
2893
|
+
const form = parseForm(body);
|
|
2894
|
+
const names = form ? [...form.values.keys()] : typeof body === "string" ? body.split("&").map((chunk) => {
|
|
2895
|
+
try {
|
|
2896
|
+
return decodeURIComponent(chunk.split("=")[0].replace(/\+/g, " "));
|
|
2897
|
+
}
|
|
2898
|
+
catch {
|
|
2899
|
+
return APS_CARD_FIELDS[0];
|
|
2900
|
+
}
|
|
2901
|
+
}) : [APS_CARD_FIELDS[0]];
|
|
2902
|
+
const mentionsCard = !form && typeof body === "string" && APS_CARD_FIELDS.some((name) => body.toLowerCase().includes(name) || body.replace(/%([0-9A-Fa-f]{2})/g, (_, hex) => String.fromCharCode(parseInt(hex, 16))).toLowerCase().includes(name));
|
|
2903
|
+
if (!mentionsCard && !names.some((name) => APS_CARD_FIELDS.includes(name.trim().toLowerCase())))
|
|
2904
|
+
return { verdict: "continue" };
|
|
2905
|
+
const code = apsBodyRefusal(body);
|
|
2906
|
+
return code ? { verdict: "refuse", code } : { verdict: "card" };
|
|
2907
|
+
}
|
|
2908
|
+
var ANSWER_LIMIT = 64 * 1024;
|
|
2005
2909
|
// src/card-fields.js
|
|
2006
2910
|
function processorGate(recognizer, url, body) {
|
|
2007
2911
|
if (recognizer && recognizer.psp === LYRA_PSP)
|
|
@@ -2013,6 +2917,11 @@ function processorGate(recognizer, url, body) {
|
|
|
2013
2917
|
}
|
|
2014
2918
|
if (recognizer && recognizer.psp === KOMOJU_PSP)
|
|
2015
2919
|
return komojuBodyVerdict(body, url);
|
|
2920
|
+
if (recognizer && recognizer.psp === HIPAY_PSP) {
|
|
2921
|
+
if (url !== void 0 && !isHipayTokenUrl(url))
|
|
2922
|
+
return { verdict: "refuse", code: "hipay_url_refused" };
|
|
2923
|
+
return hipayBodyVerdict(body);
|
|
2924
|
+
}
|
|
2016
2925
|
if (recognizer && recognizer.psp === PADDLE_VGS_PSP) {
|
|
2017
2926
|
if (url !== void 0 && !isPaddleVgsCardsUrl(url))
|
|
2018
2927
|
return { verdict: "refuse", code: "paddle_vgs_url_refused" };
|
|
@@ -2034,6 +2943,19 @@ function processorGate(recognizer, url, body) {
|
|
|
2034
2943
|
return { verdict: "refuse", code: "pay_nl_url_refused" };
|
|
2035
2944
|
return payNlBodyVerdict(body);
|
|
2036
2945
|
}
|
|
2946
|
+
if (recognizer && recognizer.psp === TWOC2P_PSP) {
|
|
2947
|
+
if (url === void 0)
|
|
2948
|
+
return twoC2pBodyVerdict(body);
|
|
2949
|
+
const target = twoC2pPaymentTarget(url);
|
|
2950
|
+
if (target === null)
|
|
2951
|
+
return { verdict: "refuse", code: "twoc2p_url_refused" };
|
|
2952
|
+
if (!target.reviewed)
|
|
2953
|
+
return twoC2pPaymentCarriesCard(body) ? { verdict: "refuse", code: "twoc2p_build_unreviewed" } : { verdict: "continue" };
|
|
2954
|
+
const keyBytes = twoC2pKeyBytes(target.environment);
|
|
2955
|
+
return keyBytes === null ? { verdict: "refuse", code: "twoc2p_field_unreviewed" } : twoC2pBodyVerdict(body, keyBytes, target.environment);
|
|
2956
|
+
}
|
|
2957
|
+
if (recognizer && recognizer.psp === APS_PSP)
|
|
2958
|
+
return apsBodyVerdict(body, url);
|
|
2037
2959
|
if (recognizer && recognizer.psp === PADDLE_TOKENEX_PSP) {
|
|
2038
2960
|
const target = url !== void 0 ? paddleTokenexPayTarget(url) : null;
|
|
2039
2961
|
if (url !== void 0 && target === null)
|
|
@@ -2048,6 +2970,13 @@ function processorGate(recognizer, url, body) {
|
|
|
2048
2970
|
}
|
|
2049
2971
|
if (recognizer && recognizer.psp === GOPAY_PSP)
|
|
2050
2972
|
return gopayBodyVerdict(body, url);
|
|
2973
|
+
if (recognizer && recognizer.psp === REVOLUT_PSP) {
|
|
2974
|
+
if (url !== void 0 && !isRevolutPaymentsUrl(url))
|
|
2975
|
+
return { verdict: "refuse", code: "revolut_url_refused" };
|
|
2976
|
+
return revolutBodyVerdict(body);
|
|
2977
|
+
}
|
|
2978
|
+
if (recognizer && recognizer.psp === SUMUP_PSP)
|
|
2979
|
+
return sumupBodyVerdict(body, url);
|
|
2051
2980
|
if (recognizer && recognizer.psp === GRAVY_PSP)
|
|
2052
2981
|
return gravyBodyVerdict(body);
|
|
2053
2982
|
if (recognizer && recognizer.psp === MONERIS_PSP) {
|
|
@@ -2168,21 +3097,21 @@ var KEEP_ON_FILE_REFUSAL = "Refusing to pay: this Primer payment would keep the
|
|
|
2168
3097
|
var UNSUPPORTED_SDK_REFUSAL = "Refusing to pay: this checkout uses a Primer SDK Agentcard does not support yet. Nothing was sent.";
|
|
2169
3098
|
var NETWORK_MISMATCH_REFUSAL = "Refusing to pay: this Primer payment names a card network that is not your card's. Nothing was sent.";
|
|
2170
3099
|
var FILL_REFUSAL = "Could not fill the card fields for Primer. Nothing was sent.";
|
|
2171
|
-
var
|
|
3100
|
+
var BODY_LIMIT17 = 16384;
|
|
2172
3101
|
var RESPONSE_LIMIT = 32768;
|
|
2173
|
-
var
|
|
3102
|
+
var ROOT_KEYS7 = ["paymentInstrument", "userDescription", "tokenType", "paymentFlow"];
|
|
2174
3103
|
var INSTRUMENT_KEYS = ["number", "cvv", "expirationMonth", "expirationYear", "cardholderName", "preferredNetwork"];
|
|
2175
3104
|
var REQUIRED_INSTRUMENT_KEYS = ["number", "cvv", "expirationMonth", "expirationYear"];
|
|
2176
|
-
var
|
|
3105
|
+
var record14 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
2177
3106
|
var owns5 = (value, key) => Object.prototype.hasOwnProperty.call(value, key);
|
|
2178
|
-
var
|
|
2179
|
-
var
|
|
3107
|
+
var exact2 = (pattern, value) => typeof value === "string" && pattern.exec(value)?.[0] === value;
|
|
3108
|
+
var text3 = (value, max) => typeof value === "string" && value.length <= max && !/[\u0000-\u001f\u007f]/.test(value);
|
|
2180
3109
|
var digits = (value, min, max) => typeof value === "string" && value.length >= min && value.length <= max && !/[^0-9]/.test(value);
|
|
2181
3110
|
var panLike = (value) => /(?:[0-9][ _.:-]*){12,}/.test(value);
|
|
2182
|
-
var plain = (value, max) =>
|
|
2183
|
-
var
|
|
2184
|
-
var
|
|
2185
|
-
var
|
|
3111
|
+
var plain = (value, max) => text3(value, max) && !panLike(value);
|
|
3112
|
+
var MONTH9 = /^(?:0[1-9]|1[0-2])$/;
|
|
3113
|
+
var YEAR9 = /^20[0-9]{2}$/;
|
|
3114
|
+
var NETWORK2 = /^[A-Z][A-Z_]{1,31}$/;
|
|
2186
3115
|
function isPrimerTokenizeUrl(url, method = "POST") {
|
|
2187
3116
|
if (method !== "POST" || typeof url !== "string" || url.length > 256 || url.includes("?") || url.includes("#"))
|
|
2188
3117
|
return false;
|
|
@@ -2196,7 +3125,7 @@ function isPrimerTokenizeUrl(url, method = "POST") {
|
|
|
2196
3125
|
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;
|
|
2197
3126
|
}
|
|
2198
3127
|
function judgeBody4(body) {
|
|
2199
|
-
if (typeof body !== "string" || body === "" || body.length >
|
|
3128
|
+
if (typeof body !== "string" || body === "" || body.length > BODY_LIMIT17)
|
|
2200
3129
|
return null;
|
|
2201
3130
|
let value;
|
|
2202
3131
|
try {
|
|
@@ -2205,16 +3134,16 @@ function judgeBody4(body) {
|
|
|
2205
3134
|
catch {
|
|
2206
3135
|
return null;
|
|
2207
3136
|
}
|
|
2208
|
-
if (!
|
|
3137
|
+
if (!record14(value) || !roundTrips(value, body))
|
|
2209
3138
|
return null;
|
|
2210
|
-
if (!Object.keys(value).every((key) =>
|
|
3139
|
+
if (!Object.keys(value).every((key) => ROOT_KEYS7.includes(key)) || !owns5(value, "paymentInstrument"))
|
|
2211
3140
|
return null;
|
|
2212
3141
|
const instrument = value.paymentInstrument;
|
|
2213
|
-
if (!
|
|
3142
|
+
if (!record14(instrument) || !Object.keys(instrument).every((key) => INSTRUMENT_KEYS.includes(key)) || !REQUIRED_INSTRUMENT_KEYS.every((key) => owns5(instrument, key)))
|
|
2214
3143
|
return null;
|
|
2215
|
-
if (!digits(instrument.number, 12, 19) || !digits(instrument.cvv, 3, 4) || !
|
|
3144
|
+
if (!digits(instrument.number, 12, 19) || !digits(instrument.cvv, 3, 4) || !exact2(MONTH9, instrument.expirationMonth) || !exact2(YEAR9, instrument.expirationYear))
|
|
2216
3145
|
return null;
|
|
2217
|
-
if (owns5(instrument, "cardholderName") && instrument.cardholderName !== null && !plain(instrument.cardholderName, 256) || owns5(instrument, "preferredNetwork") && instrument.preferredNetwork !== null && !
|
|
3146
|
+
if (owns5(instrument, "cardholderName") && instrument.cardholderName !== null && !plain(instrument.cardholderName, 256) || owns5(instrument, "preferredNetwork") && instrument.preferredNetwork !== null && !exact2(NETWORK2, instrument.preferredNetwork) || owns5(value, "userDescription") && value.userDescription !== null && !plain(value.userDescription, 256) || owns5(value, "tokenType") && value.tokenType !== "MULTI_USE" || owns5(value, "paymentFlow") && value.paymentFlow !== "VAULT")
|
|
2218
3147
|
return null;
|
|
2219
3148
|
return { value, keepOnFile: owns5(value, "tokenType") || owns5(value, "paymentFlow") };
|
|
2220
3149
|
}
|
|
@@ -2238,7 +3167,7 @@ var CLIENT_TOKEN = /^[A-Za-z0-9._~+/=-]{16,4096}$/;
|
|
|
2238
3167
|
var REQUEST_ID = /^[A-Za-z0-9-]{1,64}$/;
|
|
2239
3168
|
var API_VERSION = /^2\.[0-9]{1,2}$/;
|
|
2240
3169
|
function readHeaders(headers) {
|
|
2241
|
-
if (!
|
|
3170
|
+
if (!record14(headers))
|
|
2242
3171
|
return null;
|
|
2243
3172
|
const folded = /* @__PURE__ */ new Map();
|
|
2244
3173
|
for (const [name, value] of Object.entries(headers)) {
|
|
@@ -2256,9 +3185,9 @@ function headersRefusal(headers) {
|
|
|
2256
3185
|
const version = folded.get("primer-sdk-version");
|
|
2257
3186
|
if (typeof version !== "string")
|
|
2258
3187
|
return "unsupported";
|
|
2259
|
-
if (!
|
|
3188
|
+
if (!exact2(LEGACY_SDK_VERSION, version))
|
|
2260
3189
|
return "unsupported_sdk";
|
|
2261
|
-
if (!
|
|
3190
|
+
if (!exact2(CONTENT_TYPE2, folded.get("content-type")) || !exact2(CLIENT_TOKEN, folded.get("primer-client-token")) || folded.has("primer-sdk-client") && folded.get("primer-sdk-client") !== "WEB" || folded.has("x-api-version") && !exact2(API_VERSION, folded.get("x-api-version")) || folded.has("primer-sdk-checkout-session-id") && !exact2(REQUEST_ID, folded.get("primer-sdk-checkout-session-id")) || folded.has("x-request-id") && !exact2(REQUEST_ID, folded.get("x-request-id")))
|
|
2262
3191
|
return "unsupported";
|
|
2263
3192
|
return null;
|
|
2264
3193
|
}
|
|
@@ -2285,7 +3214,7 @@ function onTokenizePath(url) {
|
|
|
2285
3214
|
}
|
|
2286
3215
|
}
|
|
2287
3216
|
function primerTokenizeRefusal(request) {
|
|
2288
|
-
if (!
|
|
3217
|
+
if (!record14(request) || request.method !== "POST" || !isPrimerTokenizeUrl(request.url))
|
|
2289
3218
|
return "unsupported";
|
|
2290
3219
|
return headersRefusal(request.headers) ?? primerBodyRefusal(request.body);
|
|
2291
3220
|
}
|
|
@@ -2300,7 +3229,7 @@ function primerCardOnFileRefusal(url, options, policy = PRIMER_SESSION_CARD_ON_F
|
|
|
2300
3229
|
return "unsupported";
|
|
2301
3230
|
if (new URL(url).hostname !== LIVE_PCI_HOST)
|
|
2302
3231
|
return null;
|
|
2303
|
-
return primerCardOnFileDisclosure(url, policy) &&
|
|
3232
|
+
return primerCardOnFileDisclosure(url, policy) && record14(options) && options.keepOnFile === true ? null : "keep_on_file";
|
|
2304
3233
|
}
|
|
2305
3234
|
function primerRefusalMessage(reason) {
|
|
2306
3235
|
if (reason === "keep_on_file")
|
|
@@ -2361,7 +3290,7 @@ function injectPrimerCard(body, card) {
|
|
|
2361
3290
|
}
|
|
2362
3291
|
var TOKEN3 = /^[A-Za-z0-9_-]{8,256}$/;
|
|
2363
3292
|
var ERROR_ID = /^[A-Za-z][A-Za-z0-9_.-]{0,63}$/;
|
|
2364
|
-
var
|
|
3293
|
+
var CODE3 = /^[A-Z][A-Z0-9_]{0,63}$/;
|
|
2365
3294
|
var NETWORK_NAME = /^[A-Za-z][A-Za-z0-9 _-]{0,31}$/;
|
|
2366
3295
|
var RESPONSE_MONTH = /^(?:0?[1-9]|1[0-2])$/;
|
|
2367
3296
|
var RESPONSE_YEAR = /^(?:[0-9]{2}|20[0-9]{2})$/;
|
|
@@ -2384,25 +3313,25 @@ function readAnswer(body) {
|
|
|
2384
3313
|
return null;
|
|
2385
3314
|
try {
|
|
2386
3315
|
const value = JSON.parse(body);
|
|
2387
|
-
return
|
|
3316
|
+
return record14(value) ? value : null;
|
|
2388
3317
|
}
|
|
2389
3318
|
catch {
|
|
2390
3319
|
return null;
|
|
2391
3320
|
}
|
|
2392
3321
|
}
|
|
2393
|
-
var tokenValue = (value) =>
|
|
3322
|
+
var tokenValue = (value) => exact2(TOKEN3, value) && !panLike(value);
|
|
2394
3323
|
var optional = (value, key, check) => !owns5(value, key) || value[key] === null || check(value[key]);
|
|
2395
3324
|
function cardDetails(data) {
|
|
2396
|
-
if (!
|
|
3325
|
+
if (!record14(data) || !exact2(/^[0-9]{4}$/, data.last4Digits))
|
|
2397
3326
|
return null;
|
|
2398
|
-
if (!optional(data, "first6Digits", (v) =>
|
|
3327
|
+
if (!optional(data, "first6Digits", (v) => exact2(/^[0-9]{6}$/, v)) || !optional(data, "expirationMonth", (v) => exact2(RESPONSE_MONTH, v)) || !optional(data, "expirationYear", (v) => exact2(RESPONSE_YEAR, v)) || !optional(data, "cardholderName", (v) => plain(v, 256)) || !optional(data, "network", (v) => exact2(NETWORK_NAME, v)) || !optional(data, "isNetworkTokenized", (v) => typeof v === "boolean") || !optional(data, "binData", record14))
|
|
2399
3328
|
return null;
|
|
2400
3329
|
const safe = { last4Digits: data.last4Digits };
|
|
2401
3330
|
for (const key of ["first6Digits", "expirationMonth", "expirationYear", "cardholderName", "network", "isNetworkTokenized"]) {
|
|
2402
3331
|
if (owns5(data, key) && data[key] !== null)
|
|
2403
3332
|
safe[key] = data[key];
|
|
2404
3333
|
}
|
|
2405
|
-
if (
|
|
3334
|
+
if (record14(data.binData)) {
|
|
2406
3335
|
const bin = {};
|
|
2407
3336
|
for (const key of BIN_KEYS) {
|
|
2408
3337
|
if (!owns5(data.binData, key) || data.binData[key] === null)
|
|
@@ -2418,7 +3347,7 @@ function cardDetails(data) {
|
|
|
2418
3347
|
function threeDsSummary(value) {
|
|
2419
3348
|
if (value === void 0 || value === null)
|
|
2420
3349
|
return null;
|
|
2421
|
-
if (!
|
|
3350
|
+
if (!record14(value) || !exact2(CODE3, value.responseCode) || !optional(value, "reasonCode", (v) => exact2(CODE3, v)) || !optional(value, "reasonText", (v) => plain(v, 256)) || !optional(value, "protocolVersion", (v) => v === "" || exact2(PROTOCOL, v)) || !optional(value, "challengeIssued", (v) => typeof v === "boolean"))
|
|
2422
3351
|
return void 0;
|
|
2423
3352
|
const safe = { responseCode: value.responseCode };
|
|
2424
3353
|
for (const key of ["reasonCode", "reasonText", "protocolVersion", "challengeIssued"]) {
|
|
@@ -2446,8 +3375,8 @@ function rebuildToken(value) {
|
|
|
2446
3375
|
}
|
|
2447
3376
|
function primerErrorId(body) {
|
|
2448
3377
|
const value = readAnswer(body);
|
|
2449
|
-
const id = value &&
|
|
2450
|
-
return
|
|
3378
|
+
const id = value && record14(value.error) ? value.error.errorId : null;
|
|
3379
|
+
return exact2(ERROR_ID, id) && !panLike(id) ? id : null;
|
|
2451
3380
|
}
|
|
2452
3381
|
function matchesCard(details, card) {
|
|
2453
3382
|
const number = card && typeof card.number === "string" ? card.number : "";
|