@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
|
@@ -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: 7e485110ac882bd8e19be7369be8487a532ae7dc93bde3bf660fecb1851f500e
|
|
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
|
|
@@ -101,8 +101,8 @@ function parseConvergeBody(body) {
|
|
|
101
101
|
return parsed;
|
|
102
102
|
}
|
|
103
103
|
function convergeAmountCents(value) {
|
|
104
|
-
const
|
|
105
|
-
const m = typeof
|
|
104
|
+
const text3 = typeof value === "number" && Number.isFinite(value) ? String(value) : value;
|
|
105
|
+
const m = typeof text3 === "string" ? AMOUNT.exec(text3) : null;
|
|
106
106
|
if (!m)
|
|
107
107
|
return null;
|
|
108
108
|
const cents = Number(m[1]) * 100 + Number(((m[2] ?? "") + "00").slice(0, 2));
|
|
@@ -302,11 +302,11 @@ var MONERIS_TOKENIZE_PATH = "/HPPtoken/request.php";
|
|
|
302
302
|
function monerisTokenizeEnvironment(url) {
|
|
303
303
|
if (typeof url !== "string")
|
|
304
304
|
return null;
|
|
305
|
-
for (const
|
|
305
|
+
for (const environment2 of
|
|
306
306
|
/** @type {const} */
|
|
307
307
|
["production", "sandbox"]) {
|
|
308
|
-
if (MONERIS_TOKENIZE_HOSTS[
|
|
309
|
-
return
|
|
308
|
+
if (MONERIS_TOKENIZE_HOSTS[environment2].some((host) => url === `https://${host}${MONERIS_TOKENIZE_PATH}`))
|
|
309
|
+
return environment2;
|
|
310
310
|
}
|
|
311
311
|
return null;
|
|
312
312
|
}
|
|
@@ -357,8 +357,8 @@ var CONTROL = /[\u0000-\u001f\u007f]/;
|
|
|
357
357
|
var cardLikeName = (name) => (name.match(/[0-9]/g) ?? []).length >= 12;
|
|
358
358
|
var record3 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
359
359
|
var sameKeys = (value, keys) => {
|
|
360
|
-
const
|
|
361
|
-
return
|
|
360
|
+
const own3 = Object.keys(value);
|
|
361
|
+
return own3.length === keys.length && own3.every((key, at) => key === keys[at]);
|
|
362
362
|
};
|
|
363
363
|
var refuse4 = (code) => Object.freeze({ verdict: "refuse", code });
|
|
364
364
|
var CARD4 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
|
|
@@ -582,9 +582,9 @@ var K = /* @__PURE__ */ new Uint32Array([
|
|
|
582
582
|
3329325298
|
|
583
583
|
]);
|
|
584
584
|
var rotr = (x, n) => x >>> n | x << 32 - n;
|
|
585
|
-
function utf8(
|
|
585
|
+
function utf8(text3) {
|
|
586
586
|
const out = [];
|
|
587
|
-
for (const char of
|
|
587
|
+
for (const char of text3) {
|
|
588
588
|
let cp = char.codePointAt(0);
|
|
589
589
|
if (cp >= 55296 && cp <= 57343)
|
|
590
590
|
cp = 65533;
|
|
@@ -746,13 +746,13 @@ var PADDLE_TOKENEX_KEYS = /* @__PURE__ */ Object.freeze({
|
|
|
746
746
|
sha256: "92529bd289bb24d52a1bdcc42edc9ac0bb1dacbb58f7568573d44771e1287762"
|
|
747
747
|
})
|
|
748
748
|
});
|
|
749
|
-
function paddleTokenexKey(
|
|
750
|
-
if (
|
|
749
|
+
function paddleTokenexKey(environment2) {
|
|
750
|
+
if (environment2 !== "sandbox" && environment2 !== "production")
|
|
751
751
|
return null;
|
|
752
|
-
return PADDLE_TOKENEX_KEYS[
|
|
752
|
+
return PADDLE_TOKENEX_KEYS[environment2] ?? null;
|
|
753
753
|
}
|
|
754
|
-
function paddleTokenexKeyBytes(
|
|
755
|
-
const key = paddleTokenexKey(
|
|
754
|
+
function paddleTokenexKeyBytes(environment2) {
|
|
755
|
+
const key = paddleTokenexKey(environment2);
|
|
756
756
|
if (!key)
|
|
757
757
|
return null;
|
|
758
758
|
try {
|
|
@@ -767,8 +767,8 @@ var PADDLE_TOKENEX_PSP = "paddle_tokenex";
|
|
|
767
767
|
var PADDLE_TOKENEX_FACT_KEYS = /* @__PURE__ */ Object.freeze(["card_first_six", "card_last_four", "expiry_month", "expiry_year", "card_brand"]);
|
|
768
768
|
var record4 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
769
769
|
var sameKeys2 = (value, keys) => {
|
|
770
|
-
const
|
|
771
|
-
return
|
|
770
|
+
const own3 = Object.keys(value);
|
|
771
|
+
return own3.length === keys.length && own3.every((key, at) => key === keys[at]);
|
|
772
772
|
};
|
|
773
773
|
var refuse7 = (code) => Object.freeze({ verdict: "refuse", code });
|
|
774
774
|
var CARD6 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
|
|
@@ -813,11 +813,11 @@ function isBase64OfBytes(value, bytes) {
|
|
|
813
813
|
const pad = value.endsWith("==") ? 2 : value.endsWith("=") ? 1 : 0;
|
|
814
814
|
return value.length / 4 * 3 - pad === bytes && btoa(atob(value)) === value;
|
|
815
815
|
}
|
|
816
|
-
function isPaddleTokenexCiphertext(value,
|
|
817
|
-
const bytes = paddleTokenexKeyBytes(
|
|
816
|
+
function isPaddleTokenexCiphertext(value, environment2) {
|
|
817
|
+
const bytes = paddleTokenexKeyBytes(environment2);
|
|
818
818
|
return bytes !== null && isBase64OfBytes(value, bytes);
|
|
819
819
|
}
|
|
820
|
-
function readPay(body, line,
|
|
820
|
+
function readPay(body, line, environment2) {
|
|
821
821
|
if (typeof body !== "string" || body === "" || body.length > PAY_BODY_LIMIT)
|
|
822
822
|
return null;
|
|
823
823
|
let value;
|
|
@@ -849,11 +849,11 @@ function readPay(body, line, environment) {
|
|
|
849
849
|
return null;
|
|
850
850
|
for (const name of CARD_KEYS3) {
|
|
851
851
|
const blob = tokenex[name];
|
|
852
|
-
if (
|
|
852
|
+
if (environment2 === void 0) {
|
|
853
853
|
if (typeof blob !== "string" || !BASE642.test(blob) || blob.length < 4 || blob.length > 4096)
|
|
854
854
|
return null;
|
|
855
855
|
}
|
|
856
|
-
else if (!isPaddleTokenexCiphertext(blob,
|
|
856
|
+
else if (!isPaddleTokenexCiphertext(blob, environment2))
|
|
857
857
|
return null;
|
|
858
858
|
}
|
|
859
859
|
if (tokenex.encrypted_card_number === tokenex.encrypted_cvv)
|
|
@@ -1257,8 +1257,8 @@ var TEXT_LIMIT = 256;
|
|
|
1257
1257
|
var CONTROL4 = /[\u0000-\u001f\u007f]/;
|
|
1258
1258
|
var record6 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
1259
1259
|
var sameKeys3 = (value, keys) => {
|
|
1260
|
-
const
|
|
1261
|
-
return
|
|
1260
|
+
const own3 = Object.keys(value);
|
|
1261
|
+
return own3.length === keys.length && own3.every((key, at) => key === keys[at]);
|
|
1262
1262
|
};
|
|
1263
1263
|
var plainText = (value) => typeof value === "string" && value.length <= TEXT_LIMIT && !CONTROL4.test(value) && (value.match(/[0-9]/g) ?? []).length < 12;
|
|
1264
1264
|
var refuse9 = (code) => Object.freeze({ verdict: "refuse", code });
|
|
@@ -1368,14 +1368,14 @@ function readJson2(body) {
|
|
|
1368
1368
|
catch {
|
|
1369
1369
|
return { parsed: null, exact: false };
|
|
1370
1370
|
}
|
|
1371
|
-
let
|
|
1371
|
+
let exact2 = false;
|
|
1372
1372
|
try {
|
|
1373
|
-
|
|
1373
|
+
exact2 = body.length <= BODY_LIMIT6 && JSON.stringify(parsed) === body;
|
|
1374
1374
|
}
|
|
1375
1375
|
catch {
|
|
1376
|
-
|
|
1376
|
+
exact2 = false;
|
|
1377
1377
|
}
|
|
1378
|
-
return { parsed, exact };
|
|
1378
|
+
return { parsed, exact: exact2 };
|
|
1379
1379
|
}
|
|
1380
1380
|
function billingValue(value) {
|
|
1381
1381
|
if (value === UNDEFINED)
|
|
@@ -1430,14 +1430,14 @@ function attachType(parsed) {
|
|
|
1430
1430
|
return typeof type === "string" ? type : null;
|
|
1431
1431
|
}
|
|
1432
1432
|
function paymongoBodyVerdict(body, session) {
|
|
1433
|
-
const { parsed, exact } = readJson2(body);
|
|
1433
|
+
const { parsed, exact: exact2 } = readJson2(body);
|
|
1434
1434
|
const type = parsed === null ? null : attachType(parsed);
|
|
1435
1435
|
if (type !== "card") {
|
|
1436
1436
|
if (parsed === null)
|
|
1437
1437
|
return body === void 0 || body === null || body === "" ? CONTINUE4 : refuse10("paymongo_body_unsupported");
|
|
1438
1438
|
return namesCardValue(parsed) ? refuse10("paymongo_body_unsupported") : CONTINUE4;
|
|
1439
1439
|
}
|
|
1440
|
-
if (!
|
|
1440
|
+
if (!exact2)
|
|
1441
1441
|
return refuse10("paymongo_body_unsupported");
|
|
1442
1442
|
const code = judgeCardAttach(parsed, session);
|
|
1443
1443
|
return code === null ? CARD9 : refuse10(code);
|
|
@@ -1460,8 +1460,8 @@ var EXPIRATION = /^[0-9]{2}(?:0[1-9]|1[0-2])$/;
|
|
|
1460
1460
|
var CARD_PAYMENT = "PAYMENT_CARD";
|
|
1461
1461
|
var record8 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
1462
1462
|
var sameKeys4 = (value, keys) => {
|
|
1463
|
-
const
|
|
1464
|
-
return
|
|
1463
|
+
const own3 = Object.keys(value);
|
|
1464
|
+
return own3.length === keys.length && own3.every((key, at) => key === keys[at]);
|
|
1465
1465
|
};
|
|
1466
1466
|
var refuse11 = (code) => Object.freeze({ verdict: "refuse", code });
|
|
1467
1467
|
var CARD10 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
|
|
@@ -1490,8 +1490,8 @@ function gopayCardFormUrl(url) {
|
|
|
1490
1490
|
}
|
|
1491
1491
|
if (parsed.href !== url || parsed.protocol !== "https:" || parsed.port || parsed.username || parsed.password)
|
|
1492
1492
|
return null;
|
|
1493
|
-
const
|
|
1494
|
-
if (
|
|
1493
|
+
const environment2 = Object.prototype.hasOwnProperty.call(GOPAY_CARD_FORM_HOSTS, parsed.hostname) ? GOPAY_CARD_FORM_HOSTS[parsed.hostname] : null;
|
|
1494
|
+
if (environment2 === null || !parsed.pathname.startsWith(GOPAY_CARD_FORM_PATH))
|
|
1495
1495
|
return null;
|
|
1496
1496
|
if (!TOKEN2.test(parsed.pathname.slice(GOPAY_CARD_FORM_PATH.length)))
|
|
1497
1497
|
return null;
|
|
@@ -1503,7 +1503,7 @@ function gopayCardFormUrl(url) {
|
|
|
1503
1503
|
const version = parsed.searchParams.get("ver");
|
|
1504
1504
|
if (signature === null || !SIGNATURE.test(signature) || language !== null && !LANGUAGE.test(language) || version !== null && !VERSION.test(version))
|
|
1505
1505
|
return null;
|
|
1506
|
-
return Object.freeze({ host: parsed.hostname, environment, signature });
|
|
1506
|
+
return Object.freeze({ host: parsed.hostname, environment: environment2, signature });
|
|
1507
1507
|
}
|
|
1508
1508
|
function readBody4(body) {
|
|
1509
1509
|
if (typeof body !== "string" || body === "" || body.length > BODY_LIMIT7)
|
|
@@ -1658,6 +1658,9 @@ function payrexxGateVerdict(url, body) {
|
|
|
1658
1658
|
const verdict = payrexxBodyVerdict(body);
|
|
1659
1659
|
return verdict.verdict === "card" && target.pspId !== PAYREXX_PAY_PSP_ID ? refuse12("payrexx_other_provider") : verdict;
|
|
1660
1660
|
}
|
|
1661
|
+
var PAYREXX_FOLLOW_UP_WINDOW_MS = 15 * 60 * 1e3;
|
|
1662
|
+
var PAYREXX_FOLLOW_UP_IDLE_MS = 60 * 1e3;
|
|
1663
|
+
var PAYREXX_FOLLOW_UP_CHALLENGE_MS = 11 * 60 * 1e3;
|
|
1661
1664
|
// src/komoju.js
|
|
1662
1665
|
var KOMOJU_PSP = "komoju";
|
|
1663
1666
|
var KOMOJU_HOST = "komoju.com";
|
|
@@ -1685,8 +1688,8 @@ var LOCALE = /^[a-z]{2}(?:-[A-Za-z]{2,4})?$/;
|
|
|
1685
1688
|
var PAN_LIKE3 = /(?:[0-9][ _.:-]*){12,}/;
|
|
1686
1689
|
var record9 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
1687
1690
|
var sameKeys5 = (value, keys) => {
|
|
1688
|
-
const
|
|
1689
|
-
return
|
|
1691
|
+
const own3 = Object.keys(value);
|
|
1692
|
+
return own3.length === keys.length && own3.every((key, at) => key === keys[at]);
|
|
1690
1693
|
};
|
|
1691
1694
|
var refuse13 = (code) => Object.freeze({ verdict: "refuse", code });
|
|
1692
1695
|
var CARD12 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
|
|
@@ -1843,14 +1846,14 @@ function paygentBodyVerdict(body) {
|
|
|
1843
1846
|
return code === null ? CARD13 : refuse14(code);
|
|
1844
1847
|
}
|
|
1845
1848
|
function paygentRequestVerdict(url, body) {
|
|
1846
|
-
const
|
|
1847
|
-
if (
|
|
1849
|
+
const environment2 = paygentEnvironment(url);
|
|
1850
|
+
if (environment2 === null)
|
|
1848
1851
|
return refuse14("paygent_url_refused");
|
|
1849
1852
|
const { code, pairs } = judgeBody3(body);
|
|
1850
1853
|
if (code !== null)
|
|
1851
1854
|
return refuse14(code);
|
|
1852
1855
|
const key = pairs[1][1];
|
|
1853
|
-
return (
|
|
1856
|
+
return (environment2 === "production" ? LIVE_KEY : SANDBOX_KEY).test(key) ? CARD13 : refuse14("paygent_key_environment");
|
|
1854
1857
|
}
|
|
1855
1858
|
// src/multipart-form.js
|
|
1856
1859
|
var BODY_LIMIT11 = 65536;
|
|
@@ -1994,6 +1997,907 @@ function payNlBodyVerdict(body, contentType) {
|
|
|
1994
1997
|
}
|
|
1995
1998
|
var ERROR_KEYS = /* @__PURE__ */ Object.freeze(["errorId", "errorTag", "errorMessage", "errorFieldName"]);
|
|
1996
1999
|
var REQUEST_KEYS = /* @__PURE__ */ Object.freeze(["result", ...ERROR_KEYS]);
|
|
2000
|
+
// src/revolut.js
|
|
2001
|
+
var REVOLUT_PSP = "revolut";
|
|
2002
|
+
var REVOLUT_HOSTS = /* @__PURE__ */ Object.freeze(["merchant.revolut.com", "sandbox-merchant.revolut.com"]);
|
|
2003
|
+
var REVOLUT_BODY_KEYS = /* @__PURE__ */ Object.freeze(["payment_method", "customer", "amount", "channel"]);
|
|
2004
|
+
var REVOLUT_CARD_FIELD_KEYS = /* @__PURE__ */ Object.freeze([
|
|
2005
|
+
"type",
|
|
2006
|
+
"number",
|
|
2007
|
+
"expiry_month",
|
|
2008
|
+
"expiry_year",
|
|
2009
|
+
"cvv",
|
|
2010
|
+
"kount_session_id",
|
|
2011
|
+
"billing_address",
|
|
2012
|
+
"cardholder_name",
|
|
2013
|
+
"shipping_address",
|
|
2014
|
+
"save_for",
|
|
2015
|
+
"environment"
|
|
2016
|
+
]);
|
|
2017
|
+
var REVOLUT_CARD_POPUP_KEYS = /* @__PURE__ */ Object.freeze([
|
|
2018
|
+
"type",
|
|
2019
|
+
"number",
|
|
2020
|
+
"expiry_month",
|
|
2021
|
+
"expiry_year",
|
|
2022
|
+
"cvv",
|
|
2023
|
+
"kount_session_id",
|
|
2024
|
+
"cardholder_name",
|
|
2025
|
+
"billing_address",
|
|
2026
|
+
"shipping_address",
|
|
2027
|
+
"save_for",
|
|
2028
|
+
"environment"
|
|
2029
|
+
]);
|
|
2030
|
+
var REVOLUT_CHANNELS = /* @__PURE__ */ Object.freeze(["WEB_SDK", "REV_CHECKOUT", "HOSTED_PAYMENT_PAGE"]);
|
|
2031
|
+
var BODY_LIMIT12 = 16384;
|
|
2032
|
+
var URL_LIMIT6 = 128;
|
|
2033
|
+
var UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;
|
|
2034
|
+
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$/;
|
|
2035
|
+
var CARD_NUMBER8 = /^[0-9]{12,19}$/;
|
|
2036
|
+
var SECURITY_CODE11 = /^[0-9]{3,4}$/;
|
|
2037
|
+
var KOUNT_SESSION = /^[0-9a-f]{32}$/;
|
|
2038
|
+
var AMOUNT_LIMIT = 1e11;
|
|
2039
|
+
var ADDRESS_KEYS = /* @__PURE__ */ Object.freeze(["country", "region", "city", "postcode", "street_line_1", "street_line_2"]);
|
|
2040
|
+
var ENVIRONMENT_KEYS = /* @__PURE__ */ Object.freeze([
|
|
2041
|
+
"type",
|
|
2042
|
+
"color_depth",
|
|
2043
|
+
"screen_width",
|
|
2044
|
+
"screen_height",
|
|
2045
|
+
"java_enabled",
|
|
2046
|
+
"time_zone_utc_offset",
|
|
2047
|
+
"challenge_window_width",
|
|
2048
|
+
"browser_url",
|
|
2049
|
+
"referrer_url"
|
|
2050
|
+
]);
|
|
2051
|
+
var NEW_CUSTOMER_KEYS = /* @__PURE__ */ Object.freeze(["type", "email", "name", "phone"]);
|
|
2052
|
+
var COUNTRY = /^[A-Z]{2}$/;
|
|
2053
|
+
var PHONE = /^\+?[0-9 \u00a0\/().-]{6,32}$/;
|
|
2054
|
+
var EMAIL3 = /^[^\s@]{1,64}@[^\s@]{1,255}$/;
|
|
2055
|
+
var TEXT_LIMIT2 = 256;
|
|
2056
|
+
var CONTROL5 = /[\u0000-\u001f\u007f]/;
|
|
2057
|
+
var CARD_MEMBER2 = /^(?:number|card_?number|cardnumber|cardnum|card_num|pan|cvv|cvc|cvv2)$/i;
|
|
2058
|
+
var record10 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
2059
|
+
var own2 = (value, key) => Object.prototype.hasOwnProperty.call(value, key);
|
|
2060
|
+
var inOrder = (value, keys) => {
|
|
2061
|
+
let at = 0;
|
|
2062
|
+
for (const name of Object.keys(value)) {
|
|
2063
|
+
while (at < keys.length && keys[at] !== name)
|
|
2064
|
+
at += 1;
|
|
2065
|
+
if (at === keys.length)
|
|
2066
|
+
return false;
|
|
2067
|
+
at += 1;
|
|
2068
|
+
}
|
|
2069
|
+
return true;
|
|
2070
|
+
};
|
|
2071
|
+
var wellFormed = (value) => {
|
|
2072
|
+
try {
|
|
2073
|
+
encodeURIComponent(value);
|
|
2074
|
+
return true;
|
|
2075
|
+
}
|
|
2076
|
+
catch {
|
|
2077
|
+
return false;
|
|
2078
|
+
}
|
|
2079
|
+
};
|
|
2080
|
+
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);
|
|
2081
|
+
var between = (value, min, max) => Number.isSafeInteger(value) && value >= min && value <= max;
|
|
2082
|
+
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})$/;
|
|
2083
|
+
var luhn2 = (digits) => {
|
|
2084
|
+
let sum = 0;
|
|
2085
|
+
for (let at = 0; at < digits.length; at += 1) {
|
|
2086
|
+
let d = digits.charCodeAt(digits.length - 1 - at) - 48;
|
|
2087
|
+
if (at % 2 === 1) {
|
|
2088
|
+
d *= 2;
|
|
2089
|
+
if (d > 9)
|
|
2090
|
+
d -= 9;
|
|
2091
|
+
}
|
|
2092
|
+
sum += d;
|
|
2093
|
+
}
|
|
2094
|
+
return sum % 10 === 0;
|
|
2095
|
+
};
|
|
2096
|
+
var ANY_NETWORK = /^[2-6][0-9]{12,18}$/;
|
|
2097
|
+
var holdsCardShape = (text3, shape = NETWORK) => (text3.match(/[0-9]{13,}/g) ?? []).some((run) => run.length > 19 || shape.test(run) && luhn2(run));
|
|
2098
|
+
var phone = (value) => typeof value === "string" && PHONE.test(value) && (value.match(/[0-9]/g) ?? []).length >= 6 && (value.match(/[0-9]/g) ?? []).length <= 15;
|
|
2099
|
+
var refuse16 = (code) => Object.freeze({ verdict: "refuse", code });
|
|
2100
|
+
var CARD15 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
|
|
2101
|
+
var CONTINUE7 = /* @__PURE__ */ Object.freeze({ verdict: "continue" });
|
|
2102
|
+
function revolutPaymentsTarget(url) {
|
|
2103
|
+
if (typeof url !== "string" || url.length > URL_LIMIT6 || url.includes("?") || url.includes("#"))
|
|
2104
|
+
return null;
|
|
2105
|
+
let parsed;
|
|
2106
|
+
try {
|
|
2107
|
+
parsed = new URL(url);
|
|
2108
|
+
}
|
|
2109
|
+
catch {
|
|
2110
|
+
return null;
|
|
2111
|
+
}
|
|
2112
|
+
if (parsed.href !== url || parsed.protocol !== "https:" || parsed.port || parsed.username || parsed.password || !REVOLUT_HOSTS.includes(parsed.hostname))
|
|
2113
|
+
return null;
|
|
2114
|
+
const match = PAYMENTS_PATH.exec(parsed.pathname);
|
|
2115
|
+
return match ? Object.freeze({ host: parsed.hostname, order: match[1] }) : null;
|
|
2116
|
+
}
|
|
2117
|
+
function isRevolutPaymentsUrl(url) {
|
|
2118
|
+
return revolutPaymentsTarget(url) !== null;
|
|
2119
|
+
}
|
|
2120
|
+
function readBody7(body) {
|
|
2121
|
+
if (typeof body !== "string" || body === "" || body.length > BODY_LIMIT12)
|
|
2122
|
+
return null;
|
|
2123
|
+
let value;
|
|
2124
|
+
try {
|
|
2125
|
+
value = JSON.parse(body);
|
|
2126
|
+
if (!record10(value) || JSON.stringify(value) !== body)
|
|
2127
|
+
return null;
|
|
2128
|
+
}
|
|
2129
|
+
catch {
|
|
2130
|
+
return null;
|
|
2131
|
+
}
|
|
2132
|
+
return value;
|
|
2133
|
+
}
|
|
2134
|
+
function address(value) {
|
|
2135
|
+
if (!record10(value) || !inOrder(value, ADDRESS_KEYS))
|
|
2136
|
+
return false;
|
|
2137
|
+
const names = Object.keys(value);
|
|
2138
|
+
if (!names.some((key) => typeof value[key] === "string" && value[key].trim() !== ""))
|
|
2139
|
+
return false;
|
|
2140
|
+
return names.every((key) => value[key] === "" || (key === "country" ? typeof value[key] === "string" && COUNTRY.test(value[key]) : plainText2(value[key])));
|
|
2141
|
+
}
|
|
2142
|
+
function pageUrl(value) {
|
|
2143
|
+
if (typeof value !== "string" || value.length > 2048 || CONTROL5.test(value) || holdsCardShape(value, ANY_NETWORK) || !wellFormed(value))
|
|
2144
|
+
return false;
|
|
2145
|
+
let parsed;
|
|
2146
|
+
try {
|
|
2147
|
+
parsed = new URL(value);
|
|
2148
|
+
}
|
|
2149
|
+
catch {
|
|
2150
|
+
return false;
|
|
2151
|
+
}
|
|
2152
|
+
return parsed.protocol === "https:" || parsed.protocol === "http:";
|
|
2153
|
+
}
|
|
2154
|
+
function referrerOrigin(value) {
|
|
2155
|
+
if (value === "" || value === "null")
|
|
2156
|
+
return true;
|
|
2157
|
+
if (typeof value !== "string" || value.length > 512 || holdsCardShape(value, ANY_NETWORK))
|
|
2158
|
+
return false;
|
|
2159
|
+
let parsed;
|
|
2160
|
+
try {
|
|
2161
|
+
parsed = new URL(value);
|
|
2162
|
+
}
|
|
2163
|
+
catch {
|
|
2164
|
+
return false;
|
|
2165
|
+
}
|
|
2166
|
+
return (parsed.protocol === "https:" || parsed.protocol === "http:") && parsed.origin === value;
|
|
2167
|
+
}
|
|
2168
|
+
function environment(value) {
|
|
2169
|
+
if (!record10(value) || !inOrder(value, ENVIRONMENT_KEYS))
|
|
2170
|
+
return false;
|
|
2171
|
+
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));
|
|
2172
|
+
}
|
|
2173
|
+
function customer(value) {
|
|
2174
|
+
if (!record10(value))
|
|
2175
|
+
return false;
|
|
2176
|
+
if (value.type === "existing") {
|
|
2177
|
+
const names = Object.keys(value);
|
|
2178
|
+
return names.length === 2 && names[0] === "type" && names[1] === "id" && typeof value.id === "string" && UUID.test(value.id);
|
|
2179
|
+
}
|
|
2180
|
+
if (value.type !== "new" || !inOrder(value, NEW_CUSTOMER_KEYS) || !own2(value, "email"))
|
|
2181
|
+
return false;
|
|
2182
|
+
if (typeof value.email !== "string" || !EMAIL3.test(value.email) || !plainText2(value.email))
|
|
2183
|
+
return false;
|
|
2184
|
+
if (own2(value, "name") && !plainText2(value.name))
|
|
2185
|
+
return false;
|
|
2186
|
+
return !own2(value, "phone") || phone(value.phone);
|
|
2187
|
+
}
|
|
2188
|
+
function cardMethod(value) {
|
|
2189
|
+
if (!record10(value) || value.type !== "card")
|
|
2190
|
+
return "revolut_body_unsupported";
|
|
2191
|
+
if (!inOrder(value, REVOLUT_CARD_FIELD_KEYS) && !inOrder(value, REVOLUT_CARD_POPUP_KEYS))
|
|
2192
|
+
return "revolut_body_unsupported";
|
|
2193
|
+
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))
|
|
2194
|
+
return "revolut_body_unsupported";
|
|
2195
|
+
if (!own2(value, "environment") || !environment(value.environment))
|
|
2196
|
+
return "revolut_body_unsupported";
|
|
2197
|
+
if (own2(value, "kount_session_id") && (typeof value.kount_session_id !== "string" || !KOUNT_SESSION.test(value.kount_session_id))) {
|
|
2198
|
+
return "revolut_body_unsupported";
|
|
2199
|
+
}
|
|
2200
|
+
for (const key of ["billing_address", "shipping_address"]) {
|
|
2201
|
+
if (own2(value, key) && !address(value[key]))
|
|
2202
|
+
return "revolut_body_unsupported";
|
|
2203
|
+
}
|
|
2204
|
+
if (own2(value, "cardholder_name") && !plainText2(value.cardholder_name))
|
|
2205
|
+
return "revolut_body_unsupported";
|
|
2206
|
+
if (own2(value, "save_for")) {
|
|
2207
|
+
if (value.save_for === "CUSTOMER" || value.save_for === "MERCHANT")
|
|
2208
|
+
return "revolut_card_on_file";
|
|
2209
|
+
if (value.save_for !== "NONE")
|
|
2210
|
+
return "revolut_body_unsupported";
|
|
2211
|
+
}
|
|
2212
|
+
return null;
|
|
2213
|
+
}
|
|
2214
|
+
function namesCardValue2(parsed) {
|
|
2215
|
+
const pending = record10(parsed) || Array.isArray(parsed) ? [parsed] : [];
|
|
2216
|
+
while (pending.length > 0) {
|
|
2217
|
+
const node = pending.pop();
|
|
2218
|
+
for (const key of Object.keys(node)) {
|
|
2219
|
+
if (!Array.isArray(node) && CARD_MEMBER2.test(key))
|
|
2220
|
+
return true;
|
|
2221
|
+
const value = node[key];
|
|
2222
|
+
if (value !== null && typeof value === "object")
|
|
2223
|
+
pending.push(value);
|
|
2224
|
+
}
|
|
2225
|
+
}
|
|
2226
|
+
return false;
|
|
2227
|
+
}
|
|
2228
|
+
function revolutBodyVerdict(body) {
|
|
2229
|
+
const value = readBody7(body);
|
|
2230
|
+
if (value === null) {
|
|
2231
|
+
return body === void 0 || body === null || body === "" ? CONTINUE7 : refuse16("revolut_body_unsupported");
|
|
2232
|
+
}
|
|
2233
|
+
const method = record10(value.payment_method) ? value.payment_method.type : void 0;
|
|
2234
|
+
if (method !== "card")
|
|
2235
|
+
return namesCardValue2(value) ? refuse16("revolut_body_unsupported") : CONTINUE7;
|
|
2236
|
+
if (!inOrder(value, REVOLUT_BODY_KEYS) || Object.keys(value).length !== REVOLUT_BODY_KEYS.length)
|
|
2237
|
+
return refuse16("revolut_body_unsupported");
|
|
2238
|
+
const code = cardMethod(value.payment_method);
|
|
2239
|
+
if (code !== null)
|
|
2240
|
+
return refuse16(code);
|
|
2241
|
+
if (!customer(value.customer) || !between(value.amount, 1, AMOUNT_LIMIT) || !REVOLUT_CHANNELS.includes(value.channel)) {
|
|
2242
|
+
return refuse16("revolut_body_unsupported");
|
|
2243
|
+
}
|
|
2244
|
+
return CARD15;
|
|
2245
|
+
}
|
|
2246
|
+
// src/sumup.js
|
|
2247
|
+
var SUMUP_PSP = "sumup";
|
|
2248
|
+
var SUMUP_API_HOST = "api.sumup.com";
|
|
2249
|
+
var SUMUP_CHECKOUT_PATH = "/v0.2/checkouts/";
|
|
2250
|
+
var BODY_LIMIT13 = 16384;
|
|
2251
|
+
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;
|
|
2252
|
+
var ROOT_KEYS5 = /* @__PURE__ */ Object.freeze([
|
|
2253
|
+
"payment_type",
|
|
2254
|
+
"device_information",
|
|
2255
|
+
"method_details",
|
|
2256
|
+
"personal_details",
|
|
2257
|
+
"card",
|
|
2258
|
+
"installments",
|
|
2259
|
+
"mandate",
|
|
2260
|
+
"lxn_session_token",
|
|
2261
|
+
"customer_details",
|
|
2262
|
+
"sca_experience"
|
|
2263
|
+
]);
|
|
2264
|
+
var CARD_KEYS7 = /* @__PURE__ */ Object.freeze(["zip_code", "name", "number", "expiry_month", "expiry_year", "cvv"]);
|
|
2265
|
+
var PERSONAL_KEYS = /* @__PURE__ */ Object.freeze(["first_name", "last_name", "email", "address", "birth_date", "phone"]);
|
|
2266
|
+
var ADDRESS_KEYS2 = /* @__PURE__ */ Object.freeze(["country", "city", "line1", "line2", "postal_code", "state"]);
|
|
2267
|
+
var CUSTOMER_KEYS = /* @__PURE__ */ Object.freeze(["first_name", "last_name", "email", "note_for_merchant"]);
|
|
2268
|
+
var CARD_NUMBER9 = /^[0-9]{12,19}$/;
|
|
2269
|
+
var MONTH7 = /^(?:0[1-9]|1[0-2])$/;
|
|
2270
|
+
var YEAR7 = /^(?:[0-9]{2}|[0-9]{4})$/;
|
|
2271
|
+
var CODE2 = /^[0-9]{3,4}$/;
|
|
2272
|
+
var BASE643 = /^[A-Za-z0-9+/]{4,4096}={0,2}$/;
|
|
2273
|
+
var BASE64_ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
2274
|
+
var DEVICE_KEYS2 = /* @__PURE__ */ Object.freeze([
|
|
2275
|
+
"user_agent",
|
|
2276
|
+
"language",
|
|
2277
|
+
"timezone_offset",
|
|
2278
|
+
"screen_width",
|
|
2279
|
+
"screen_height",
|
|
2280
|
+
"color_depth",
|
|
2281
|
+
"modal_width",
|
|
2282
|
+
"modal_height",
|
|
2283
|
+
"adblock",
|
|
2284
|
+
"realIp",
|
|
2285
|
+
"route"
|
|
2286
|
+
]);
|
|
2287
|
+
var RISK_TOKEN = /^[A-Za-z0-9_+/=-]+\.[A-Za-z0-9_+/=-]+\.[A-Za-z0-9_+/=-]*$/;
|
|
2288
|
+
var RISK_TOKEN_LIMIT = 4096;
|
|
2289
|
+
var PAN_LIKE4 = /(?:[0-9][ _.:-]*){12,}/;
|
|
2290
|
+
var DATE = /^[0-9]{4}-[0-9]{2}-[0-9]{2}$/;
|
|
2291
|
+
var COUNTRY2 = /^[A-Z]{2}$/;
|
|
2292
|
+
var PHONE2 = /^[ #0-9_+\/().-]{1,32}$/;
|
|
2293
|
+
var CARD_PAYMENT2 = "card";
|
|
2294
|
+
var SCA_EXPERIENCE = "iframe";
|
|
2295
|
+
var record11 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
2296
|
+
var refuse17 = (code) => Object.freeze({ verdict: "refuse", code });
|
|
2297
|
+
var CARD16 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
|
|
2298
|
+
function orderedSubset(value, keys) {
|
|
2299
|
+
let at = -1;
|
|
2300
|
+
for (const key of Object.keys(value)) {
|
|
2301
|
+
const next = keys.indexOf(key);
|
|
2302
|
+
if (next <= at)
|
|
2303
|
+
return false;
|
|
2304
|
+
at = next;
|
|
2305
|
+
}
|
|
2306
|
+
return true;
|
|
2307
|
+
}
|
|
2308
|
+
function luhn3(digits) {
|
|
2309
|
+
let sum = 0;
|
|
2310
|
+
for (let at = 0; at < digits.length; at += 1) {
|
|
2311
|
+
let digit = Number(digits[digits.length - 1 - at]);
|
|
2312
|
+
if (at % 2 === 1) {
|
|
2313
|
+
digit *= 2;
|
|
2314
|
+
if (digit > 9)
|
|
2315
|
+
digit -= 9;
|
|
2316
|
+
}
|
|
2317
|
+
sum += digit;
|
|
2318
|
+
}
|
|
2319
|
+
return sum % 10 === 0 && sum > 0;
|
|
2320
|
+
}
|
|
2321
|
+
var printable = (value) => [...value].every((ch) => ch.charCodeAt(0) >= 32 && ch.charCodeAt(0) !== 127);
|
|
2322
|
+
function typed(value, limit = 256) {
|
|
2323
|
+
return typeof value === "string" && value.length >= 1 && value.length <= limit && !PAN_LIKE4.test(value) && printable(value);
|
|
2324
|
+
}
|
|
2325
|
+
function decodeBase64(text3) {
|
|
2326
|
+
if (typeof text3 !== "string" || !BASE643.test(text3) || text3.length % 4 !== 0)
|
|
2327
|
+
return null;
|
|
2328
|
+
let bits = 0;
|
|
2329
|
+
let value = 0;
|
|
2330
|
+
let out = "";
|
|
2331
|
+
for (const ch of text3.replace(/=+$/, "")) {
|
|
2332
|
+
value = (value << 6 | BASE64_ALPHABET.indexOf(ch)) & 16777215;
|
|
2333
|
+
bits += 6;
|
|
2334
|
+
if (bits >= 8) {
|
|
2335
|
+
bits -= 8;
|
|
2336
|
+
out += String.fromCharCode(value >> bits & 255);
|
|
2337
|
+
}
|
|
2338
|
+
}
|
|
2339
|
+
return out;
|
|
2340
|
+
}
|
|
2341
|
+
function soundDevice(text3) {
|
|
2342
|
+
const json = decodeBase64(text3);
|
|
2343
|
+
if (json === null)
|
|
2344
|
+
return false;
|
|
2345
|
+
let value;
|
|
2346
|
+
try {
|
|
2347
|
+
value = JSON.parse(json);
|
|
2348
|
+
if (JSON.stringify(value) !== json)
|
|
2349
|
+
return false;
|
|
2350
|
+
}
|
|
2351
|
+
catch {
|
|
2352
|
+
return false;
|
|
2353
|
+
}
|
|
2354
|
+
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) {
|
|
2355
|
+
return false;
|
|
2356
|
+
}
|
|
2357
|
+
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));
|
|
2358
|
+
}
|
|
2359
|
+
var soundRiskToken = (token) => typeof token === "string" && token.length <= RISK_TOKEN_LIMIT && RISK_TOKEN.test(token) && !PAN_LIKE4.test(token);
|
|
2360
|
+
function sumupCheckoutUrl(url) {
|
|
2361
|
+
if (typeof url !== "string" || url.length > 256 || url.includes("#") || url.includes("?"))
|
|
2362
|
+
return null;
|
|
2363
|
+
let parsed;
|
|
2364
|
+
try {
|
|
2365
|
+
parsed = new URL(url);
|
|
2366
|
+
}
|
|
2367
|
+
catch {
|
|
2368
|
+
return null;
|
|
2369
|
+
}
|
|
2370
|
+
if (parsed.href !== url || parsed.protocol !== "https:" || parsed.port || parsed.username || parsed.password)
|
|
2371
|
+
return null;
|
|
2372
|
+
if (parsed.hostname !== SUMUP_API_HOST || !parsed.pathname.startsWith(SUMUP_CHECKOUT_PATH))
|
|
2373
|
+
return null;
|
|
2374
|
+
const checkoutId = parsed.pathname.slice(SUMUP_CHECKOUT_PATH.length);
|
|
2375
|
+
return CHECKOUT_ID.test(checkoutId) ? Object.freeze({ checkoutId }) : null;
|
|
2376
|
+
}
|
|
2377
|
+
function readBody8(body) {
|
|
2378
|
+
if (typeof body !== "string" || body === "" || body.length > BODY_LIMIT13)
|
|
2379
|
+
return null;
|
|
2380
|
+
let value;
|
|
2381
|
+
try {
|
|
2382
|
+
value = JSON.parse(body);
|
|
2383
|
+
if (!record11(value) || JSON.stringify(value) !== body)
|
|
2384
|
+
return null;
|
|
2385
|
+
}
|
|
2386
|
+
catch {
|
|
2387
|
+
return null;
|
|
2388
|
+
}
|
|
2389
|
+
return value;
|
|
2390
|
+
}
|
|
2391
|
+
function soundCard(card) {
|
|
2392
|
+
if (!record11(card) || !orderedSubset(card, CARD_KEYS7))
|
|
2393
|
+
return false;
|
|
2394
|
+
if (typeof card.number !== "string" || !CARD_NUMBER9.test(card.number) || !luhn3(card.number))
|
|
2395
|
+
return false;
|
|
2396
|
+
if (typeof card.expiry_month !== "string" || !MONTH7.test(card.expiry_month))
|
|
2397
|
+
return false;
|
|
2398
|
+
if (typeof card.expiry_year !== "string" || !YEAR7.test(card.expiry_year))
|
|
2399
|
+
return false;
|
|
2400
|
+
if (typeof card.cvv !== "string" || !CODE2.test(card.cvv))
|
|
2401
|
+
return false;
|
|
2402
|
+
if (card.name !== void 0 && (!typed(card.name, 129) || /[0-9]/.test(card.name)))
|
|
2403
|
+
return false;
|
|
2404
|
+
if (card.zip_code !== void 0 && !typed(card.zip_code, 10))
|
|
2405
|
+
return false;
|
|
2406
|
+
return true;
|
|
2407
|
+
}
|
|
2408
|
+
function soundPersonal(details) {
|
|
2409
|
+
if (!record11(details) || !orderedSubset(details, PERSONAL_KEYS) || Object.keys(details).length === 0)
|
|
2410
|
+
return false;
|
|
2411
|
+
for (const key of ["first_name", "last_name", "email"]) {
|
|
2412
|
+
if (details[key] !== void 0 && !typed(details[key]))
|
|
2413
|
+
return false;
|
|
2414
|
+
}
|
|
2415
|
+
if (details.birth_date !== void 0 && (typeof details.birth_date !== "string" || !DATE.test(details.birth_date)))
|
|
2416
|
+
return false;
|
|
2417
|
+
if (details.phone !== void 0 && (typeof details.phone !== "string" || !PHONE2.test(details.phone) || (details.phone.match(/[0-9]/g) ?? []).length > 15))
|
|
2418
|
+
return false;
|
|
2419
|
+
if (details.address === void 0)
|
|
2420
|
+
return true;
|
|
2421
|
+
const address2 = details.address;
|
|
2422
|
+
if (!record11(address2) || !orderedSubset(address2, ADDRESS_KEYS2) || Object.keys(address2).length === 0)
|
|
2423
|
+
return false;
|
|
2424
|
+
if (address2.country !== void 0 && (typeof address2.country !== "string" || !COUNTRY2.test(address2.country)))
|
|
2425
|
+
return false;
|
|
2426
|
+
return ["city", "line1", "line2", "postal_code", "state"].every((key) => address2[key] === void 0 || typed(address2[key]));
|
|
2427
|
+
}
|
|
2428
|
+
function soundCustomer(details) {
|
|
2429
|
+
if (!record11(details) || !orderedSubset(details, CUSTOMER_KEYS) || Object.keys(details).length === 0)
|
|
2430
|
+
return false;
|
|
2431
|
+
return CUSTOMER_KEYS.every((key) => details[key] === void 0 || typed(details[key], key === "note_for_merchant" ? 1024 : 256));
|
|
2432
|
+
}
|
|
2433
|
+
function sumupBodyVerdict(body, url) {
|
|
2434
|
+
if (url !== void 0 && sumupCheckoutUrl(url) === null)
|
|
2435
|
+
return refuse17("sumup_url_refused");
|
|
2436
|
+
const value = readBody8(body);
|
|
2437
|
+
if (value === null || !orderedSubset(value, ROOT_KEYS5))
|
|
2438
|
+
return refuse17("sumup_body_unsupported");
|
|
2439
|
+
if (value.payment_type !== CARD_PAYMENT2 || !soundDevice(value.device_information) || !soundCard(value.card) || value.installments !== 1) {
|
|
2440
|
+
return refuse17("sumup_body_unsupported");
|
|
2441
|
+
}
|
|
2442
|
+
if (value.method_details !== void 0 && !(record11(value.method_details) && orderedSubset(value.method_details, ["zip_code"]) && typed(value.method_details.zip_code, 10)))
|
|
2443
|
+
return refuse17("sumup_body_unsupported");
|
|
2444
|
+
if (value.personal_details !== void 0 && !soundPersonal(value.personal_details))
|
|
2445
|
+
return refuse17("sumup_body_unsupported");
|
|
2446
|
+
if (value.customer_details !== void 0 && !soundCustomer(value.customer_details))
|
|
2447
|
+
return refuse17("sumup_body_unsupported");
|
|
2448
|
+
if (value.lxn_session_token !== void 0 && !soundRiskToken(value.lxn_session_token))
|
|
2449
|
+
return refuse17("sumup_body_unsupported");
|
|
2450
|
+
if (value.sca_experience !== void 0 && value.sca_experience !== SCA_EXPERIENCE)
|
|
2451
|
+
return refuse17("sumup_body_unsupported");
|
|
2452
|
+
if (value.mandate !== void 0)
|
|
2453
|
+
return refuse17("sumup_card_saving_refused");
|
|
2454
|
+
return CARD16;
|
|
2455
|
+
}
|
|
2456
|
+
// src/twoc2p-secure-pay.js
|
|
2457
|
+
var SALTED = /* @__PURE__ */ Object.freeze([83, 97, 108, 116, 101, 100, 95, 95]);
|
|
2458
|
+
var B64 = /^[A-Za-z0-9+/]+={0,2}$/;
|
|
2459
|
+
var FIELD_LIMIT = 1024;
|
|
2460
|
+
function decodeCanonical(text3) {
|
|
2461
|
+
if (typeof text3 !== "string" || text3.length === 0 || text3.length % 4 !== 0 || !B64.test(text3))
|
|
2462
|
+
return null;
|
|
2463
|
+
let binary;
|
|
2464
|
+
try {
|
|
2465
|
+
binary = atob(text3);
|
|
2466
|
+
}
|
|
2467
|
+
catch {
|
|
2468
|
+
return null;
|
|
2469
|
+
}
|
|
2470
|
+
if (btoa(binary) !== text3)
|
|
2471
|
+
return null;
|
|
2472
|
+
return Uint8Array.from(binary, (char) => char.charCodeAt(0));
|
|
2473
|
+
}
|
|
2474
|
+
function twoC2pSecurePayParts(value) {
|
|
2475
|
+
if (typeof value !== "string" || value.length > FIELD_LIMIT || !/^[0-9a-f]{4}/.test(value))
|
|
2476
|
+
return null;
|
|
2477
|
+
const length = parseInt(value.slice(0, 4), 16);
|
|
2478
|
+
if (length < 4 || 4 + length >= value.length)
|
|
2479
|
+
return null;
|
|
2480
|
+
const rsaText = value.slice(4, 4 + length);
|
|
2481
|
+
const rsa = decodeCanonical(rsaText);
|
|
2482
|
+
const cipher = decodeCanonical(value.slice(4 + length));
|
|
2483
|
+
if (!rsa || !cipher || cipher.length < 32 || cipher.length > 80 || cipher.length % 16 !== 0)
|
|
2484
|
+
return null;
|
|
2485
|
+
if (!SALTED.every((byte, at) => cipher[at] === byte))
|
|
2486
|
+
return null;
|
|
2487
|
+
return { rsaText, rsa, salt: cipher.slice(8, 16), blocks: (cipher.length - 16) / 16 };
|
|
2488
|
+
}
|
|
2489
|
+
function isTwoC2pPageField(value, keyBytes) {
|
|
2490
|
+
const parts = twoC2pSecurePayParts(value);
|
|
2491
|
+
if (!parts || !Number.isInteger(keyBytes) || keyBytes < 128)
|
|
2492
|
+
return false;
|
|
2493
|
+
const expected = Math.ceil(keyBytes / 3) * 4;
|
|
2494
|
+
return parts.rsaText.length === expected && (parts.rsa.length === keyBytes || parts.rsa.length === keyBytes - 1);
|
|
2495
|
+
}
|
|
2496
|
+
// src/twoc2p-keys.js
|
|
2497
|
+
var TWOC2P_KEYS = /* @__PURE__ */ Object.freeze({
|
|
2498
|
+
production: Object.freeze({
|
|
2499
|
+
spki: "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC/1ljsxI+r6qQraTFrHfWNrV41vxumBF+4ILAG3WsN6HEBQU2wSUv/IyQmZkiys1ilOb+OOuQTH8OXMnqQg9E4epyePW3L7IeOieSbIIDeSX6UpTWmT/Fs7moWZkN8RpuCV0u87n3AY2tQbtcSqwEKi2sxzWLFwscoGn6N5yVIpQIDAQAB",
|
|
2500
|
+
sha256: "bb8f27929ce140c6ef0ec9c4a20d7ca0b83376bc35a501985dc40d16669384fe",
|
|
2501
|
+
script: Object.freeze({ url: "https://t.2c2p.com/SecurePayment/api/my2c2p.1.7.6.min.js", sha256: "4a745a37765a2e28e299d64f6ea5811aab27b176da61db6f840fa85d6a47e763" })
|
|
2502
|
+
}),
|
|
2503
|
+
sandbox: Object.freeze({
|
|
2504
|
+
spki: "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDKakJC+2MSZikKoPzlNqXvJCuWNLhejg3gMRePSetYNNgnhyqFwwAR7t7i/B2QFZoixSYc2/23cJz0jA5O+q+Cu3fycqKlf1L9966+X3B9nyHe2eKQZr8KrcS/8+sEKcd0pLATY4AleW1iktuN+2oghrDKuv+aDNztWcOy+PTofwIDAQAB",
|
|
2505
|
+
sha256: "7f80c07f1d72db28ede10dae942940657c72dfa789836c9fdf283cba6feff2e6",
|
|
2506
|
+
script: Object.freeze({ url: "https://demo2.2c2p.com/2C2PFrontEnd/SecurePayment/api/my2c2p.1.7.6.min.js", sha256: "435723d92bfefb00607a56851967e0b745d52b8d49443de5f0000f0583fde5cc" })
|
|
2507
|
+
})
|
|
2508
|
+
});
|
|
2509
|
+
function twoC2pKey(environment2) {
|
|
2510
|
+
if (environment2 !== "production" && environment2 !== "sandbox")
|
|
2511
|
+
return null;
|
|
2512
|
+
return TWOC2P_KEYS[environment2] ?? null;
|
|
2513
|
+
}
|
|
2514
|
+
function twoC2pKeyBytes(environment2) {
|
|
2515
|
+
const key = twoC2pKey(environment2);
|
|
2516
|
+
if (!key)
|
|
2517
|
+
return null;
|
|
2518
|
+
try {
|
|
2519
|
+
return parseRsaPublicKey(key).size;
|
|
2520
|
+
}
|
|
2521
|
+
catch {
|
|
2522
|
+
return null;
|
|
2523
|
+
}
|
|
2524
|
+
}
|
|
2525
|
+
// src/twoc2p.js
|
|
2526
|
+
var TWOC2P_PSP = "twoc2p";
|
|
2527
|
+
var TWOC2P_FIELD = "securePayToken";
|
|
2528
|
+
var TWOC2P_REVIEWED_BUILDS = /* @__PURE__ */ Object.freeze(["4.1", "4.2", "4.3", "4.4", "4.5"]);
|
|
2529
|
+
var record12 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
2530
|
+
var refuse18 = (code) => Object.freeze({ verdict: "refuse", code });
|
|
2531
|
+
var CARD17 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
|
|
2532
|
+
var CONTINUE8 = /* @__PURE__ */ Object.freeze({ verdict: "continue" });
|
|
2533
|
+
var PAYMENT_URL = /^https:\/\/(sandbox-)?pgwv4\.2c2p\.com\/payment\/(4\.[0-9]{1,2})\/Payment$/;
|
|
2534
|
+
function twoC2pPaymentTarget(url) {
|
|
2535
|
+
const match = typeof url === "string" ? PAYMENT_URL.exec(url) : null;
|
|
2536
|
+
if (!match)
|
|
2537
|
+
return null;
|
|
2538
|
+
return Object.freeze({ environment: match[1] ? "sandbox" : "production", version: match[2], reviewed: TWOC2P_REVIEWED_BUILDS.includes(match[2]) });
|
|
2539
|
+
}
|
|
2540
|
+
function twoC2pPaymentCarriesCard(body) {
|
|
2541
|
+
if (typeof body !== "string")
|
|
2542
|
+
return true;
|
|
2543
|
+
try {
|
|
2544
|
+
return JSON.stringify(JSON.parse(body)).includes(`"${TWOC2P_FIELD}"`);
|
|
2545
|
+
}
|
|
2546
|
+
catch {
|
|
2547
|
+
return true;
|
|
2548
|
+
}
|
|
2549
|
+
}
|
|
2550
|
+
var ROOT_KEYS6 = /* @__PURE__ */ Object.freeze(["paymentToken", "clientIP", "locale", "responseReturnUrl", "clientID", "payment"]);
|
|
2551
|
+
var CODE_KEYS = /* @__PURE__ */ Object.freeze(["channelCode", "agentCode", "agentChannelCode"]);
|
|
2552
|
+
var DATA_KEYS2 = /* @__PURE__ */ Object.freeze([
|
|
2553
|
+
"name",
|
|
2554
|
+
"isIppChosen",
|
|
2555
|
+
"cardDetails",
|
|
2556
|
+
"loyaltyPoints",
|
|
2557
|
+
"fxRateID",
|
|
2558
|
+
"email",
|
|
2559
|
+
"mobileNo",
|
|
2560
|
+
"mobileNoPrefix",
|
|
2561
|
+
"customerNote",
|
|
2562
|
+
"paymentExpiry",
|
|
2563
|
+
"securePayToken",
|
|
2564
|
+
"cardTokenize",
|
|
2565
|
+
"accountTokenization",
|
|
2566
|
+
"token",
|
|
2567
|
+
"customerToken",
|
|
2568
|
+
"accountNo",
|
|
2569
|
+
"installmentPeriod",
|
|
2570
|
+
"interestType",
|
|
2571
|
+
"payLaterPeriod",
|
|
2572
|
+
"billingAddress1",
|
|
2573
|
+
"billingAddress2",
|
|
2574
|
+
"billingCity",
|
|
2575
|
+
"billingState",
|
|
2576
|
+
"billingCountryCode",
|
|
2577
|
+
"billingPostalCode",
|
|
2578
|
+
"riskInfo"
|
|
2579
|
+
]);
|
|
2580
|
+
var RISK_KEYS = /* @__PURE__ */ Object.freeze(["customer_id", "shipping_method", "deviceSessionId", "customData"]);
|
|
2581
|
+
var BODY_LIMIT14 = 16384;
|
|
2582
|
+
var CONTROL6 = /[\u0000-\u001f\u007f]/;
|
|
2583
|
+
var CARD_LIKE = /(?:[0-9][ _.:/-]*){12,}/;
|
|
2584
|
+
var PAYMENT_TOKEN = /^[A-Za-z0-9+/]{16,1000}={0,2}$/;
|
|
2585
|
+
var UUID2 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
2586
|
+
var IP = /^[0-9A-Fa-f.:]{2,45}$/;
|
|
2587
|
+
var LOCALE2 = /^[A-Za-z]{2,3}(?:[-_][A-Za-z0-9]{2,8})?$/;
|
|
2588
|
+
var AGENT = /^[A-Za-z0-9_]{1,32}$/;
|
|
2589
|
+
var RISK_TOKEN2 = /^[\x21-\x7e]{1,512}$/;
|
|
2590
|
+
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})?$/;
|
|
2591
|
+
var PAGE_HOSTS = /* @__PURE__ */ Object.freeze({ production: "pgw-ui.2c2p.com", sandbox: "sandbox-pgw-ui.2c2p.com" });
|
|
2592
|
+
var returnUrlTaken = (value, paymentToken, environment2) => {
|
|
2593
|
+
if (value === void 0)
|
|
2594
|
+
return true;
|
|
2595
|
+
const match = typeof value === "string" ? RETURN_URL.exec(value) : null;
|
|
2596
|
+
return !!match && (match[2] === void 0 || match[2] === paymentToken) && (environment2 === void 0 || match[1] === PAGE_HOSTS[environment2]);
|
|
2597
|
+
};
|
|
2598
|
+
var inOrder2 = (value, order) => {
|
|
2599
|
+
let at = -1;
|
|
2600
|
+
for (const key of Object.keys(value)) {
|
|
2601
|
+
const next = order.indexOf(key);
|
|
2602
|
+
if (next <= at)
|
|
2603
|
+
return false;
|
|
2604
|
+
at = next;
|
|
2605
|
+
}
|
|
2606
|
+
return true;
|
|
2607
|
+
};
|
|
2608
|
+
var text2 = (value, limit) => typeof value === "string" && value.length <= limit && !CONTROL6.test(value) && !CARD_LIKE.test(value);
|
|
2609
|
+
var optionalText = (value, limit) => value === void 0 || text2(value, limit);
|
|
2610
|
+
function twoC2pBodyVerdict(body, keyBytes = 128, environment2 = void 0) {
|
|
2611
|
+
if (!twoC2pPaymentCarriesCard(body))
|
|
2612
|
+
return CONTINUE8;
|
|
2613
|
+
if (typeof body !== "string" || body.length > BODY_LIMIT14)
|
|
2614
|
+
return refuse18("twoc2p_body_unsupported");
|
|
2615
|
+
let value;
|
|
2616
|
+
try {
|
|
2617
|
+
value = JSON.parse(body);
|
|
2618
|
+
}
|
|
2619
|
+
catch {
|
|
2620
|
+
return refuse18("twoc2p_body_unsupported");
|
|
2621
|
+
}
|
|
2622
|
+
if (!record12(value) || JSON.stringify(value) !== body || !inOrder2(value, ROOT_KEYS6))
|
|
2623
|
+
return refuse18("twoc2p_body_unsupported");
|
|
2624
|
+
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)))
|
|
2625
|
+
return refuse18("twoc2p_body_unsupported");
|
|
2626
|
+
const payment = value.payment;
|
|
2627
|
+
if (!record12(payment) || Object.keys(payment).join(",") !== "code,data")
|
|
2628
|
+
return refuse18("twoc2p_body_unsupported");
|
|
2629
|
+
const code = payment.code;
|
|
2630
|
+
const data = payment.data;
|
|
2631
|
+
if (!record12(code) || !record12(data))
|
|
2632
|
+
return refuse18("twoc2p_body_unsupported");
|
|
2633
|
+
if (Object.prototype.hasOwnProperty.call(code, "subChannelCode"))
|
|
2634
|
+
return refuse18("twoc2p_stored_card");
|
|
2635
|
+
if (code.channelCode === "IPP" || code.channelCode === "LIPP")
|
|
2636
|
+
return refuse18("twoc2p_installments");
|
|
2637
|
+
if (!inOrder2(code, CODE_KEYS) || code.channelCode === void 0)
|
|
2638
|
+
return refuse18("twoc2p_body_unsupported");
|
|
2639
|
+
if (code.channelCode !== "CC")
|
|
2640
|
+
return refuse18("twoc2p_channel_unsupported");
|
|
2641
|
+
if ([code.agentCode, code.agentChannelCode].some((part) => part !== void 0 && !(typeof part === "string" && AGENT.test(part))))
|
|
2642
|
+
return refuse18("twoc2p_body_unsupported");
|
|
2643
|
+
return dataVerdict(data, keyBytes, body);
|
|
2644
|
+
}
|
|
2645
|
+
function dataVerdict(data, keyBytes, body) {
|
|
2646
|
+
if (data.cardTokenize !== void 0 || data.accountTokenization !== void 0)
|
|
2647
|
+
return refuse18("twoc2p_keeps_card");
|
|
2648
|
+
if (data.token !== void 0 || data.customerToken !== void 0)
|
|
2649
|
+
return refuse18("twoc2p_stored_card");
|
|
2650
|
+
if (data.accountNo !== void 0)
|
|
2651
|
+
return refuse18("twoc2p_card_in_clear");
|
|
2652
|
+
const details = data.cardDetails;
|
|
2653
|
+
if (record12(details) && (details.cardNo !== void 0 || details.accountNo !== void 0))
|
|
2654
|
+
return refuse18("twoc2p_card_in_clear");
|
|
2655
|
+
if (record12(details) && Object.keys(details).some((key) => key !== "email"))
|
|
2656
|
+
return refuse18("twoc2p_stored_card");
|
|
2657
|
+
if (data.isIppChosen === true || data.installmentPeriod !== void 0 || data.interestType !== void 0 || data.payLaterPeriod !== void 0) {
|
|
2658
|
+
return refuse18("twoc2p_installments");
|
|
2659
|
+
}
|
|
2660
|
+
if (data.fxRateID !== void 0)
|
|
2661
|
+
return refuse18("twoc2p_currency_conversion");
|
|
2662
|
+
if (data.loyaltyPoints !== void 0 && !(Array.isArray(data.loyaltyPoints) && data.loyaltyPoints.length === 0)) {
|
|
2663
|
+
return refuse18("twoc2p_loyalty_redemption");
|
|
2664
|
+
}
|
|
2665
|
+
if (!inOrder2(data, DATA_KEYS2) || data.paymentExpiry !== void 0)
|
|
2666
|
+
return refuse18("twoc2p_body_unsupported");
|
|
2667
|
+
if (typeof data.securePayToken !== "string" || !isTwoC2pPageField(data.securePayToken, keyBytes))
|
|
2668
|
+
return refuse18("twoc2p_field_unreviewed");
|
|
2669
|
+
if (body.split(data.securePayToken).length !== 2)
|
|
2670
|
+
return refuse18("twoc2p_body_unsupported");
|
|
2671
|
+
if (data.isIppChosen !== void 0 && data.isIppChosen !== false)
|
|
2672
|
+
return refuse18("twoc2p_body_unsupported");
|
|
2673
|
+
if (details !== void 0 && !(record12(details) && (details.email === void 0 || text2(details.email, 254))))
|
|
2674
|
+
return refuse18("twoc2p_body_unsupported");
|
|
2675
|
+
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))) {
|
|
2676
|
+
return refuse18("twoc2p_body_unsupported");
|
|
2677
|
+
}
|
|
2678
|
+
for (const key of ["billingAddress1", "billingAddress2", "billingCity", "billingState", "billingPostalCode"]) {
|
|
2679
|
+
if (!optionalText(data[key], 128))
|
|
2680
|
+
return refuse18("twoc2p_body_unsupported");
|
|
2681
|
+
}
|
|
2682
|
+
if (data.billingCountryCode !== void 0 && !(typeof data.billingCountryCode === "string" && /^[A-Za-z]{2}$/.test(data.billingCountryCode))) {
|
|
2683
|
+
return refuse18("twoc2p_body_unsupported");
|
|
2684
|
+
}
|
|
2685
|
+
const risk = data.riskInfo;
|
|
2686
|
+
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)) {
|
|
2687
|
+
return refuse18("twoc2p_body_unsupported");
|
|
2688
|
+
}
|
|
2689
|
+
return CARD17;
|
|
2690
|
+
}
|
|
2691
|
+
// src/hipay.js
|
|
2692
|
+
var HIPAY_PSP = "hipay";
|
|
2693
|
+
var HIPAY_TOKEN_URLS = /* @__PURE__ */ Object.freeze({
|
|
2694
|
+
production: "https://secure2-vault.hipay-tpp.com/rest/v2/token",
|
|
2695
|
+
sandbox: "https://stage-secure2-vault.hipay-tpp.com/rest/v2/token"
|
|
2696
|
+
});
|
|
2697
|
+
var BODY_LIMIT15 = 2048;
|
|
2698
|
+
var HOSTED_KEYS = /* @__PURE__ */ Object.freeze(["multi_use", "card_expiry_month", "card_expiry_year", "card_number", "card_holder", "cvc"]);
|
|
2699
|
+
var HOSTED_KEYS_NO_HOLDER = /* @__PURE__ */ Object.freeze(["multi_use", "card_expiry_month", "card_expiry_year", "card_number", "cvc"]);
|
|
2700
|
+
var DIRECT_KEYS = /* @__PURE__ */ Object.freeze(["card_expiry_month", "card_expiry_year", "card_number", "card_holder", "cvc", "multi_use"]);
|
|
2701
|
+
var DIRECT_KEYS_NO_HOLDER = /* @__PURE__ */ Object.freeze(["card_expiry_month", "card_expiry_year", "card_number", "cvc", "multi_use"]);
|
|
2702
|
+
var CARD_SHAPES = /* @__PURE__ */ Object.freeze([HOSTED_KEYS, HOSTED_KEYS_NO_HOLDER, DIRECT_KEYS, DIRECT_KEYS_NO_HOLDER]);
|
|
2703
|
+
var NUMBER_ONLY_KEYS = /* @__PURE__ */ Object.freeze(["multi_use", "card_expiry_month", "card_expiry_year", "card_number"]);
|
|
2704
|
+
var CARD_NUMBER10 = /^[0-9]{12,19}$/;
|
|
2705
|
+
var SECURITY_CODE12 = /^[0-9]{3,4}$/;
|
|
2706
|
+
var MONTH8 = /^(?:0[1-9]|1[0-2])$/;
|
|
2707
|
+
var YEAR8 = /^20[0-9]{2}$/;
|
|
2708
|
+
var TEXT_LIMIT3 = 256;
|
|
2709
|
+
var CONTROL7 = /[\u0000-\u001f\u007f]/;
|
|
2710
|
+
var record13 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
2711
|
+
var sameKeys7 = (value, keys) => {
|
|
2712
|
+
const own3 = Object.keys(value);
|
|
2713
|
+
return own3.length === keys.length && own3.every((key, at) => key === keys[at]);
|
|
2714
|
+
};
|
|
2715
|
+
var plainText3 = (value) => typeof value === "string" && value.length <= TEXT_LIMIT3 && !CONTROL7.test(value) && (value.match(/[0-9]/g) ?? []).length < 12;
|
|
2716
|
+
var refuse19 = (code) => Object.freeze({ verdict: "refuse", code });
|
|
2717
|
+
var CARD18 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
|
|
2718
|
+
function hipayTokenEnvironment(url) {
|
|
2719
|
+
if (url === HIPAY_TOKEN_URLS.production)
|
|
2720
|
+
return "production";
|
|
2721
|
+
if (url === HIPAY_TOKEN_URLS.sandbox)
|
|
2722
|
+
return "sandbox";
|
|
2723
|
+
return null;
|
|
2724
|
+
}
|
|
2725
|
+
function isHipayTokenUrl(url) {
|
|
2726
|
+
return hipayTokenEnvironment(url) !== null;
|
|
2727
|
+
}
|
|
2728
|
+
function readBody9(body) {
|
|
2729
|
+
if (typeof body !== "string" || body === "" || body.length > BODY_LIMIT15)
|
|
2730
|
+
return null;
|
|
2731
|
+
let value;
|
|
2732
|
+
try {
|
|
2733
|
+
value = JSON.parse(body);
|
|
2734
|
+
if (!record13(value) || JSON.stringify(value) !== body)
|
|
2735
|
+
return null;
|
|
2736
|
+
}
|
|
2737
|
+
catch {
|
|
2738
|
+
return null;
|
|
2739
|
+
}
|
|
2740
|
+
return value;
|
|
2741
|
+
}
|
|
2742
|
+
function hipayBodyVerdict(body) {
|
|
2743
|
+
const value = readBody9(body);
|
|
2744
|
+
if (value === null)
|
|
2745
|
+
return refuse19("hipay_body_unsupported");
|
|
2746
|
+
if (sameKeys7(value, NUMBER_ONLY_KEYS))
|
|
2747
|
+
return refuse19("hipay_number_only");
|
|
2748
|
+
if (!CARD_SHAPES.some((keys) => sameKeys7(value, keys)))
|
|
2749
|
+
return refuse19("hipay_body_unsupported");
|
|
2750
|
+
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)) {
|
|
2751
|
+
return refuse19("hipay_body_unsupported");
|
|
2752
|
+
}
|
|
2753
|
+
if (value.multi_use === 1)
|
|
2754
|
+
return refuse19("hipay_keeps_card");
|
|
2755
|
+
return value.multi_use === 0 ? CARD18 : refuse19("hipay_body_unsupported");
|
|
2756
|
+
}
|
|
2757
|
+
// src/amazon-payment-services.js
|
|
2758
|
+
var APS_PSP = "amazon_payment_services";
|
|
2759
|
+
var APS_HOSTS = /* @__PURE__ */ Object.freeze({ "checkout.payfort.com": "production", "sbcheckout.payfort.com": "sandbox" });
|
|
2760
|
+
var APS_TOKENIZATION_PATH = "/FortAPI/paymentPage";
|
|
2761
|
+
var APS_SIGNED_FIELDS = /* @__PURE__ */ Object.freeze([
|
|
2762
|
+
"service_command",
|
|
2763
|
+
"access_code",
|
|
2764
|
+
"merchant_identifier",
|
|
2765
|
+
"merchant_reference",
|
|
2766
|
+
"language",
|
|
2767
|
+
"return_url",
|
|
2768
|
+
"signature"
|
|
2769
|
+
]);
|
|
2770
|
+
var APS_CARD_FIELDS = /* @__PURE__ */ Object.freeze(["card_number", "expiry_date", "card_security_code"]);
|
|
2771
|
+
var APS_OPTIONAL_FIELDS = /* @__PURE__ */ Object.freeze(["card_holder_name", "remember_me"]);
|
|
2772
|
+
var URL_LIMIT7 = 2048;
|
|
2773
|
+
var BODY_LIMIT16 = 32 * 1024;
|
|
2774
|
+
var exact = (pattern, value) => typeof value === "string" && pattern.exec(value)?.[0] === value;
|
|
2775
|
+
var controlFree = (value, max) => typeof value === "string" && value.length <= max && !/[\u0000-\u001f\u007f]/.test(value);
|
|
2776
|
+
var SHAPES = /* @__PURE__ */ new Map([
|
|
2777
|
+
["service_command", (v) => v === "TOKENIZATION"],
|
|
2778
|
+
["access_code", (v) => exact(/^[A-Za-z0-9]{1,20}$/, v)],
|
|
2779
|
+
["merchant_identifier", (v) => exact(/^[A-Za-z0-9]{1,20}$/, v)],
|
|
2780
|
+
["merchant_reference", (v) => exact(/^[A-Za-z0-9._-]{1,40}$/, v)],
|
|
2781
|
+
["language", (v) => v === "en" || v === "ar"],
|
|
2782
|
+
// Hex SHA-256 (APS's default), SHA-512, or the 40 characters of the SHA-1 APS calls SHA-128.
|
|
2783
|
+
["signature", (v) => exact(/^(?:[0-9A-Fa-f]{40}|[0-9A-Fa-f]{64}|[0-9A-Fa-f]{128})$/, v)],
|
|
2784
|
+
["card_number", (v) => exact(/^[0-9]{12,19}$/, v)],
|
|
2785
|
+
["expiry_date", (v) => exact(/^[0-9]{2}(?:0[1-9]|1[0-2])$/, v)],
|
|
2786
|
+
["card_security_code", (v) => exact(/^[0-9]{3,4}$/, v)],
|
|
2787
|
+
["card_holder_name", (v) => controlFree(v, 255)],
|
|
2788
|
+
["remember_me", (v) => v === "YES" || v === "NO"]
|
|
2789
|
+
]);
|
|
2790
|
+
function apsTokenizationUrl(url) {
|
|
2791
|
+
if (typeof url !== "string" || url.length > URL_LIMIT7 || url.includes("?") || url.includes("#"))
|
|
2792
|
+
return null;
|
|
2793
|
+
let parsed;
|
|
2794
|
+
try {
|
|
2795
|
+
parsed = new URL(url);
|
|
2796
|
+
}
|
|
2797
|
+
catch {
|
|
2798
|
+
return null;
|
|
2799
|
+
}
|
|
2800
|
+
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))
|
|
2801
|
+
return null;
|
|
2802
|
+
return Object.freeze({ host: parsed.hostname, environment: APS_HOSTS[parsed.hostname] });
|
|
2803
|
+
}
|
|
2804
|
+
function formEncode2(value) {
|
|
2805
|
+
let encoded;
|
|
2806
|
+
try {
|
|
2807
|
+
encoded = encodeURIComponent(value);
|
|
2808
|
+
}
|
|
2809
|
+
catch {
|
|
2810
|
+
return null;
|
|
2811
|
+
}
|
|
2812
|
+
return encoded.replace(/[!'()~]/g, (ch) => `%${ch.charCodeAt(0).toString(16).toUpperCase()}`).replace(/%20/g, "+");
|
|
2813
|
+
}
|
|
2814
|
+
function formDecode(raw) {
|
|
2815
|
+
if (!/^(?:[A-Za-z0-9*._+-]|%[0-9A-F]{2})*$/.test(raw))
|
|
2816
|
+
return null;
|
|
2817
|
+
let value;
|
|
2818
|
+
try {
|
|
2819
|
+
value = decodeURIComponent(raw.replace(/\+/g, "%20"));
|
|
2820
|
+
}
|
|
2821
|
+
catch {
|
|
2822
|
+
return null;
|
|
2823
|
+
}
|
|
2824
|
+
return formEncode2(value) === raw ? value : null;
|
|
2825
|
+
}
|
|
2826
|
+
function parseForm(body) {
|
|
2827
|
+
if (typeof body !== "string" || body === "" || body.length > BODY_LIMIT16)
|
|
2828
|
+
return null;
|
|
2829
|
+
const pairs = [];
|
|
2830
|
+
const values = /* @__PURE__ */ new Map();
|
|
2831
|
+
for (const chunk of body.split("&")) {
|
|
2832
|
+
const separator = chunk.indexOf("=");
|
|
2833
|
+
if (separator < 1)
|
|
2834
|
+
return null;
|
|
2835
|
+
const rawName = chunk.slice(0, separator), raw = chunk.slice(separator + 1);
|
|
2836
|
+
const name = formDecode(rawName), value = formDecode(raw);
|
|
2837
|
+
if (name === null || value === null || values.has(name))
|
|
2838
|
+
return null;
|
|
2839
|
+
pairs.push({ name, rawName, raw, value });
|
|
2840
|
+
values.set(name, value);
|
|
2841
|
+
}
|
|
2842
|
+
return { pairs, values };
|
|
2843
|
+
}
|
|
2844
|
+
function returnUrlAdmitted(value) {
|
|
2845
|
+
if (typeof value !== "string" || value.length > 400 || value.includes("#") || /[\u0000- \u007f]/.test(value))
|
|
2846
|
+
return false;
|
|
2847
|
+
let parsed;
|
|
2848
|
+
try {
|
|
2849
|
+
parsed = new URL(value);
|
|
2850
|
+
}
|
|
2851
|
+
catch {
|
|
2852
|
+
return false;
|
|
2853
|
+
}
|
|
2854
|
+
return parsed.protocol === "https:" && !parsed.username && !parsed.password && parsed.href === value;
|
|
2855
|
+
}
|
|
2856
|
+
function apsBodyRefusal(body) {
|
|
2857
|
+
const form = parseForm(body);
|
|
2858
|
+
if (!form)
|
|
2859
|
+
return "aps_body_unsupported";
|
|
2860
|
+
const has = (name) => form.values.has(name);
|
|
2861
|
+
if (has("token_name"))
|
|
2862
|
+
return "aps_saved_card_refused";
|
|
2863
|
+
if ([...form.values.keys()].some((name) => /^merchant_extra[1-5]?$|^agreement_id$|^recurring_/.test(name)))
|
|
2864
|
+
return "aps_recurring_refused";
|
|
2865
|
+
if (has("service_command") && form.values.get("service_command") !== "TOKENIZATION")
|
|
2866
|
+
return "aps_service_command_refused";
|
|
2867
|
+
const allowed = /* @__PURE__ */ new Set([...APS_SIGNED_FIELDS, ...APS_CARD_FIELDS, ...APS_OPTIONAL_FIELDS]);
|
|
2868
|
+
if (form.pairs.some(({ name }) => !allowed.has(name)))
|
|
2869
|
+
return "aps_body_unsupported";
|
|
2870
|
+
if (!returnUrlAdmitted(form.values.get("return_url")))
|
|
2871
|
+
return "aps_return_url_refused";
|
|
2872
|
+
for (const name of [...APS_SIGNED_FIELDS, ...APS_CARD_FIELDS]) {
|
|
2873
|
+
if (name !== "return_url" && !SHAPES.get(name)(form.values.get(name)))
|
|
2874
|
+
return "aps_body_unsupported";
|
|
2875
|
+
}
|
|
2876
|
+
for (const name of APS_OPTIONAL_FIELDS) {
|
|
2877
|
+
if (has(name) && !SHAPES.get(name)(form.values.get(name)))
|
|
2878
|
+
return "aps_body_unsupported";
|
|
2879
|
+
}
|
|
2880
|
+
return null;
|
|
2881
|
+
}
|
|
2882
|
+
function apsBodyVerdict(body, url) {
|
|
2883
|
+
if (url !== void 0 && !apsTokenizationUrl(url))
|
|
2884
|
+
return { verdict: "refuse", code: "aps_url_refused" };
|
|
2885
|
+
const form = parseForm(body);
|
|
2886
|
+
const names = form ? [...form.values.keys()] : typeof body === "string" ? body.split("&").map((chunk) => {
|
|
2887
|
+
try {
|
|
2888
|
+
return decodeURIComponent(chunk.split("=")[0].replace(/\+/g, " "));
|
|
2889
|
+
}
|
|
2890
|
+
catch {
|
|
2891
|
+
return APS_CARD_FIELDS[0];
|
|
2892
|
+
}
|
|
2893
|
+
}) : [APS_CARD_FIELDS[0]];
|
|
2894
|
+
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));
|
|
2895
|
+
if (!mentionsCard && !names.some((name) => APS_CARD_FIELDS.includes(name.trim().toLowerCase())))
|
|
2896
|
+
return { verdict: "continue" };
|
|
2897
|
+
const code = apsBodyRefusal(body);
|
|
2898
|
+
return code ? { verdict: "refuse", code } : { verdict: "card" };
|
|
2899
|
+
}
|
|
2900
|
+
var ANSWER_LIMIT = 64 * 1024;
|
|
1997
2901
|
// src/card-fields.js
|
|
1998
2902
|
function processorGate(recognizer, url, body) {
|
|
1999
2903
|
if (recognizer && recognizer.psp === LYRA_PSP)
|
|
@@ -2005,6 +2909,11 @@ function processorGate(recognizer, url, body) {
|
|
|
2005
2909
|
}
|
|
2006
2910
|
if (recognizer && recognizer.psp === KOMOJU_PSP)
|
|
2007
2911
|
return komojuBodyVerdict(body, url);
|
|
2912
|
+
if (recognizer && recognizer.psp === HIPAY_PSP) {
|
|
2913
|
+
if (url !== void 0 && !isHipayTokenUrl(url))
|
|
2914
|
+
return { verdict: "refuse", code: "hipay_url_refused" };
|
|
2915
|
+
return hipayBodyVerdict(body);
|
|
2916
|
+
}
|
|
2008
2917
|
if (recognizer && recognizer.psp === PADDLE_VGS_PSP) {
|
|
2009
2918
|
if (url !== void 0 && !isPaddleVgsCardsUrl(url))
|
|
2010
2919
|
return { verdict: "refuse", code: "paddle_vgs_url_refused" };
|
|
@@ -2026,6 +2935,19 @@ function processorGate(recognizer, url, body) {
|
|
|
2026
2935
|
return { verdict: "refuse", code: "pay_nl_url_refused" };
|
|
2027
2936
|
return payNlBodyVerdict(body);
|
|
2028
2937
|
}
|
|
2938
|
+
if (recognizer && recognizer.psp === TWOC2P_PSP) {
|
|
2939
|
+
if (url === void 0)
|
|
2940
|
+
return twoC2pBodyVerdict(body);
|
|
2941
|
+
const target = twoC2pPaymentTarget(url);
|
|
2942
|
+
if (target === null)
|
|
2943
|
+
return { verdict: "refuse", code: "twoc2p_url_refused" };
|
|
2944
|
+
if (!target.reviewed)
|
|
2945
|
+
return twoC2pPaymentCarriesCard(body) ? { verdict: "refuse", code: "twoc2p_build_unreviewed" } : { verdict: "continue" };
|
|
2946
|
+
const keyBytes = twoC2pKeyBytes(target.environment);
|
|
2947
|
+
return keyBytes === null ? { verdict: "refuse", code: "twoc2p_field_unreviewed" } : twoC2pBodyVerdict(body, keyBytes, target.environment);
|
|
2948
|
+
}
|
|
2949
|
+
if (recognizer && recognizer.psp === APS_PSP)
|
|
2950
|
+
return apsBodyVerdict(body, url);
|
|
2029
2951
|
if (recognizer && recognizer.psp === PADDLE_TOKENEX_PSP) {
|
|
2030
2952
|
const target = url !== void 0 ? paddleTokenexPayTarget(url) : null;
|
|
2031
2953
|
if (url !== void 0 && target === null)
|
|
@@ -2040,6 +2962,13 @@ function processorGate(recognizer, url, body) {
|
|
|
2040
2962
|
}
|
|
2041
2963
|
if (recognizer && recognizer.psp === GOPAY_PSP)
|
|
2042
2964
|
return gopayBodyVerdict(body, url);
|
|
2965
|
+
if (recognizer && recognizer.psp === REVOLUT_PSP) {
|
|
2966
|
+
if (url !== void 0 && !isRevolutPaymentsUrl(url))
|
|
2967
|
+
return { verdict: "refuse", code: "revolut_url_refused" };
|
|
2968
|
+
return revolutBodyVerdict(body);
|
|
2969
|
+
}
|
|
2970
|
+
if (recognizer && recognizer.psp === SUMUP_PSP)
|
|
2971
|
+
return sumupBodyVerdict(body, url);
|
|
2043
2972
|
if (recognizer && recognizer.psp === GRAVY_PSP)
|
|
2044
2973
|
return gravyBodyVerdict(body);
|
|
2045
2974
|
if (recognizer && recognizer.psp === MONERIS_PSP) {
|
|
@@ -2157,7 +3086,7 @@ function splitCardLeg(recognizer, body) {
|
|
|
2157
3086
|
const absorb = list(split.absorb);
|
|
2158
3087
|
const pass = list(split.pass);
|
|
2159
3088
|
const sibling = list(split.siblingKeys);
|
|
2160
|
-
const
|
|
3089
|
+
const own3 = [];
|
|
2161
3090
|
const seen = /* @__PURE__ */ new Set();
|
|
2162
3091
|
for (const chunk of body.split("&")) {
|
|
2163
3092
|
const eq = chunk.indexOf("=");
|
|
@@ -2174,13 +3103,13 @@ function splitCardLeg(recognizer, body) {
|
|
|
2174
3103
|
return null;
|
|
2175
3104
|
seen.add(key);
|
|
2176
3105
|
if (!sibling.includes(key))
|
|
2177
|
-
|
|
3106
|
+
own3.push(key);
|
|
2178
3107
|
}
|
|
2179
|
-
if (
|
|
3108
|
+
if (own3.length === 0)
|
|
2180
3109
|
return null;
|
|
2181
|
-
if (
|
|
3110
|
+
if (own3.every((key) => absorb.includes(key)))
|
|
2182
3111
|
return "absorb";
|
|
2183
|
-
if (
|
|
3112
|
+
if (own3.every((key) => pass.includes(key)))
|
|
2184
3113
|
return "pass";
|
|
2185
3114
|
return null;
|
|
2186
3115
|
}
|