@agent-cards/sdk 0.23.28 → 0.24.0
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 +58 -0
- package/PREFLIGHT.md +7 -1
- package/README.md +137 -99
- package/dist/aci.d.ts +52 -22
- package/dist/aci.js +79 -15
- package/dist/adyen-merchant-hosted.generated.d.ts +1 -1
- package/dist/adyen-merchant-hosted.generated.js +459 -21
- package/dist/agent-amount.generated.js +1 -1
- package/dist/agentcard.d.ts +4 -5
- package/dist/agentcard.js +4 -5
- package/dist/amadeus.d.ts +9 -3
- package/dist/amadeus.js +33 -4
- package/dist/api-module.d.ts +1 -7
- package/dist/api-module.js +3 -5
- package/dist/{voice-retry.js → api-retry.js} +1 -1
- package/dist/api-types.d.ts +53 -0
- package/dist/{voice-types.js → api-types.js} +7 -2
- package/dist/approvals.d.ts +166 -0
- package/dist/approvals.js +213 -0
- package/dist/buy.d.ts +20 -101
- package/dist/buy.js +19 -74
- package/dist/capabilities.generated.js +1 -1
- package/dist/card-fields.generated.js +1398 -106
- package/dist/cdp.d.ts +3 -13
- package/dist/cdp.js +231 -175
- package/dist/client.d.ts +104 -22
- package/dist/client.js +215 -40
- package/dist/creditguard.generated.d.ts +4 -4
- package/dist/datatrans.generated.js +22 -1
- package/dist/elavon-converge.generated.js +5 -3
- package/dist/hold.d.ts +8 -0
- package/dist/hold.js +43 -2
- package/dist/hosted-entry.js +2 -0
- package/dist/index.d.ts +9 -15
- package/dist/index.js +6 -10
- package/dist/lifecycle.d.ts +9 -61
- package/dist/lifecycle.js +24 -10
- package/dist/merchant-card-endpoints.generated.d.ts +6 -1
- package/dist/merchant-card-endpoints.generated.js +344 -19
- package/dist/merchant-hosted.d.ts +8 -1
- package/dist/nike-order.d.ts +51 -0
- package/dist/nike-order.js +81 -0
- package/dist/oceanpayment.d.ts +38 -0
- package/dist/oceanpayment.js +70 -0
- package/dist/paddle-tokenex.generated.js +105 -10
- package/dist/payplug.d.ts +41 -0
- package/dist/payplug.js +71 -0
- package/dist/payrails.generated.js +27 -7
- package/dist/pre-claim.d.ts +9 -0
- package/dist/pre-claim.js +86 -7
- package/dist/preflight-capabilities.generated.d.ts +0 -4
- package/dist/preflight-capabilities.generated.js +0 -5
- package/dist/preflight-catalog.json +46 -5
- package/dist/preflight-playwright.d.ts +2 -2
- package/dist/preflight-playwright.js +63 -14
- package/dist/preflight-schemas.json +4 -0
- package/dist/preflight.generated.d.ts +0 -4
- package/dist/preflight.generated.js +24 -1
- package/dist/prepared-processor.d.ts +18 -5
- package/dist/prepared-processor.js +48 -8
- package/dist/primer.generated.js +1418 -120
- package/dist/processout.generated.d.ts +61 -0
- package/dist/processout.generated.js +577 -0
- package/dist/requests.js +1 -1
- package/dist/shiji-sts.generated.js +105 -10
- package/dist/stripe-checkout.generated.js +1405 -234
- package/dist/substitutions.generated.js +460 -26
- package/dist/tap-payments.generated.js +105 -10
- package/dist/twoc2p.generated.js +105 -10
- package/dist/url-masks/bluesnap.d.ts +2 -0
- package/dist/url-masks/bluesnap.js +15 -0
- package/dist/url-masks/oceanpayment.d.ts +2 -0
- package/dist/url-masks/oceanpayment.js +13 -0
- package/dist/url-masks/payplug.d.ts +2 -0
- package/dist/url-masks/payplug.js +13 -0
- package/dist/url-masks/vtex_payments.d.ts +2 -0
- package/dist/url-masks/vtex_payments.js +12 -0
- package/dist/url-masks.generated.d.ts +1 -1
- package/dist/url-masks.generated.js +6 -2
- package/dist/verifone.generated.js +42 -2
- package/dist/vtex-payments.generated.d.ts +127 -0
- package/dist/vtex-payments.generated.js +544 -0
- package/dist/webhooks.d.ts +2 -2
- package/dist/webhooks.js +2 -2
- package/examples/preflight/kernel-native/inventory.json +1 -1
- package/package.json +6 -8
- package/dist/languages.d.ts +0 -23
- package/dist/languages.js +0 -76
- package/dist/voice-pkce.d.ts +0 -49
- package/dist/voice-pkce.js +0 -147
- package/dist/voice-stream.generated.d.ts +0 -118
- package/dist/voice-stream.generated.js +0 -170
- package/dist/voice-types.d.ts +0 -735
- package/dist/voice.d.ts +0 -373
- package/dist/voice.js +0 -815
- package/readme.test.mjs +0 -53
- /package/dist/{voice-retry.d.ts → api-retry.d.ts} +0 -0
|
@@ -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: 30e71492a40034d2902de57f0000892645e620526fdf00b2072fa1160a7875cb
|
|
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
|
|
@@ -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 own19 = Object.keys(value);
|
|
361
|
+
return own19.length === keys.length && own19.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" });
|
|
@@ -713,13 +713,13 @@ function readElement(der, at, tag) {
|
|
|
713
713
|
let length = der[at + 1];
|
|
714
714
|
let start = at + 2;
|
|
715
715
|
if (length & 128) {
|
|
716
|
-
const
|
|
717
|
-
if (
|
|
716
|
+
const count2 = length & 127;
|
|
717
|
+
if (count2 === 0 || count2 > 2 || start + count2 > der.length || der[start] === 0)
|
|
718
718
|
throw refuse6("key");
|
|
719
|
-
length =
|
|
719
|
+
length = count2 === 1 ? der[start] : der[start] * 256 + der[start + 1];
|
|
720
720
|
if (length < 128)
|
|
721
721
|
throw refuse6("key");
|
|
722
|
-
start +=
|
|
722
|
+
start += count2;
|
|
723
723
|
}
|
|
724
724
|
if (start + length > der.length)
|
|
725
725
|
throw refuse6("key");
|
|
@@ -771,8 +771,8 @@ var PADDLE_TOKENEX_PSP = "paddle_tokenex";
|
|
|
771
771
|
var PADDLE_TOKENEX_FACT_KEYS = /* @__PURE__ */ Object.freeze(["card_first_six", "card_last_four", "expiry_month", "expiry_year", "card_brand"]);
|
|
772
772
|
var record4 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
773
773
|
var sameKeys2 = (value, keys) => {
|
|
774
|
-
const
|
|
775
|
-
return
|
|
774
|
+
const own19 = Object.keys(value);
|
|
775
|
+
return own19.length === keys.length && own19.every((key, at) => key === keys[at]);
|
|
776
776
|
};
|
|
777
777
|
var refuse7 = (code) => Object.freeze({ verdict: "refuse", code });
|
|
778
778
|
var CARD6 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
|
|
@@ -842,8 +842,8 @@ function readPay(body, line, environment2) {
|
|
|
842
842
|
const card = record4(method) && sameKeys2(method, ["card"]) ? method.card : null;
|
|
843
843
|
if (!record4(card) || !(sameKeys2(card, PAY_CARD_KEYS) || sameKeys2(card, [...PAY_CARD_KEYS, "session_tracking"])))
|
|
844
844
|
return null;
|
|
845
|
-
const
|
|
846
|
-
if (!record4(
|
|
845
|
+
const metadata2 = card.metadata;
|
|
846
|
+
if (!record4(metadata2) || !sameKeys2(metadata2, METADATA_KEYS2) || typeof metadata2.cardholder_name !== "string" || metadata2.cardholder_name.length > NAME_LIMIT2 || CONTROL2.test(metadata2.cardholder_name) || cardLikeName2(metadata2.cardholder_name) || typeof metadata2.card_first_six !== "string" || !FIRST_SIX.test(metadata2.card_first_six) || typeof metadata2.card_last_four !== "string" || !LAST_FOUR.test(metadata2.card_last_four) || !expiryMonth(metadata2.expiry_month) || !expiryYear(metadata2.expiry_year) || !FRAME_BRANDS.includes(metadata2.card_brand))
|
|
847
847
|
return null;
|
|
848
848
|
const details = card.three_d_s;
|
|
849
849
|
if (!record4(details) || !sameKeys2(details, ["browser_info"]) || typeof details.browser_info !== "string" || !BROWSER_INFO.test(details.browser_info))
|
|
@@ -1261,8 +1261,8 @@ var TEXT_LIMIT = 256;
|
|
|
1261
1261
|
var CONTROL4 = /[\u0000-\u001f\u007f]/;
|
|
1262
1262
|
var record6 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
1263
1263
|
var sameKeys3 = (value, keys) => {
|
|
1264
|
-
const
|
|
1265
|
-
return
|
|
1264
|
+
const own19 = Object.keys(value);
|
|
1265
|
+
return own19.length === keys.length && own19.every((key, at) => key === keys[at]);
|
|
1266
1266
|
};
|
|
1267
1267
|
var plainText = (value) => typeof value === "string" && value.length <= TEXT_LIMIT && !CONTROL4.test(value) && (value.match(/[0-9]/g) ?? []).length < 12;
|
|
1268
1268
|
var refuse9 = (code) => Object.freeze({ verdict: "refuse", code });
|
|
@@ -1292,13 +1292,13 @@ function billingFields(value) {
|
|
|
1292
1292
|
if (names.length > MAX_FIELDS)
|
|
1293
1293
|
return false;
|
|
1294
1294
|
return names.every((name) => {
|
|
1295
|
-
const
|
|
1295
|
+
const field3 = value[name];
|
|
1296
1296
|
if (!FIELD_NAME.test(name))
|
|
1297
1297
|
return false;
|
|
1298
|
-
if (!record6(
|
|
1299
|
-
return billingText(
|
|
1300
|
-
const nested = Object.keys(
|
|
1301
|
-
return nested.length <= MAX_NESTED_FIELDS && nested.every((key) => FIELD_NAME.test(key) && billingText(
|
|
1298
|
+
if (!record6(field3))
|
|
1299
|
+
return billingText(field3);
|
|
1300
|
+
const nested = Object.keys(field3);
|
|
1301
|
+
return nested.length <= MAX_NESTED_FIELDS && nested.every((key) => FIELD_NAME.test(key) && billingText(field3[key]));
|
|
1302
1302
|
});
|
|
1303
1303
|
}
|
|
1304
1304
|
function wixPaymentsBodyVerdict(body) {
|
|
@@ -1372,14 +1372,14 @@ function readJson2(body) {
|
|
|
1372
1372
|
catch {
|
|
1373
1373
|
return { parsed: null, exact: false };
|
|
1374
1374
|
}
|
|
1375
|
-
let
|
|
1375
|
+
let exact5 = false;
|
|
1376
1376
|
try {
|
|
1377
|
-
|
|
1377
|
+
exact5 = body.length <= BODY_LIMIT6 && JSON.stringify(parsed) === body;
|
|
1378
1378
|
}
|
|
1379
1379
|
catch {
|
|
1380
|
-
|
|
1380
|
+
exact5 = false;
|
|
1381
1381
|
}
|
|
1382
|
-
return { parsed, exact:
|
|
1382
|
+
return { parsed, exact: exact5 };
|
|
1383
1383
|
}
|
|
1384
1384
|
function billingValue(value) {
|
|
1385
1385
|
if (value === UNDEFINED)
|
|
@@ -1393,15 +1393,15 @@ function judgeCardAttach(args, session) {
|
|
|
1393
1393
|
return "paymongo_body_unsupported";
|
|
1394
1394
|
}
|
|
1395
1395
|
const id = args[0].slice(3);
|
|
1396
|
-
const
|
|
1397
|
-
const details =
|
|
1396
|
+
const attributes2 = args[1].data.attributes;
|
|
1397
|
+
const details = attributes2.details;
|
|
1398
1398
|
if (record7(details) && CLICK_TO_PAY_KEYS.some((key) => own(details, key)))
|
|
1399
1399
|
return "paymongo_click_to_pay";
|
|
1400
|
-
if (!keysAre(args[1], ["data"]) || !keysAre(args[1].data, ["attributes"]) || !keysAre(
|
|
1400
|
+
if (!keysAre(args[1], ["data"]) || !keysAre(args[1].data, ["attributes"]) || !keysAre(attributes2, PAYMONGO_ATTRIBUTE_KEYS) || !record7(details) || !keysAre(details, PAYMONGO_CARD_KEYS))
|
|
1401
1401
|
return "paymongo_body_unsupported";
|
|
1402
1402
|
if (typeof details.card_number !== "string" || !NUMBER.test(details.card_number) || !Number.isSafeInteger(details.exp_month) || details.exp_month < 1 || details.exp_month > 12 || !Number.isSafeInteger(details.exp_year) || details.exp_year < 0 || details.exp_year > 99 || typeof details.cvc !== "string" || !SECURITY_CODE6.test(details.cvc))
|
|
1403
1403
|
return "paymongo_body_unsupported";
|
|
1404
|
-
const billing =
|
|
1404
|
+
const billing = attributes2.billing;
|
|
1405
1405
|
if (!record7(billing) || !keysAre(billing, PAYMONGO_BILLING_KEYS) || !record7(billing.address) || !keysAre(billing.address, PAYMONGO_ADDRESS_KEYS))
|
|
1406
1406
|
return "paymongo_body_unsupported";
|
|
1407
1407
|
if (billing.name === UNDEFINED || !billingValue(billing.name) || !billingValue(billing.email) || !billingValue(billing.phone) || !PAYMONGO_ADDRESS_KEYS.every((key) => billingValue(billing.address[key])))
|
|
@@ -1409,7 +1409,7 @@ function judgeCardAttach(args, session) {
|
|
|
1409
1409
|
const third = args[2];
|
|
1410
1410
|
if (!record7(third) || !keysAre(third, ["viewerAccept"]) || !billingValue(third.viewerAccept))
|
|
1411
1411
|
return "paymongo_body_unsupported";
|
|
1412
|
-
if (
|
|
1412
|
+
if (attributes2.return_url !== `${ORIGIN}${id}` || session !== void 0 && session !== id)
|
|
1413
1413
|
return "paymongo_session_mismatch";
|
|
1414
1414
|
return null;
|
|
1415
1415
|
}
|
|
@@ -1434,14 +1434,14 @@ function attachType(parsed) {
|
|
|
1434
1434
|
return typeof type === "string" ? type : null;
|
|
1435
1435
|
}
|
|
1436
1436
|
function paymongoBodyVerdict(body, session) {
|
|
1437
|
-
const { parsed, exact:
|
|
1437
|
+
const { parsed, exact: exact5 } = readJson2(body);
|
|
1438
1438
|
const type = parsed === null ? null : attachType(parsed);
|
|
1439
1439
|
if (type !== "card") {
|
|
1440
1440
|
if (parsed === null)
|
|
1441
1441
|
return body === void 0 || body === null || body === "" ? CONTINUE4 : refuse10("paymongo_body_unsupported");
|
|
1442
1442
|
return namesCardValue(parsed) ? refuse10("paymongo_body_unsupported") : CONTINUE4;
|
|
1443
1443
|
}
|
|
1444
|
-
if (!
|
|
1444
|
+
if (!exact5)
|
|
1445
1445
|
return refuse10("paymongo_body_unsupported");
|
|
1446
1446
|
const code = judgeCardAttach(parsed, session);
|
|
1447
1447
|
return code === null ? CARD9 : refuse10(code);
|
|
@@ -1464,8 +1464,8 @@ var EXPIRATION = /^[0-9]{2}(?:0[1-9]|1[0-2])$/;
|
|
|
1464
1464
|
var CARD_PAYMENT = "PAYMENT_CARD";
|
|
1465
1465
|
var record8 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
1466
1466
|
var sameKeys4 = (value, keys) => {
|
|
1467
|
-
const
|
|
1468
|
-
return
|
|
1467
|
+
const own19 = Object.keys(value);
|
|
1468
|
+
return own19.length === keys.length && own19.every((key, at) => key === keys[at]);
|
|
1469
1469
|
};
|
|
1470
1470
|
var refuse11 = (code) => Object.freeze({ verdict: "refuse", code });
|
|
1471
1471
|
var CARD10 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
|
|
@@ -1695,8 +1695,8 @@ var LOCALE = /^[a-z]{2}(?:-[A-Za-z]{2,4})?$/;
|
|
|
1695
1695
|
var PAN_LIKE3 = /(?:[0-9][ _.:-]*){12,}/;
|
|
1696
1696
|
var record9 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
1697
1697
|
var sameKeys5 = (value, keys) => {
|
|
1698
|
-
const
|
|
1699
|
-
return
|
|
1698
|
+
const own19 = Object.keys(value);
|
|
1699
|
+
return own19.length === keys.length && own19.every((key, at) => key === keys[at]);
|
|
1700
1700
|
};
|
|
1701
1701
|
var refuse13 = (code) => Object.freeze({ verdict: "refuse", code });
|
|
1702
1702
|
var CARD12 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
|
|
@@ -1948,10 +1948,10 @@ function judge(body, contentType, rule) {
|
|
|
1948
1948
|
if (read.parts.some((part) => !listed(rule.parts, part.name)))
|
|
1949
1949
|
return refusal("multipart_unknown_part");
|
|
1950
1950
|
for (const name of rule.card) {
|
|
1951
|
-
const
|
|
1952
|
-
if (
|
|
1951
|
+
const count2 = read.parts.filter((part) => part.name === name).length;
|
|
1952
|
+
if (count2 === 0)
|
|
1953
1953
|
return refusal("multipart_missing_card_part");
|
|
1954
|
-
if (
|
|
1954
|
+
if (count2 > 1)
|
|
1955
1955
|
return refusal("multipart_duplicate_card_part");
|
|
1956
1956
|
}
|
|
1957
1957
|
return read;
|
|
@@ -2727,8 +2727,8 @@ var TEXT_LIMIT3 = 256;
|
|
|
2727
2727
|
var CONTROL7 = /[\u0000-\u001f\u007f]/;
|
|
2728
2728
|
var record13 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
2729
2729
|
var sameKeys7 = (value, keys) => {
|
|
2730
|
-
const
|
|
2731
|
-
return
|
|
2730
|
+
const own19 = Object.keys(value);
|
|
2731
|
+
return own19.length === keys.length && own19.every((key, at) => key === keys[at]);
|
|
2732
2732
|
};
|
|
2733
2733
|
var plainText3 = (value) => typeof value === "string" && value.length <= TEXT_LIMIT3 && !CONTROL7.test(value) && (value.match(/[0-9]/g) ?? []).length < 12;
|
|
2734
2734
|
var refuse19 = (code) => Object.freeze({ verdict: "refuse", code });
|
|
@@ -3005,10 +3005,10 @@ function paypalBodyVerdict(body) {
|
|
|
3005
3005
|
if (number === void 0 || number === null || number === "")
|
|
3006
3006
|
return CONTINUE9;
|
|
3007
3007
|
const context = value.application_context;
|
|
3008
|
-
const
|
|
3009
|
-
if (record14(context) && context.vault === true || own3(card, "stored_credential") ||
|
|
3008
|
+
const attributes2 = record14(card.attributes) ? card.attributes : null;
|
|
3009
|
+
if (record14(context) && context.vault === true || own3(card, "stored_credential") || attributes2 && (own3(attributes2, "vault") || own3(attributes2, "customer")))
|
|
3010
3010
|
return refuse20("paypal_card_on_file");
|
|
3011
|
-
if (
|
|
3011
|
+
if (attributes2 && record14(attributes2.verification) && attributes2.verification.method === "SCA_ALWAYS")
|
|
3012
3012
|
return refuse20("paypal_three_ds");
|
|
3013
3013
|
if (!keysWithin2(value, ["payment_source"]) || !keysWithin2(source, ["card"]) || !keysWithin2(card, CARD_KEYS8) || !typedNumber(card.number) || typeof card.expiry !== "string" || !/^[0-9]{4}-(?:0[1-9]|1[0-2])$/.test(card.expiry))
|
|
3014
3014
|
return refuse20("paypal_body_unsupported");
|
|
@@ -3022,7 +3022,7 @@ function paypalBodyVerdict(body) {
|
|
|
3022
3022
|
if (own3(card, "billing_address") && !(keysWithin2(card.billing_address, ADDRESS_KEYS3) && Object.values(card.billing_address).every(text3))) {
|
|
3023
3023
|
return refuse20("paypal_body_unsupported");
|
|
3024
3024
|
}
|
|
3025
|
-
if (own3(card, "attributes") && !(keysWithin2(
|
|
3025
|
+
if (own3(card, "attributes") && !(keysWithin2(attributes2, ["installments"]) && installmentsOk(attributes2.installments))) {
|
|
3026
3026
|
return refuse20("paypal_body_unsupported");
|
|
3027
3027
|
}
|
|
3028
3028
|
return CARD19;
|
|
@@ -3433,8 +3433,8 @@ var HOSTNAME = /^(?=.{1,253}$)[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?(?:\.[a-z0-9](
|
|
|
3433
3433
|
var PUBLISHABLE_KEY = /^[A-Za-z0-9]{16,64}$/;
|
|
3434
3434
|
var record18 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
3435
3435
|
var sameKeys8 = (value, keys) => {
|
|
3436
|
-
const
|
|
3437
|
-
return
|
|
3436
|
+
const own19 = Object.keys(value);
|
|
3437
|
+
return own19.length === keys.length && own19.every((key, at) => key === keys[at]);
|
|
3438
3438
|
};
|
|
3439
3439
|
var refuse24 = (code) => Object.freeze({ verdict: "refuse", code });
|
|
3440
3440
|
var CARD23 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
|
|
@@ -4125,8 +4125,8 @@ var LONG_TEXT_LIMIT = BODY_LIMIT25;
|
|
|
4125
4125
|
var record22 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
4126
4126
|
var owns6 = (value, key) => Object.prototype.hasOwnProperty.call(value, key);
|
|
4127
4127
|
var sameKeys9 = (value, keys) => {
|
|
4128
|
-
const
|
|
4129
|
-
return
|
|
4128
|
+
const own19 = Object.keys(value);
|
|
4129
|
+
return own19.length === keys.length && own19.every((key, at) => key === keys[at]);
|
|
4130
4130
|
};
|
|
4131
4131
|
var exact3 = (pattern, value) => typeof value === "string" && pattern.test(value);
|
|
4132
4132
|
var printable3 = (text9) => [...text9].every((character) => {
|
|
@@ -4525,8 +4525,8 @@ var POSTAL_CODE4 = /^[A-Za-z0-9 -]{0,16}$/;
|
|
|
4525
4525
|
var CIPHERTEXT_B64 = /^[A-Za-z0-9+/]{341}[AQgw]==$/;
|
|
4526
4526
|
var record24 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
4527
4527
|
var sameKeys11 = (value, keys) => {
|
|
4528
|
-
const
|
|
4529
|
-
return
|
|
4528
|
+
const own19 = Object.keys(value);
|
|
4529
|
+
return own19.length === keys.length && own19.every((key, at) => key === keys[at]);
|
|
4530
4530
|
};
|
|
4531
4531
|
var refuse29 = (code) => Object.freeze({ verdict: "refuse", code });
|
|
4532
4532
|
var failed = (code) => (
|
|
@@ -4677,14 +4677,14 @@ function readJson7(body) {
|
|
|
4677
4677
|
catch {
|
|
4678
4678
|
return { parsed: null, exact: false };
|
|
4679
4679
|
}
|
|
4680
|
-
let
|
|
4680
|
+
let exact5 = false;
|
|
4681
4681
|
try {
|
|
4682
|
-
|
|
4682
|
+
exact5 = JSON.stringify(parsed) === body;
|
|
4683
4683
|
}
|
|
4684
4684
|
catch {
|
|
4685
|
-
|
|
4685
|
+
exact5 = false;
|
|
4686
4686
|
}
|
|
4687
|
-
return { parsed, exact:
|
|
4687
|
+
return { parsed, exact: exact5 };
|
|
4688
4688
|
}
|
|
4689
4689
|
function numberDigits(number) {
|
|
4690
4690
|
if (typeof number !== "string")
|
|
@@ -4761,7 +4761,7 @@ function judgeCard2(parsed) {
|
|
|
4761
4761
|
return null;
|
|
4762
4762
|
}
|
|
4763
4763
|
function fastspringBodyVerdict(body) {
|
|
4764
|
-
const { parsed, exact:
|
|
4764
|
+
const { parsed, exact: exact5 } = readJson7(body);
|
|
4765
4765
|
if (!record25(parsed))
|
|
4766
4766
|
return body === void 0 || body === null || body === "" ? CONTINUE11 : refuse30("fastspring_body_unsupported");
|
|
4767
4767
|
if (parsed.paymentType !== "card") {
|
|
@@ -4769,7 +4769,7 @@ function fastspringBodyVerdict(body) {
|
|
|
4769
4769
|
return refuse30("fastspring_body_unsupported");
|
|
4770
4770
|
return typeof parsed.paymentType === "string" && parsed.paymentType !== "" ? CONTINUE11 : refuse30("fastspring_body_unsupported");
|
|
4771
4771
|
}
|
|
4772
|
-
if (!
|
|
4772
|
+
if (!exact5)
|
|
4773
4773
|
return refuse30("fastspring_body_unsupported");
|
|
4774
4774
|
const code = judgeCard2(parsed);
|
|
4775
4775
|
return code === null ? CARD29 : refuse30(code);
|
|
@@ -5005,10 +5005,10 @@ function billingDetails(value) {
|
|
|
5005
5005
|
if (!record27(value) || !inOrder5(value, BILLING_KEYS))
|
|
5006
5006
|
return false;
|
|
5007
5007
|
return Object.keys(value).every((key) => {
|
|
5008
|
-
const
|
|
5008
|
+
const field3 = value[key];
|
|
5009
5009
|
if (key !== "address")
|
|
5010
|
-
return key === "mobile_number" || key === "phone_number" ? typeof
|
|
5011
|
-
return record27(
|
|
5010
|
+
return key === "mobile_number" || key === "phone_number" ? typeof field3 === "string" && PHONE4.test(field3) : plainText6(field3);
|
|
5011
|
+
return record27(field3) && inOrder5(field3, ADDRESS_KEYS5) && Object.keys(field3).every((name) => plainText6(field3[name]));
|
|
5012
5012
|
});
|
|
5013
5013
|
}
|
|
5014
5014
|
function cardData(value) {
|
|
@@ -5038,8 +5038,8 @@ function xenditBodyVerdict(body) {
|
|
|
5038
5038
|
if (own9(value, "fp_session_id") && (typeof value.fp_session_id !== "string" || !FP_SESSION.test(value.fp_session_id)))
|
|
5039
5039
|
return refuse32("xendit_body_unsupported");
|
|
5040
5040
|
if (own9(value, "metadata")) {
|
|
5041
|
-
const
|
|
5042
|
-
if (!record27(
|
|
5041
|
+
const metadata2 = value.metadata;
|
|
5042
|
+
if (!record27(metadata2) || Object.keys(metadata2).length !== 1 || !record27(metadata2._forter) || Object.keys(metadata2._forter).length !== 1 || typeof metadata2._forter.token !== "string" || !FORTER_TOKEN.test(metadata2._forter.token))
|
|
5043
5043
|
return refuse32("xendit_body_unsupported");
|
|
5044
5044
|
}
|
|
5045
5045
|
if (own9(value, "mid_label") && (typeof value.mid_label !== "string" || !MID_LABEL.test(value.mid_label)))
|
|
@@ -5317,14 +5317,14 @@ function readJson8(body) {
|
|
|
5317
5317
|
catch {
|
|
5318
5318
|
return { parsed: null, exact: false };
|
|
5319
5319
|
}
|
|
5320
|
-
let
|
|
5320
|
+
let exact5 = false;
|
|
5321
5321
|
try {
|
|
5322
|
-
|
|
5322
|
+
exact5 = body.length <= BODY_LIMIT32 && JSON.stringify(parsed) === body;
|
|
5323
5323
|
}
|
|
5324
5324
|
catch {
|
|
5325
|
-
|
|
5325
|
+
exact5 = false;
|
|
5326
5326
|
}
|
|
5327
|
-
return { parsed, exact:
|
|
5327
|
+
return { parsed, exact: exact5 };
|
|
5328
5328
|
}
|
|
5329
5329
|
function namesCardValue3(parsed) {
|
|
5330
5330
|
const pending = parsed !== null && typeof parsed === "object" ? [parsed] : [];
|
|
@@ -5385,8 +5385,8 @@ function judgeCardPayment(parsed) {
|
|
|
5385
5385
|
function paymobBodyVerdict(body) {
|
|
5386
5386
|
if (body === void 0 || body === null || body === "")
|
|
5387
5387
|
return CONTINUE12;
|
|
5388
|
-
const { parsed, exact:
|
|
5389
|
-
if (!
|
|
5388
|
+
const { parsed, exact: exact5 } = readJson8(body);
|
|
5389
|
+
if (!exact5 || !record29(parsed) || !record29(parsed.source) || typeof parsed.source.subtype !== "string")
|
|
5390
5390
|
return refuse34("paymob_body_unsupported");
|
|
5391
5391
|
const subtype = parsed.source.subtype;
|
|
5392
5392
|
if (subtype === "CARD") {
|
|
@@ -5858,12 +5858,12 @@ function membersRefusal(root) {
|
|
|
5858
5858
|
const pending = [[root, ""]];
|
|
5859
5859
|
while (pending.length > 0) {
|
|
5860
5860
|
const [node, path] = pending.pop();
|
|
5861
|
-
const
|
|
5861
|
+
const own19 = path === "" ? TRANSACTION_MEMBERS : owns7(RECORD_MEMBERS, path) ? RECORD_MEMBERS[path] : null;
|
|
5862
5862
|
for (const [key, child] of Object.entries(node)) {
|
|
5863
5863
|
const at = Array.isArray(node) ? path : path === "" ? key : `${path}.${key}`;
|
|
5864
5864
|
if (at === "checkoutCreditCard")
|
|
5865
5865
|
continue;
|
|
5866
|
-
if (
|
|
5866
|
+
if (own19 !== null && !own19.includes(key))
|
|
5867
5867
|
return true;
|
|
5868
5868
|
if (TEXT_RECORDS.includes(path) && child !== null && typeof child !== "string")
|
|
5869
5869
|
return true;
|
|
@@ -6084,7 +6084,17 @@ var TOKEN_FACTS = /* @__PURE__ */ Object.freeze([
|
|
|
6084
6084
|
"primary"
|
|
6085
6085
|
]);
|
|
6086
6086
|
// src/registration.js
|
|
6087
|
-
var PARTS = {
|
|
6087
|
+
var PARTS = {
|
|
6088
|
+
psp: "id",
|
|
6089
|
+
definitions: "list",
|
|
6090
|
+
refusedOperations: "list",
|
|
6091
|
+
settlementReadback: "any",
|
|
6092
|
+
exactUrl: "rule",
|
|
6093
|
+
bodyGate: "rule",
|
|
6094
|
+
amount: "rule",
|
|
6095
|
+
hostedEntry: "rule",
|
|
6096
|
+
limitations: "sentences"
|
|
6097
|
+
};
|
|
6088
6098
|
var PSP_ID = /^[a-z][a-z0-9_]*$/;
|
|
6089
6099
|
var registrationProblems = (spec) => problemsOf(spec, PARTS);
|
|
6090
6100
|
function problemsOf(spec, parts) {
|
|
@@ -6100,9 +6110,14 @@ function problemsOf(spec, parts) {
|
|
|
6100
6110
|
continue;
|
|
6101
6111
|
if (kind === "rule" && typeof value !== "function")
|
|
6102
6112
|
problems2.push(`${psp}: ${key} is not a function`);
|
|
6113
|
+
if (kind === "flag" && value !== true)
|
|
6114
|
+
problems2.push(`${psp}: ${key} is not true`);
|
|
6103
6115
|
if (kind === "numbers" && !((Array.isArray(value) || value instanceof Set) && [...value].every((n) => typeof n === "string" && /^\d{12,19}$/.test(n)))) {
|
|
6104
6116
|
problems2.push(`${psp}: ${key} is not a list of card numbers`);
|
|
6105
6117
|
}
|
|
6118
|
+
if (kind === "sentences" && !(Array.isArray(value) && value.length > 0 && value.every((s) => typeof s === "string" && s.trim() !== ""))) {
|
|
6119
|
+
problems2.push(`${psp}: ${key} is not a list of sentences`);
|
|
6120
|
+
}
|
|
6106
6121
|
}
|
|
6107
6122
|
if ("definitions" in parts) {
|
|
6108
6123
|
if (!Array.isArray(spec.definitions) || spec.definitions.length === 0)
|
|
@@ -6113,6 +6128,10 @@ function problemsOf(spec, parts) {
|
|
|
6113
6128
|
if (typeof id !== "string" || !id.startsWith(`${psp}.`))
|
|
6114
6129
|
problems2.push(`${psp}: ${JSON.stringify(id)} is not one of its operations`);
|
|
6115
6130
|
}
|
|
6131
|
+
const pages = Array.isArray(spec.definitions) ? spec.definitions.filter((d) => d?.hostedForm?.cardIn === "processor_page") : [];
|
|
6132
|
+
if (spec.hostedEntry !== void 0 && (pages.length === 0 || pages.some((d) => d.hostedForm.policy !== void 0))) {
|
|
6133
|
+
problems2.push(`${psp}: hostedEntry needs a definition whose hosted form takes the card on the processor's page and names no policy`);
|
|
6134
|
+
}
|
|
6116
6135
|
}
|
|
6117
6136
|
return problems2;
|
|
6118
6137
|
}
|
|
@@ -6125,21 +6144,230 @@ function registered(spec, parts) {
|
|
|
6125
6144
|
function registerProcessor(spec) {
|
|
6126
6145
|
return registered(spec, PARTS);
|
|
6127
6146
|
}
|
|
6147
|
+
// src/processors/bluesnap.js
|
|
6148
|
+
var BLUESNAP_PSP = "bluesnap";
|
|
6149
|
+
var BLUESNAP_OPERATION = "bluesnap.card_request";
|
|
6150
|
+
var BLUESNAP_HOSTS = /* @__PURE__ */ Object.freeze({ 1: "ws1.bluesnap.com", 2: "ws2.bluesnap.com", _: "sandpay.bluesnap.com" });
|
|
6151
|
+
var BLUESNAP_SANDBOX_HOST = "sandpay.bluesnap.com";
|
|
6152
|
+
var BLUESNAP_CARD_KEYS = /* @__PURE__ */ Object.freeze(["cvv", "ccNumber", "expDate"]);
|
|
6153
|
+
var BLUESNAP_LEG_KEYS = /* @__PURE__ */ Object.freeze(["cvv", "expDate"]);
|
|
6154
|
+
var BODY_LIMIT35 = 1024;
|
|
6155
|
+
var TOKEN_URL2 = /^https:\/\/(ws1|ws2|sandpay)\.bluesnap\.com\/services\/2\/payment-fields-tokens\/([0-9a-f]{64}_[12]?)$/;
|
|
6156
|
+
var CARD_NUMBER18 = /^[0-9]{12,19}$/;
|
|
6157
|
+
var SECURITY_CODE22 = /^[0-9]{3,4}$/;
|
|
6158
|
+
var EXPIRY3 = /^(?:0[1-9]|1[0-2])\/20[0-9]{2}$/;
|
|
6159
|
+
var SAVED_CARD_KEYS2 = ["last4Digits", "lastFourDigits", "ccType"];
|
|
6160
|
+
var record32 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
6161
|
+
var own12 = (value, key) => Object.prototype.hasOwnProperty.call(value, key);
|
|
6162
|
+
var refuse37 = (code) => Object.freeze({ verdict: "refuse", code });
|
|
6163
|
+
var CARD36 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
|
|
6164
|
+
var LEG = /* @__PURE__ */ Object.freeze({ verdict: "continue" });
|
|
6165
|
+
function bluesnapTokenUrl(url) {
|
|
6166
|
+
const match = typeof url === "string" ? TOKEN_URL2.exec(url) : null;
|
|
6167
|
+
if (!match || BLUESNAP_HOSTS[match[2].slice(-1)] !== `${match[1]}.bluesnap.com`)
|
|
6168
|
+
return null;
|
|
6169
|
+
const host = `${match[1]}.bluesnap.com`;
|
|
6170
|
+
return Object.freeze({ host, token: match[2], environment: host === BLUESNAP_SANDBOX_HOST ? "sandbox" : "production" });
|
|
6171
|
+
}
|
|
6172
|
+
function isBluesnapTokenUrl(url) {
|
|
6173
|
+
return bluesnapTokenUrl(url) !== null;
|
|
6174
|
+
}
|
|
6175
|
+
function readBody21(body) {
|
|
6176
|
+
if (typeof body !== "string" || body === "" || body.length > BODY_LIMIT35)
|
|
6177
|
+
return null;
|
|
6178
|
+
try {
|
|
6179
|
+
const value = JSON.parse(body);
|
|
6180
|
+
return record32(value) && JSON.stringify(value) === body ? value : null;
|
|
6181
|
+
}
|
|
6182
|
+
catch {
|
|
6183
|
+
return null;
|
|
6184
|
+
}
|
|
6185
|
+
}
|
|
6186
|
+
function bluesnapBodyVerdict(body) {
|
|
6187
|
+
const value = readBody21(body);
|
|
6188
|
+
if (value === null)
|
|
6189
|
+
return refuse37("bluesnap_body_unsupported");
|
|
6190
|
+
const keys = Object.keys(value);
|
|
6191
|
+
if (keys.some((key) => SAVED_CARD_KEYS2.includes(key)))
|
|
6192
|
+
return refuse37(own12(value, "ccNumber") ? "bluesnap_body_unsupported" : "bluesnap_saved_card");
|
|
6193
|
+
if (keys.length === 0 || keys.some((key, i) => !BLUESNAP_CARD_KEYS.includes(key) || i > 0 && BLUESNAP_CARD_KEYS.indexOf(keys[i - 1]) >= BLUESNAP_CARD_KEYS.indexOf(key))) {
|
|
6194
|
+
return refuse37("bluesnap_body_unsupported");
|
|
6195
|
+
}
|
|
6196
|
+
if (own12(value, "ccNumber") && !(typeof value.ccNumber === "string" && CARD_NUMBER18.test(value.ccNumber)) || own12(value, "cvv") && !(typeof value.cvv === "string" && SECURITY_CODE22.test(value.cvv)) || own12(value, "expDate") && !(typeof value.expDate === "string" && EXPIRY3.test(value.expDate)))
|
|
6197
|
+
return refuse37("bluesnap_body_unsupported");
|
|
6198
|
+
return own12(value, "ccNumber") ? CARD36 : LEG;
|
|
6199
|
+
}
|
|
6200
|
+
var bluesnap_default = /* @__PURE__ */ registerProcessor({
|
|
6201
|
+
psp: BLUESNAP_PSP,
|
|
6202
|
+
definitions: [
|
|
6203
|
+
{
|
|
6204
|
+
psp: "bluesnap",
|
|
6205
|
+
// The card fields' PUTs, as the header above reads them. The sandbox has its own server, so the device sends a
|
|
6206
|
+
// test-mode request only documented test cards (hostEnvironmentPinned, device-replay.js S7). `(?![\w/.%-])`
|
|
6207
|
+
// ends the token for a consumer that tests `match` unanchored; the exact-URL rule pins each server to its suffix.
|
|
6208
|
+
// Ships dark: served only to a client that declares `bluesnap_hosted_payment_fields`, and the backend's gate turns
|
|
6209
|
+
// it on for Agentcard's own company alone, in code.
|
|
6210
|
+
capability: "bluesnap_hosted_payment_fields",
|
|
6211
|
+
match: "(?:ws1|ws2|sandpay)\\.bluesnap\\.com/services/2/payment-fields-tokens/[0-9a-f]{64}_[12]?(?![\\w/.%-])",
|
|
6212
|
+
hosts: ["^ws1\\.bluesnap\\.com$", "^ws2\\.bluesnap\\.com$", "^sandpay\\.bluesnap\\.com$"],
|
|
6213
|
+
sandboxHosts: ["^sandpay\\.bluesnap\\.com$"],
|
|
6214
|
+
hostEnvironmentPinned: true,
|
|
6215
|
+
encoding: "json",
|
|
6216
|
+
// The frames' own headers, each held to its shape by bluesnapRequestRefusal. Origin, Referer and cookies never
|
|
6217
|
+
// ride (the frames send no cookie).
|
|
6218
|
+
passthroughHeaders: ["^authorization$", "^bluesnap_version_header$", "^bluesnap_origin_version_header$", "^bluesnap_origin_header$"],
|
|
6219
|
+
jsonCardFields: [["ccNumber"]],
|
|
6220
|
+
// The expiry and code frames' PUTs: held by the checkout SDK and answered with the card request's answer.
|
|
6221
|
+
splitCard: { absorb: [...BLUESNAP_LEG_KEYS], pass: [], siblingKeys: [] },
|
|
6222
|
+
request: { method: "PUT", cardIn: "body", response: "json" }
|
|
6223
|
+
}
|
|
6224
|
+
],
|
|
6225
|
+
// Only the cardholder's device sends the card, after a person approves; no reviewed list names bluesnap.
|
|
6226
|
+
refusedOperations: [BLUESNAP_OPERATION],
|
|
6227
|
+
// Not surveyed: the PUT moves no money, and the merchant's own charge is a server call Agentcard never sees.
|
|
6228
|
+
settlementReadback: "not_surveyed",
|
|
6229
|
+
exactUrl: isBluesnapTokenUrl,
|
|
6230
|
+
bodyGate: (url, body) => url !== void 0 && !isBluesnapTokenUrl(url) ? { verdict: "refuse", code: "bluesnap_url_refused" } : bluesnapBodyVerdict(body)
|
|
6231
|
+
});
|
|
6232
|
+
// src/processors/iyzico.js
|
|
6233
|
+
var IYZICO_PSP = "iyzico";
|
|
6234
|
+
var IYZICO_OPERATION = "iyzico.card_request";
|
|
6235
|
+
var PATHS = ["/payment/iyzipos/checkoutform/auth/ecom", "/payment/iyzipos/checkoutform/initialize3ds/ecom"];
|
|
6236
|
+
var IYZICO_CARD_URLS = /* @__PURE__ */ Object.freeze(["https://api.iyzipay.com", "https://sandbox-api.iyzipay.com"].flatMap((origin) => PATHS.map((path) => `${origin}${path}`)));
|
|
6237
|
+
var IYZICO_BODY_KEYS = /* @__PURE__ */ Object.freeze([
|
|
6238
|
+
"installment",
|
|
6239
|
+
"paidPrice",
|
|
6240
|
+
"paymentChannel",
|
|
6241
|
+
"paymentCard",
|
|
6242
|
+
"buyerProtected",
|
|
6243
|
+
"gsmNumber",
|
|
6244
|
+
"dccPayment",
|
|
6245
|
+
"dccQueryRrn",
|
|
6246
|
+
"pwiMetadata"
|
|
6247
|
+
]);
|
|
6248
|
+
var IYZICO_CARD_KEYS = /* @__PURE__ */ Object.freeze([
|
|
6249
|
+
"cardNumber",
|
|
6250
|
+
"cardHolderName",
|
|
6251
|
+
"expireYear",
|
|
6252
|
+
"expireMonth",
|
|
6253
|
+
"cvc",
|
|
6254
|
+
"registerConsumerCard",
|
|
6255
|
+
"registerCard"
|
|
6256
|
+
]);
|
|
6257
|
+
var BODY_LIMIT36 = 4096;
|
|
6258
|
+
var CARD_NUMBER19 = /^[0-9]{12,19}$/;
|
|
6259
|
+
var SECURITY_CODE23 = /^[0-9]{3,4}$/;
|
|
6260
|
+
var MONTH19 = /^(?:0?[1-9]|1[0-2])$/;
|
|
6261
|
+
var YEAR20 = /^(?:[0-9]{2}|20[0-9]{2})$/;
|
|
6262
|
+
var PRICE = /^([1-9][0-9]{0,8}|0)(?:\.([0-9]{1,2}))?$/;
|
|
6263
|
+
var CHANNELS = /* @__PURE__ */ Object.freeze(["WEB", "MOBILE_WEB", "MOBILE_IOS", "MOBILE_ANDROID", "MOBILE_WINDOWS"]);
|
|
6264
|
+
var METADATA_KEYS3 = /* @__PURE__ */ Object.freeze(["lightRedesign", "pwiGrowthActionDisabled"]);
|
|
6265
|
+
var FLAG = /^[A-Za-z_]{1,16}$/;
|
|
6266
|
+
var HOLDER5 = /^[^\x00-\x1f\x7f0-9]{3,100}$/u;
|
|
6267
|
+
var record33 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
6268
|
+
var own13 = (value, key) => Object.prototype.hasOwnProperty.call(value, key);
|
|
6269
|
+
var inOrder6 = (value, keys) => {
|
|
6270
|
+
let at = 0;
|
|
6271
|
+
for (const name of Object.keys(value)) {
|
|
6272
|
+
while (at < keys.length && keys[at] !== name)
|
|
6273
|
+
at += 1;
|
|
6274
|
+
if (at === keys.length)
|
|
6275
|
+
return false;
|
|
6276
|
+
at += 1;
|
|
6277
|
+
}
|
|
6278
|
+
return true;
|
|
6279
|
+
};
|
|
6280
|
+
var refuse38 = (code) => Object.freeze({ verdict: "refuse", code });
|
|
6281
|
+
var CARD37 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
|
|
6282
|
+
function isIyzicoCardUrl(url) {
|
|
6283
|
+
return typeof url === "string" && IYZICO_CARD_URLS.includes(url);
|
|
6284
|
+
}
|
|
6285
|
+
function readBody22(body) {
|
|
6286
|
+
if (typeof body !== "string" || body === "" || body.length > BODY_LIMIT36)
|
|
6287
|
+
return null;
|
|
6288
|
+
try {
|
|
6289
|
+
const value = JSON.parse(body);
|
|
6290
|
+
return record33(value) && JSON.stringify(value) === body ? value : null;
|
|
6291
|
+
}
|
|
6292
|
+
catch {
|
|
6293
|
+
return null;
|
|
6294
|
+
}
|
|
6295
|
+
}
|
|
6296
|
+
function hundredths(price) {
|
|
6297
|
+
const match = typeof price === "number" && Number.isFinite(price) ? PRICE.exec(String(price)) : null;
|
|
6298
|
+
const value = match ? Number(match[1]) * 100 + Number((match[2] ?? "").padEnd(2, "0")) : 0;
|
|
6299
|
+
return value > 0 ? value : null;
|
|
6300
|
+
}
|
|
6301
|
+
var holderName2 = (name) => typeof name === "string" && HOLDER5.test(name) && name.trim().split(/\s+/).filter((word) => word.length > 1).length > 1;
|
|
6302
|
+
var metadata = (value) => record33(value) && inOrder6(value, METADATA_KEYS3) && Object.values(value).every((flag3) => Array.isArray(flag3) && flag3.length === 1 && typeof flag3[0] === "string" && FLAG.test(flag3[0]));
|
|
6303
|
+
function iyzicoBodyVerdict(body) {
|
|
6304
|
+
const value = readBody22(body);
|
|
6305
|
+
if (value === null)
|
|
6306
|
+
return refuse38("iyzico_body_unsupported");
|
|
6307
|
+
const card = value.paymentCard;
|
|
6308
|
+
if (record33(card) && (own13(card, "cardToken") || own13(card, "ucsToken") || own13(card, "consumerToken")) && !own13(card, "cardNumber"))
|
|
6309
|
+
return refuse38("iyzico_saved_card");
|
|
6310
|
+
if (own13(value, "dccPayment") || own13(value, "dccQueryRrn"))
|
|
6311
|
+
return refuse38("iyzico_dcc_refused");
|
|
6312
|
+
if (own13(value, "gsmNumber") || own13(value, "buyerProtected") && value.buyerProtected !== false || record33(card) && (own13(card, "registerCard") && card.registerCard !== 0 || own13(card, "registerConsumerCard") && card.registerConsumerCard !== false)) {
|
|
6313
|
+
return refuse38("iyzico_keeps_card");
|
|
6314
|
+
}
|
|
6315
|
+
if (Number.isSafeInteger(value.installment) && value.installment > 1)
|
|
6316
|
+
return refuse38("iyzico_installments_refused");
|
|
6317
|
+
if (!inOrder6(value, IYZICO_BODY_KEYS) || !["installment", "paidPrice", "paymentChannel", "paymentCard"].every((key) => own13(value, key)) || value.installment !== 1 || hundredths(value.paidPrice) === null || !CHANNELS.includes(value.paymentChannel) || own13(value, "pwiMetadata") && !metadata(value.pwiMetadata))
|
|
6318
|
+
return refuse38("iyzico_body_unsupported");
|
|
6319
|
+
if (!record33(card) || Object.keys(card).join() !== IYZICO_CARD_KEYS.join() || typeof card.cardNumber !== "string" || !CARD_NUMBER19.test(card.cardNumber) || !holderName2(card.cardHolderName) || typeof card.expireYear !== "string" || !YEAR20.test(card.expireYear) || typeof card.expireMonth !== "string" || !MONTH19.test(card.expireMonth) || typeof card.cvc !== "string" || !SECURITY_CODE23.test(card.cvc))
|
|
6320
|
+
return refuse38("iyzico_body_unsupported");
|
|
6321
|
+
return CARD37;
|
|
6322
|
+
}
|
|
6323
|
+
var iyzico_default = /* @__PURE__ */ registerProcessor({
|
|
6324
|
+
psp: IYZICO_PSP,
|
|
6325
|
+
definitions: [
|
|
6326
|
+
{
|
|
6327
|
+
psp: "iyzico",
|
|
6328
|
+
// The Checkout Form's card payment, as the header above reads it. Sandbox has its own host, so the device sends
|
|
6329
|
+
// a test-mode payment only iyzico's documented test cards (hostEnvironmentPinned, device-replay.js S7). Ships dark:
|
|
6330
|
+
// served only to a client that declares `iyzico_checkout_form`, for a company the backend's gate turns iyzico on
|
|
6331
|
+
// for, and autopilot never sends it.
|
|
6332
|
+
capability: "iyzico_checkout_form",
|
|
6333
|
+
match: "(?:sandbox-)?api\\.iyzipay\\.com/payment/iyzipos/checkoutform/(?:auth|initialize3ds)/ecom",
|
|
6334
|
+
hosts: ["^api\\.iyzipay\\.com$", "^sandbox-api\\.iyzipay\\.com$"],
|
|
6335
|
+
sandboxHosts: ["^sandbox-api\\.iyzipay\\.com$"],
|
|
6336
|
+
hostEnvironmentPinned: true,
|
|
6337
|
+
encoding: "json",
|
|
6338
|
+
// The form's session token and its Accept. Origin, Referer and cookies never ride, and neither does IYZI_LC,
|
|
6339
|
+
// which iyzico's preflight does not allow.
|
|
6340
|
+
passthroughHeaders: ["^x-iyzi-token$", "^accept$"],
|
|
6341
|
+
jsonCardFields: [["paymentCard", "cardNumber"]]
|
|
6342
|
+
}
|
|
6343
|
+
],
|
|
6344
|
+
// Only the cardholder's device sends it, after a person approves; 3-D Secure needs that person at the browser.
|
|
6345
|
+
refusedOperations: [IYZICO_OPERATION],
|
|
6346
|
+
// iyzico answers the form's result (CF retrieve) only to the merchant's API key and secret.
|
|
6347
|
+
settlementReadback: {
|
|
6348
|
+
answer: "none",
|
|
6349
|
+
reason: "merchant_credential_required",
|
|
6350
|
+
note: "The processor answers a payment result only to the server credentials of the shop; the intercepted request carries a checkout reference and no credential.",
|
|
6351
|
+
source: "https://docs.iyzico.com/en/payment-methods/checkoutform/cf-implementation/cf-retrieve"
|
|
6352
|
+
},
|
|
6353
|
+
exactUrl: isIyzicoCardUrl,
|
|
6354
|
+
bodyGate: (url, body) => url !== void 0 && !isIyzicoCardUrl(url) ? refuse38("iyzico_url_refused") : iyzicoBodyVerdict(body)
|
|
6355
|
+
});
|
|
6128
6356
|
// src/processors/midtrans.js
|
|
6129
6357
|
var MIDTRANS_PSP = "midtrans";
|
|
6130
6358
|
var MIDTRANS_OPERATION = "midtrans.card_request";
|
|
6131
6359
|
var MIDTRANS_TOKEN_URL = "https://api.midtrans.com/v2/token";
|
|
6132
6360
|
var MIDTRANS_SANDBOX_TOKEN_URL = "https://api.sandbox.midtrans.com/v2/token";
|
|
6133
6361
|
var MIDTRANS_TOKEN_KEYS = /* @__PURE__ */ Object.freeze(["card_cvv", "card_number", "card_exp_month", "card_exp_year", "installment_term"]);
|
|
6134
|
-
var
|
|
6135
|
-
var
|
|
6136
|
-
var
|
|
6137
|
-
var
|
|
6138
|
-
var
|
|
6362
|
+
var BODY_LIMIT37 = 4096;
|
|
6363
|
+
var CARD_NUMBER20 = /^[0-9]{12,19}$/;
|
|
6364
|
+
var SECURITY_CODE24 = /^[0-9]{3,4}$/;
|
|
6365
|
+
var MONTH20 = /^(?:0[1-9]|1[0-2])$/;
|
|
6366
|
+
var YEAR21 = /^20[0-9]{2}$/;
|
|
6139
6367
|
var TERM = /^[0-9]{1,3}$/;
|
|
6140
|
-
var
|
|
6141
|
-
var
|
|
6142
|
-
var
|
|
6368
|
+
var record34 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
6369
|
+
var own14 = (value, key) => Object.prototype.hasOwnProperty.call(value, key);
|
|
6370
|
+
var inOrder7 = (value, keys) => {
|
|
6143
6371
|
let at = 0;
|
|
6144
6372
|
for (const name of Object.keys(value)) {
|
|
6145
6373
|
while (at < keys.length && keys[at] !== name)
|
|
@@ -6150,18 +6378,18 @@ var inOrder6 = (value, keys) => {
|
|
|
6150
6378
|
}
|
|
6151
6379
|
return true;
|
|
6152
6380
|
};
|
|
6153
|
-
var
|
|
6154
|
-
var
|
|
6381
|
+
var refuse39 = (code) => Object.freeze({ verdict: "refuse", code });
|
|
6382
|
+
var CARD38 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
|
|
6155
6383
|
function isMidtransTokenUrl(url) {
|
|
6156
6384
|
return url === MIDTRANS_TOKEN_URL || url === MIDTRANS_SANDBOX_TOKEN_URL;
|
|
6157
6385
|
}
|
|
6158
|
-
function
|
|
6159
|
-
if (typeof body !== "string" || body === "" || body.length >
|
|
6386
|
+
function readBody23(body) {
|
|
6387
|
+
if (typeof body !== "string" || body === "" || body.length > BODY_LIMIT37)
|
|
6160
6388
|
return null;
|
|
6161
6389
|
let value;
|
|
6162
6390
|
try {
|
|
6163
6391
|
value = JSON.parse(body);
|
|
6164
|
-
if (!
|
|
6392
|
+
if (!record34(value) || JSON.stringify(value) !== body)
|
|
6165
6393
|
return null;
|
|
6166
6394
|
}
|
|
6167
6395
|
catch {
|
|
@@ -6170,20 +6398,20 @@ function readBody21(body) {
|
|
|
6170
6398
|
return value;
|
|
6171
6399
|
}
|
|
6172
6400
|
function midtransBodyVerdict(body) {
|
|
6173
|
-
const value =
|
|
6174
|
-
if (value === null || !
|
|
6175
|
-
if (
|
|
6176
|
-
return
|
|
6177
|
-
return
|
|
6401
|
+
const value = readBody23(body);
|
|
6402
|
+
if (value === null || !inOrder7(value, MIDTRANS_TOKEN_KEYS)) {
|
|
6403
|
+
if (record34(value) && (own14(value, "token_id") || own14(value, "two_click")) && !own14(value, "card_number"))
|
|
6404
|
+
return refuse39("midtrans_saved_card");
|
|
6405
|
+
return refuse39("midtrans_body_unsupported");
|
|
6178
6406
|
}
|
|
6179
|
-
if (!
|
|
6180
|
-
return
|
|
6407
|
+
if (!own14(value, "card_cvv") || !own14(value, "card_number") || !own14(value, "card_exp_month") || !own14(value, "card_exp_year")) {
|
|
6408
|
+
return refuse39("midtrans_body_unsupported");
|
|
6181
6409
|
}
|
|
6182
|
-
if (typeof value.card_cvv !== "string" || !
|
|
6183
|
-
return
|
|
6184
|
-
if (
|
|
6185
|
-
return
|
|
6186
|
-
return
|
|
6410
|
+
if (typeof value.card_cvv !== "string" || !SECURITY_CODE24.test(value.card_cvv) || typeof value.card_number !== "string" || !CARD_NUMBER20.test(value.card_number) || typeof value.card_exp_month !== "string" || !MONTH20.test(value.card_exp_month) || typeof value.card_exp_year !== "string" || !YEAR21.test(value.card_exp_year))
|
|
6411
|
+
return refuse39("midtrans_body_unsupported");
|
|
6412
|
+
if (own14(value, "installment_term") && (typeof value.installment_term !== "string" || !TERM.test(value.installment_term)))
|
|
6413
|
+
return refuse39("midtrans_body_unsupported");
|
|
6414
|
+
return CARD38;
|
|
6187
6415
|
}
|
|
6188
6416
|
var midtrans_default = /* @__PURE__ */ registerProcessor({
|
|
6189
6417
|
psp: MIDTRANS_PSP,
|
|
@@ -6214,9 +6442,1058 @@ var midtrans_default = /* @__PURE__ */ registerProcessor({
|
|
|
6214
6442
|
exactUrl: isMidtransTokenUrl,
|
|
6215
6443
|
bodyGate: (url, body) => url !== void 0 && !isMidtransTokenUrl(url) ? { verdict: "refuse", code: "midtrans_url_refused" } : midtransBodyVerdict(body)
|
|
6216
6444
|
});
|
|
6445
|
+
// src/processors/oceanpayment.js
|
|
6446
|
+
var OCEANPAYMENT_PSP = "oceanpayment";
|
|
6447
|
+
var OCEANPAYMENT_OPERATION = "oceanpayment.card_request";
|
|
6448
|
+
var OCEANPAYMENT_HOSTS = /* @__PURE__ */ Object.freeze({ "secure.oceanpayment.com": "production", "test-secure.oceanpayment.com": "sandbox" });
|
|
6449
|
+
var OCEANPAYMENT_FORM_FIELDS = /* @__PURE__ */ Object.freeze([
|
|
6450
|
+
"card_number_three",
|
|
6451
|
+
"card_number_two",
|
|
6452
|
+
"card_number_temp",
|
|
6453
|
+
"card_number",
|
|
6454
|
+
"card_date",
|
|
6455
|
+
"card_year",
|
|
6456
|
+
"card_month",
|
|
6457
|
+
"card_secureCode",
|
|
6458
|
+
"copyCard",
|
|
6459
|
+
"closePage",
|
|
6460
|
+
"starttime",
|
|
6461
|
+
"endtime",
|
|
6462
|
+
"comloadpage",
|
|
6463
|
+
"timezone",
|
|
6464
|
+
"OSLang",
|
|
6465
|
+
"os",
|
|
6466
|
+
"brower",
|
|
6467
|
+
"BrowerLang",
|
|
6468
|
+
"resolution",
|
|
6469
|
+
"methods",
|
|
6470
|
+
"reference_id",
|
|
6471
|
+
"methods",
|
|
6472
|
+
"reference"
|
|
6473
|
+
]);
|
|
6474
|
+
var URL_LIMIT14 = 2048;
|
|
6475
|
+
var BODY_LIMIT38 = 8192;
|
|
6476
|
+
var SEND_PAY = /^\/gateway\/sendPay;jsessionid=[A-Za-z0-9._!-]{16,128}$/;
|
|
6477
|
+
var own15 = (value, key) => Object.prototype.hasOwnProperty.call(value, key);
|
|
6478
|
+
var exact4 = (pattern, value) => typeof value === "string" && pattern.test(value);
|
|
6479
|
+
var CARD_RUN = /[0-9]{12}/;
|
|
6480
|
+
var printable5 = (max) => (value) => typeof value === "string" && value.length <= max && /^[\x20-\x7e]*$/.test(value) && !CARD_RUN.test(value);
|
|
6481
|
+
var STAMP = /^(?:|20[0-9]{2}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12][0-9]|3[01]) (?:[01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]\.[0-9]{3})$/;
|
|
6482
|
+
var LANGUAGE4 = /^(?:|[A-Za-z]{2,8}(?:[-_][A-Za-z0-9]{1,8}){0,3})$/;
|
|
6483
|
+
var SHAPES2 = /* @__PURE__ */ new Map([
|
|
6484
|
+
["customerCardType", (v) => v === ""],
|
|
6485
|
+
// The page's paste and typing markers: "0" until typed, the number's length when its key handler read it, or "N"
|
|
6486
|
+
// after a paste.
|
|
6487
|
+
["card_number_three", (v) => exact4(/^(?:0|N|[1-9]|1[0-9])$/, v)],
|
|
6488
|
+
["card_number_two", (v) => exact4(/^(?:0|[1-9]|1[0-9])$/, v)],
|
|
6489
|
+
["card_number_temp", (v) => exact4(/^[0-9]{4}(?: ?[0-9]{4}){3}$/, v)],
|
|
6490
|
+
["card_number", (v) => exact4(/^[0-9]{16}$/, v)],
|
|
6491
|
+
["card_date", (v) => exact4(/^(?:0[1-9]|1[0-2])\/[0-9]{2}$/, v)],
|
|
6492
|
+
["card_year", (v) => exact4(/^20[0-9]{2}$/, v)],
|
|
6493
|
+
["card_month", (v) => exact4(/^(?:0[1-9]|1[0-2])$/, v)],
|
|
6494
|
+
["card_secureCode", (v) => exact4(/^[0-9]{3,4}$/, v)],
|
|
6495
|
+
["copyCard", (v) => v === "" || v === "0" || v === "1"],
|
|
6496
|
+
// PAY NOW's handler sets it to 1 before the page submits.
|
|
6497
|
+
["closePage", (v) => v === "1"],
|
|
6498
|
+
["starttime", (v) => exact4(STAMP, v)],
|
|
6499
|
+
["endtime", (v) => exact4(STAMP, v)],
|
|
6500
|
+
["comloadpage", (v) => v === "0" || v === "1"],
|
|
6501
|
+
// getTimezoneOffset()/60*-1: whole or fractional hours.
|
|
6502
|
+
["timezone", (v) => exact4(/^(?:|-?(?:[0-9]|1[0-4])(?:\.[0-9]{1,2})?)$/, v)],
|
|
6503
|
+
["OSLang", (v) => exact4(LANGUAGE4, v)],
|
|
6504
|
+
["os", printable5(64)],
|
|
6505
|
+
["brower", printable5(128)],
|
|
6506
|
+
["BrowerLang", (v) => exact4(LANGUAGE4, v)],
|
|
6507
|
+
["resolution", printable5(32)],
|
|
6508
|
+
["methods", (v) => v === "1"],
|
|
6509
|
+
["reference_id", (v) => v === ""],
|
|
6510
|
+
// The page's own trade number.
|
|
6511
|
+
["reference", (v) => exact4(/^[0-9]{1,40}$/, v)],
|
|
6512
|
+
["button", (v) => v === ""]
|
|
6513
|
+
]);
|
|
6514
|
+
function oceanpaymentSendPayUrl(url) {
|
|
6515
|
+
if (typeof url !== "string" || url.length > URL_LIMIT14 || url.includes("?") || url.includes("#"))
|
|
6516
|
+
return null;
|
|
6517
|
+
let parsed;
|
|
6518
|
+
try {
|
|
6519
|
+
parsed = new URL(url);
|
|
6520
|
+
}
|
|
6521
|
+
catch {
|
|
6522
|
+
return null;
|
|
6523
|
+
}
|
|
6524
|
+
if (parsed.href !== url || parsed.protocol !== "https:" || parsed.port || parsed.username || parsed.password || !own15(OCEANPAYMENT_HOSTS, parsed.hostname) || !SEND_PAY.test(parsed.pathname))
|
|
6525
|
+
return null;
|
|
6526
|
+
return Object.freeze({ host: parsed.hostname, environment: OCEANPAYMENT_HOSTS[parsed.hostname] });
|
|
6527
|
+
}
|
|
6528
|
+
var isOceanpaymentSendPayUrl = (url) => oceanpaymentSendPayUrl(url) !== null;
|
|
6529
|
+
function formEncode3(value) {
|
|
6530
|
+
let encoded;
|
|
6531
|
+
try {
|
|
6532
|
+
encoded = encodeURIComponent(value);
|
|
6533
|
+
}
|
|
6534
|
+
catch {
|
|
6535
|
+
return null;
|
|
6536
|
+
}
|
|
6537
|
+
return encoded.replace(/[!'()~]/g, (ch) => `%${ch.charCodeAt(0).toString(16).toUpperCase()}`).replace(/%20/g, "+");
|
|
6538
|
+
}
|
|
6539
|
+
function formDecode2(raw) {
|
|
6540
|
+
if (!/^(?:[A-Za-z0-9*._+-]|%[0-9A-F]{2})*$/.test(raw))
|
|
6541
|
+
return null;
|
|
6542
|
+
let value;
|
|
6543
|
+
try {
|
|
6544
|
+
value = decodeURIComponent(raw.replace(/\+/g, "%20"));
|
|
6545
|
+
}
|
|
6546
|
+
catch {
|
|
6547
|
+
return null;
|
|
6548
|
+
}
|
|
6549
|
+
return formEncode3(value) === raw ? value : null;
|
|
6550
|
+
}
|
|
6551
|
+
function readPairs2(body) {
|
|
6552
|
+
if (typeof body !== "string" || body === "" || body.length > BODY_LIMIT38)
|
|
6553
|
+
return null;
|
|
6554
|
+
const pairs = [];
|
|
6555
|
+
for (const chunk of body.split("&")) {
|
|
6556
|
+
const separator = chunk.indexOf("=");
|
|
6557
|
+
if (separator < 1)
|
|
6558
|
+
return null;
|
|
6559
|
+
const rawName = chunk.slice(0, separator), raw = chunk.slice(separator + 1);
|
|
6560
|
+
const name = formDecode2(rawName), value = formDecode2(raw);
|
|
6561
|
+
if (name === null || value === null)
|
|
6562
|
+
return null;
|
|
6563
|
+
pairs.push({ name, rawName, raw, value });
|
|
6564
|
+
}
|
|
6565
|
+
return pairs;
|
|
6566
|
+
}
|
|
6567
|
+
function formPairs(body) {
|
|
6568
|
+
const pairs = readPairs2(body);
|
|
6569
|
+
if (!pairs)
|
|
6570
|
+
return null;
|
|
6571
|
+
const start = pairs[0].name === "customerCardType" ? 1 : 0;
|
|
6572
|
+
const end = pairs[pairs.length - 1].name === "button" ? pairs.length - 1 : pairs.length;
|
|
6573
|
+
if (end - start !== OCEANPAYMENT_FORM_FIELDS.length || OCEANPAYMENT_FORM_FIELDS.some((name, i) => pairs[start + i].name !== name))
|
|
6574
|
+
return null;
|
|
6575
|
+
return pairs;
|
|
6576
|
+
}
|
|
6577
|
+
var valueOf = (pairs, name) => pairs.find((pair) => pair.name === name)?.value;
|
|
6578
|
+
function bodyRefusal(body) {
|
|
6579
|
+
const pairs = formPairs(body);
|
|
6580
|
+
if (!pairs)
|
|
6581
|
+
return "oceanpayment_body_unsupported";
|
|
6582
|
+
if (pairs[0].name === "customerCardType" && pairs[0].value !== "")
|
|
6583
|
+
return "oceanpayment_card_brand_refused";
|
|
6584
|
+
if (valueOf(pairs, "reference_id") !== "")
|
|
6585
|
+
return "oceanpayment_device_data_refused";
|
|
6586
|
+
if (pairs.some(({ name, value }) => !SHAPES2.get(name)(value)))
|
|
6587
|
+
return "oceanpayment_body_unsupported";
|
|
6588
|
+
const number = valueOf(pairs, "card_number");
|
|
6589
|
+
const temp = valueOf(pairs, "card_number_temp");
|
|
6590
|
+
const [month, year] = valueOf(pairs, "card_date").split("/");
|
|
6591
|
+
if (temp.replace(/ /g, "") !== number || temp !== number && temp !== spaced(number))
|
|
6592
|
+
return "oceanpayment_body_unsupported";
|
|
6593
|
+
if (valueOf(pairs, "card_month") !== month || valueOf(pairs, "card_year") !== `20${year}`)
|
|
6594
|
+
return "oceanpayment_body_unsupported";
|
|
6595
|
+
return null;
|
|
6596
|
+
}
|
|
6597
|
+
var spaced = (number) => number.replace(/([0-9]{4})(?=[0-9])/g, "$1 ");
|
|
6598
|
+
function oceanpaymentBodyVerdict(body) {
|
|
6599
|
+
const code = bodyRefusal(body);
|
|
6600
|
+
return code ? Object.freeze({ verdict: "refuse", code }) : Object.freeze({ verdict: "card" });
|
|
6601
|
+
}
|
|
6602
|
+
var oceanpayment_default = /* @__PURE__ */ registerProcessor({
|
|
6603
|
+
psp: OCEANPAYMENT_PSP,
|
|
6604
|
+
definitions: [
|
|
6605
|
+
{
|
|
6606
|
+
psp: "oceanpayment",
|
|
6607
|
+
// The hosted page's card post, as the header above reads it. The sandbox has its own host, so a test row's device
|
|
6608
|
+
// sends only Oceanpayment's documented test cards (hostEnvironmentPinned, device-replay.js S7).
|
|
6609
|
+
// Ships dark: served only to a client that declares `oceanpayment_hosted_payment_page`, and only for a company the
|
|
6610
|
+
// backend's processor gate turns Oceanpayment on for. `(?![\w/.%;=!-])` ends the path for a consumer that tests
|
|
6611
|
+
// `match` unanchored.
|
|
6612
|
+
capability: "oceanpayment_hosted_payment_page",
|
|
6613
|
+
match: "(?:test-)?secure\\.oceanpayment\\.com/gateway/sendPay;jsessionid=[A-Za-z0-9._!-]{16,128}(?![\\w/.%;=!-])",
|
|
6614
|
+
hosts: ["^secure\\.oceanpayment\\.com$", "^test-secure\\.oceanpayment\\.com$"],
|
|
6615
|
+
sandboxHosts: ["^test-secure\\.oceanpayment\\.com$"],
|
|
6616
|
+
hostEnvironmentPinned: true,
|
|
6617
|
+
encoding: "form",
|
|
6618
|
+
// A form navigation: nothing but its type is replayed. Origin, Referer and cookies never ride.
|
|
6619
|
+
passthroughHeaders: [],
|
|
6620
|
+
cardFields: ["card_number"]
|
|
6621
|
+
}
|
|
6622
|
+
],
|
|
6623
|
+
// Only the cardholder's device sends this card, after a person approves; no reviewed list names oceanpayment.
|
|
6624
|
+
refusedOperations: [OCEANPAYMENT_OPERATION],
|
|
6625
|
+
// Not surveyed: Oceanpayment tells the merchant's server the result (its noticeUrl), and reading a payment back takes the
|
|
6626
|
+
// merchant's own secure code, which Agentcard never holds.
|
|
6627
|
+
settlementReadback: "not_surveyed",
|
|
6628
|
+
exactUrl: isOceanpaymentSendPayUrl,
|
|
6629
|
+
bodyGate: (url, body) => url !== void 0 && !isOceanpaymentSendPayUrl(url) ? Object.freeze({ verdict: "refuse", code: "oceanpayment_url_refused" }) : oceanpaymentBodyVerdict(body)
|
|
6630
|
+
// No amount reader: the post names none, so the agent's pair is the figure the cardholder approves.
|
|
6631
|
+
});
|
|
6632
|
+
// src/processors/paymentwall.js
|
|
6633
|
+
var PAYMENTWALL_PSP = "paymentwall";
|
|
6634
|
+
var PAYMENTWALL_OPERATION = "paymentwall.card_request";
|
|
6635
|
+
var PAYMENTWALL_TOKEN_URL = "https://pwgateway.com/api/token";
|
|
6636
|
+
var PAYMENTWALL_SANDBOX_TOKEN_URL = "https://api.paymentwall.com/api/brick/token";
|
|
6637
|
+
var BODY_LIMIT39 = 2048;
|
|
6638
|
+
var KEY3 = "public_key";
|
|
6639
|
+
var PUBLIC_KEY2 = /^(?:t_)?[A-Za-z0-9]{16,64}$/;
|
|
6640
|
+
var SHAPES3 = /* @__PURE__ */ Object.freeze({
|
|
6641
|
+
[KEY3]: PUBLIC_KEY2,
|
|
6642
|
+
"card[number]": /^[0-9]{12,19}$/,
|
|
6643
|
+
"card[exp_month]": /^(?:0?[1-9]|1[0-2])$/,
|
|
6644
|
+
"card[exp_year]": /^(?:[0-9]{2}|20[0-9]{2})$/,
|
|
6645
|
+
"card[cvv]": /^[0-9]{3,4}$/
|
|
6646
|
+
});
|
|
6647
|
+
var refuse40 = (code) => Object.freeze({ verdict: "refuse", code });
|
|
6648
|
+
var CARD39 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
|
|
6649
|
+
function luhn9(digits3) {
|
|
6650
|
+
let sum = 0;
|
|
6651
|
+
for (let at = 0; at < digits3.length; at += 1) {
|
|
6652
|
+
let digit = Number(digits3[digits3.length - 1 - at]);
|
|
6653
|
+
if (at % 2 === 1) {
|
|
6654
|
+
digit *= 2;
|
|
6655
|
+
if (digit > 9)
|
|
6656
|
+
digit -= 9;
|
|
6657
|
+
}
|
|
6658
|
+
sum += digit;
|
|
6659
|
+
}
|
|
6660
|
+
return sum % 10 === 0;
|
|
6661
|
+
}
|
|
6662
|
+
function paymentwallUrlEnvironment(url) {
|
|
6663
|
+
if (url === PAYMENTWALL_TOKEN_URL)
|
|
6664
|
+
return "production";
|
|
6665
|
+
return url === PAYMENTWALL_SANDBOX_TOKEN_URL ? "sandbox" : null;
|
|
6666
|
+
}
|
|
6667
|
+
function isPaymentwallTokenUrl(url) {
|
|
6668
|
+
return paymentwallUrlEnvironment(url) !== null;
|
|
6669
|
+
}
|
|
6670
|
+
function paymentwallKeyEnvironment(publicKey) {
|
|
6671
|
+
if (typeof publicKey !== "string" || !PUBLIC_KEY2.test(publicKey))
|
|
6672
|
+
return null;
|
|
6673
|
+
return publicKey.startsWith("t_") ? "sandbox" : "production";
|
|
6674
|
+
}
|
|
6675
|
+
function readPairs3(body) {
|
|
6676
|
+
if (typeof body !== "string" || body === "" || body.length > BODY_LIMIT39 || !/^[A-Za-z0-9_[\]=&]+$/.test(body))
|
|
6677
|
+
return null;
|
|
6678
|
+
const pairs = /* @__PURE__ */ new Map();
|
|
6679
|
+
for (const chunk of body.split("&")) {
|
|
6680
|
+
const eq = chunk.indexOf("=");
|
|
6681
|
+
if (eq <= 0 || chunk.indexOf("=", eq + 1) !== -1)
|
|
6682
|
+
return null;
|
|
6683
|
+
const key = chunk.slice(0, eq);
|
|
6684
|
+
if (pairs.has(key))
|
|
6685
|
+
return null;
|
|
6686
|
+
pairs.set(key, chunk.slice(eq + 1));
|
|
6687
|
+
}
|
|
6688
|
+
return pairs;
|
|
6689
|
+
}
|
|
6690
|
+
function paymentwallBodyVerdict(body, url) {
|
|
6691
|
+
if (url !== void 0 && !isPaymentwallTokenUrl(url))
|
|
6692
|
+
return refuse40("paymentwall_url_refused");
|
|
6693
|
+
const pairs = readPairs3(body);
|
|
6694
|
+
if (pairs === null)
|
|
6695
|
+
return refuse40("paymentwall_body_unsupported");
|
|
6696
|
+
if (pairs.has("card[token]") && !pairs.has("card[number]"))
|
|
6697
|
+
return refuse40("paymentwall_saved_card");
|
|
6698
|
+
const keys = Object.keys(SHAPES3);
|
|
6699
|
+
if (pairs.size !== keys.length || !keys.every((key) => pairs.has(key) && SHAPES3[key].test(pairs.get(key)))) {
|
|
6700
|
+
return refuse40("paymentwall_body_unsupported");
|
|
6701
|
+
}
|
|
6702
|
+
if (!luhn9(pairs.get("card[number]")))
|
|
6703
|
+
return refuse40("paymentwall_body_unsupported");
|
|
6704
|
+
if (url !== void 0 && paymentwallKeyEnvironment(pairs.get(KEY3)) !== paymentwallUrlEnvironment(url))
|
|
6705
|
+
return refuse40("paymentwall_key_refused");
|
|
6706
|
+
return CARD39;
|
|
6707
|
+
}
|
|
6708
|
+
var paymentwall_default = /* @__PURE__ */ registerProcessor({
|
|
6709
|
+
psp: PAYMENTWALL_PSP,
|
|
6710
|
+
definitions: [
|
|
6711
|
+
{
|
|
6712
|
+
psp: "paymentwall",
|
|
6713
|
+
// Brick's token request, as the header above reads it. A test key's request has its own host, so the device sends
|
|
6714
|
+
// it only Paymentwall's documented test cards (hostEnvironmentPinned, device-replay.js S7). Ships dark: served only
|
|
6715
|
+
// to a client that declares `paymentwall_card_token`, for a company the backend's gate turns it on for
|
|
6716
|
+
// (checkout-processor-gate.ts), and the device sends a live card only under a key a reviewed pin names.
|
|
6717
|
+
capability: "paymentwall_card_token",
|
|
6718
|
+
match: "(?:pwgateway\\.com/api/token|api\\.paymentwall\\.com/api/brick/token)",
|
|
6719
|
+
hosts: ["^pwgateway\\.com$", "^api\\.paymentwall\\.com$"],
|
|
6720
|
+
sandboxHosts: ["^api\\.paymentwall\\.com$"],
|
|
6721
|
+
hostEnvironmentPinned: true,
|
|
6722
|
+
encoding: "form",
|
|
6723
|
+
// Brick's XHR sets the form Content-Type alone, and that always rides. Origin, Referer and cookies never do.
|
|
6724
|
+
passthroughHeaders: [],
|
|
6725
|
+
cardFields: ["card[number]"]
|
|
6726
|
+
}
|
|
6727
|
+
],
|
|
6728
|
+
// Only the cardholder's device sends a card request, after a person approves; no reviewed list names paymentwall.
|
|
6729
|
+
refusedOperations: [PAYMENTWALL_OPERATION],
|
|
6730
|
+
// Not surveyed: the token moves no money, and the charge that spends it happens out of this request.
|
|
6731
|
+
settlementReadback: "not_surveyed",
|
|
6732
|
+
exactUrl: isPaymentwallTokenUrl,
|
|
6733
|
+
bodyGate: (url, body) => paymentwallBodyVerdict(body, url)
|
|
6734
|
+
});
|
|
6735
|
+
// src/processors/ekashu.js
|
|
6736
|
+
var EKASHU_HOSTS = Object.freeze(["live.ekashu.com", "test.ekashu.com"]);
|
|
6737
|
+
var EKASHU_TEST_PANS = Object.freeze(["4100000000000100", "5100000000000107"]);
|
|
6738
|
+
var EKASHU_SIGNED_FIELDS = Object.freeze([
|
|
6739
|
+
"ekashu_3d_secure_verify",
|
|
6740
|
+
"ekashu_amount",
|
|
6741
|
+
"ekashu_amount_format",
|
|
6742
|
+
"ekashu_auto_confirm",
|
|
6743
|
+
"ekashu_callback_failure_url",
|
|
6744
|
+
"ekashu_callback_include_post",
|
|
6745
|
+
"ekashu_callback_success_url",
|
|
6746
|
+
"ekashu_card_address_editable",
|
|
6747
|
+
"ekashu_card_address_required",
|
|
6748
|
+
"ekashu_card_address_verify",
|
|
6749
|
+
"ekashu_card_email_address_mandatory",
|
|
6750
|
+
"ekashu_card_phone_number_mandatory",
|
|
6751
|
+
"ekashu_card_title_mandatory",
|
|
6752
|
+
"ekashu_card_zip_code_verify",
|
|
6753
|
+
"ekashu_currency",
|
|
6754
|
+
"ekashu_delivery_address_editable",
|
|
6755
|
+
"ekashu_delivery_address_required",
|
|
6756
|
+
"ekashu_delivery_email_address_mandatory",
|
|
6757
|
+
"ekashu_delivery_phone_number_mandatory",
|
|
6758
|
+
"ekashu_delivery_title_mandatory",
|
|
6759
|
+
"ekashu_description",
|
|
6760
|
+
"ekashu_device",
|
|
6761
|
+
"ekashu_duplicate_check",
|
|
6762
|
+
"ekashu_duplicate_minutes",
|
|
6763
|
+
"ekashu_failure_return_text",
|
|
6764
|
+
"ekashu_failure_url",
|
|
6765
|
+
"ekashu_hash_code_format",
|
|
6766
|
+
"ekashu_hash_code_type",
|
|
6767
|
+
"ekashu_hash_code_version",
|
|
6768
|
+
"ekashu_include_post",
|
|
6769
|
+
"ekashu_invoice_address_editable",
|
|
6770
|
+
"ekashu_invoice_address_required",
|
|
6771
|
+
"ekashu_invoice_email_address_mandatory",
|
|
6772
|
+
"ekashu_invoice_phone_number_mandatory",
|
|
6773
|
+
"ekashu_invoice_title_mandatory",
|
|
6774
|
+
"ekashu_locale",
|
|
6775
|
+
"ekashu_payment_methods",
|
|
6776
|
+
"ekashu_reference",
|
|
6777
|
+
"ekashu_request_type",
|
|
6778
|
+
"ekashu_return_text",
|
|
6779
|
+
"ekashu_seller_address",
|
|
6780
|
+
"ekashu_seller_email_address",
|
|
6781
|
+
"ekashu_seller_id",
|
|
6782
|
+
"ekashu_seller_key",
|
|
6783
|
+
"ekashu_seller_name",
|
|
6784
|
+
"ekashu_shortcut_icon",
|
|
6785
|
+
"ekashu_style_sheet",
|
|
6786
|
+
"ekashu_success_url",
|
|
6787
|
+
"ekashu_title",
|
|
6788
|
+
"ekashu_verification_value_mask",
|
|
6789
|
+
"ekashu_verification_value_verify",
|
|
6790
|
+
"ekashu_viewport"
|
|
6791
|
+
]);
|
|
6792
|
+
var REQUIRED = Object.freeze([
|
|
6793
|
+
"ekashu_seller_id",
|
|
6794
|
+
"ekashu_seller_key",
|
|
6795
|
+
"ekashu_amount",
|
|
6796
|
+
"ekashu_currency",
|
|
6797
|
+
"ekashu_reference",
|
|
6798
|
+
"ekashu_hash_code",
|
|
6799
|
+
"ekashu_hash_code_type",
|
|
6800
|
+
"ekashu_hash_code_version",
|
|
6801
|
+
"ekashu_success_url",
|
|
6802
|
+
"ekashu_failure_url",
|
|
6803
|
+
"ekashu_callback_success_url"
|
|
6804
|
+
]);
|
|
6805
|
+
var CARD_KEYS16 = Object.freeze([
|
|
6806
|
+
"ekashu_card_number",
|
|
6807
|
+
"ekashu_expires_end_month",
|
|
6808
|
+
"ekashu_expires_end_year",
|
|
6809
|
+
"ekashu_verification_value",
|
|
6810
|
+
"ekashu_valid_from_month",
|
|
6811
|
+
"ekashu_valid_from_year",
|
|
6812
|
+
"ekashu_issue_number"
|
|
6813
|
+
]);
|
|
6814
|
+
var PAGE_KEYS = Object.freeze(["ekashu_stage", "ekashu_context", "ekashu_submission_id"]);
|
|
6815
|
+
var STORED_KEYS = Object.freeze(["ekashu_card_hash", "ekashu_card_reference", "ekashu_cof_initiated_by", "ekashu_cof_reason", "ekashu_cof_id"]);
|
|
6816
|
+
var REDIRECT_KEYS = Object.freeze(["ekashu_success_url", "ekashu_failure_url", "ekashu_return_url"]);
|
|
6817
|
+
var CALLBACK_KEYS = Object.freeze(["ekashu_callback_success_url", "ekashu_callback_failure_url"]);
|
|
6818
|
+
var MAX_ENTRY = 16 * 1024;
|
|
6819
|
+
var MAX_PAGE = 256 * 1024;
|
|
6820
|
+
var EKASHU_SELLERS = Object.freeze([
|
|
6821
|
+
Object.freeze({ sellerId: "25060100", merchant: "Heathrow Drop-off", entryHost: "heathrowdropoff.apcoa.com", callbackHost: "incomingapi.apcoa.co.uk" })
|
|
6822
|
+
]);
|
|
6823
|
+
var CARD_FIELDS = Object.freeze({
|
|
6824
|
+
number: "ekashu_card_number",
|
|
6825
|
+
month: "ekashu_expires_end_month",
|
|
6826
|
+
year: "ekashu_expires_end_year",
|
|
6827
|
+
cvc: "ekashu_verification_value"
|
|
6828
|
+
});
|
|
6829
|
+
var NAME_FIELDS = Object.freeze({ first: "ekashu_card_first_name", last: "ekashu_card_last_name" });
|
|
6830
|
+
var LEFT_EMPTY = Object.freeze(["ekashu_card_title", "ekashu_valid_from_month", "ekashu_valid_from_year", "ekashu_issue_number"]);
|
|
6831
|
+
var VISIBLE = /* @__PURE__ */ new Set([...Object.values(CARD_FIELDS), ...Object.values(NAME_FIELDS), ...LEFT_EMPTY]);
|
|
6832
|
+
// src/processors/payplug.js
|
|
6833
|
+
var PAYPLUG_PSP = "payplug";
|
|
6834
|
+
var PAYPLUG_OPERATION = "payplug.hosted_sale";
|
|
6835
|
+
var PAYPLUG_HOST = "secure.payplug.com";
|
|
6836
|
+
var ENTRY_PATH = /^\/pay\/(?:(test)\/)?([A-Za-z0-9]{22})$/;
|
|
6837
|
+
var MAX_URL = 256;
|
|
6838
|
+
var field2 = (name, reason) => ({ ok: false, code: "hosted_form_field_refused", field: name, reason });
|
|
6839
|
+
function payplugEntry(raw) {
|
|
6840
|
+
if (typeof raw !== "string" || raw.length > MAX_URL || raw.includes("?") || raw.includes("#"))
|
|
6841
|
+
return null;
|
|
6842
|
+
let url;
|
|
6843
|
+
try {
|
|
6844
|
+
url = new URL(raw);
|
|
6845
|
+
}
|
|
6846
|
+
catch {
|
|
6847
|
+
return null;
|
|
6848
|
+
}
|
|
6849
|
+
if (url.href !== raw || url.protocol !== "https:" || url.hostname !== PAYPLUG_HOST || url.port || url.username || url.password)
|
|
6850
|
+
return null;
|
|
6851
|
+
const match = ENTRY_PATH.exec(url.pathname);
|
|
6852
|
+
return match ? Object.freeze({ id: match[2], test: match[1] === "test" }) : null;
|
|
6853
|
+
}
|
|
6854
|
+
function isPayplugEntryUrl(raw) {
|
|
6855
|
+
return payplugEntry(raw) !== null;
|
|
6856
|
+
}
|
|
6857
|
+
var PAYPLUG_MERCHANTS = Object.freeze([
|
|
6858
|
+
Object.freeze({ merchant: "Lazartigue", origins: Object.freeze(["https://lazartigue.com"]), payee: null, account: null })
|
|
6859
|
+
]);
|
|
6860
|
+
var ACCOUNT_ID = /^[A-Za-z0-9-]{1,64}$/;
|
|
6861
|
+
function payplugMerchant(checkoutOrigin, merchants = PAYPLUG_MERCHANTS) {
|
|
6862
|
+
if (typeof checkoutOrigin !== "string" || checkoutOrigin.length > MAX_URL || !Array.isArray(merchants))
|
|
6863
|
+
return null;
|
|
6864
|
+
let url;
|
|
6865
|
+
try {
|
|
6866
|
+
url = new URL(checkoutOrigin);
|
|
6867
|
+
}
|
|
6868
|
+
catch {
|
|
6869
|
+
return null;
|
|
6870
|
+
}
|
|
6871
|
+
if (url.protocol !== "https:" || url.origin !== checkoutOrigin || url.port)
|
|
6872
|
+
return null;
|
|
6873
|
+
const found = merchants.filter((row) => !!row && typeof row.merchant === "string" && row.merchant.trim() !== "" && typeof row.payee === "string" && row.payee.trim() !== "" && typeof row.account === "string" && ACCOUNT_ID.test(row.account) && Array.isArray(row.origins) && row.origins.includes(checkoutOrigin));
|
|
6874
|
+
return found.length === 1 ? found[0] : null;
|
|
6875
|
+
}
|
|
6876
|
+
function checkPayplugEntry(body, { url = null, checkoutOrigin = null, merchants = PAYPLUG_MERCHANTS } = {}) {
|
|
6877
|
+
if (body !== void 0 && body !== null && body !== "")
|
|
6878
|
+
return field2("(body)", "not_an_entry");
|
|
6879
|
+
const entry = payplugEntry(url);
|
|
6880
|
+
if (!entry)
|
|
6881
|
+
return field2("(url)", "malformed_field");
|
|
6882
|
+
const seller = payplugMerchant(checkoutOrigin, merchants);
|
|
6883
|
+
if (!seller)
|
|
6884
|
+
return field2("(checkout_origin)", "seller_unreviewed");
|
|
6885
|
+
return { ok: true, pairs: [], gated: false, dedupe: [entry.id], paymentId: entry.id, sandbox: entry.test, seller };
|
|
6886
|
+
}
|
|
6887
|
+
var MAX_PAGE2 = 512 * 1024;
|
|
6888
|
+
var PAYPLUG_REFUSALS = Object.freeze(["payplug_failed", "payplug_expired", "payplug_cancelled"]);
|
|
6889
|
+
var payplug_default = /* @__PURE__ */ registerProcessor({
|
|
6890
|
+
psp: PAYPLUG_PSP,
|
|
6891
|
+
definitions: [
|
|
6892
|
+
{
|
|
6893
|
+
psp: "payplug",
|
|
6894
|
+
// The merchant's redirect to PayPlug's payment page, as the header above reads it: a Document navigation that
|
|
6895
|
+
// carries no card. The cardholder's device repeats it over the end-to-end TLS relay and pays on the page PayPlug
|
|
6896
|
+
// returns to it, and the runtime resolves the paused navigation with the hosted_form notice. Only the entry is
|
|
6897
|
+
// matched (isPayplugEntryUrl): the page's card post and its 3-D Secure steps share the host, and none of them is
|
|
6898
|
+
// the entry. Test and live payments share the host, and the entry's path says which it is. Ships dark: served
|
|
6899
|
+
// only to a client that declares `payplug_hosted_payment_page`, and the backend's gate serves only Agentcard's
|
|
6900
|
+
// own company until a reviewed merchant pays.
|
|
6901
|
+
capability: "payplug_hosted_payment_page",
|
|
6902
|
+
match: "secure\\.payplug\\.com/pay/(?:test/)?[A-Za-z0-9]{22}",
|
|
6903
|
+
hosts: ["^secure\\.payplug\\.com$"],
|
|
6904
|
+
// `encoding` describes the page's own card post, which the device makes as the page does, since the entry has no
|
|
6905
|
+
// body. No captured header is ever replayed.
|
|
6906
|
+
encoding: "form",
|
|
6907
|
+
passthroughHeaders: [],
|
|
6908
|
+
request: { method: "GET", cardIn: "none", response: "html_page" },
|
|
6909
|
+
mode: "hosted_form",
|
|
6910
|
+
hostedForm: {
|
|
6911
|
+
// The card goes into PayPlug's page on the device, never into the entry, which carries no body at all. The
|
|
6912
|
+
// entry's own rules come with this registration (hostedEntry below), so no policy is named here.
|
|
6913
|
+
cardIn: "processor_page",
|
|
6914
|
+
required: [],
|
|
6915
|
+
// The page's card inputs, by the data-payplug role its script reads them by: they carry no name, and the
|
|
6916
|
+
// script posts the card only as its ciphertext, encryptedCard.
|
|
6917
|
+
card: { number: "card_number", expiry: "card_month_year", cvc: "card_cvv" },
|
|
6918
|
+
// The payment's id in the entry's URL names the one payment the merchant created; the entry's rules read it
|
|
6919
|
+
// there (checkPayplugEntry's dedupe), since no form field holds it.
|
|
6920
|
+
dedupe: ["(paymentId)"]
|
|
6921
|
+
}
|
|
6922
|
+
}
|
|
6923
|
+
],
|
|
6924
|
+
// Only the cardholder's device repeats an entry, after a person approves; no reviewed list names payplug.
|
|
6925
|
+
refusedOperations: [PAYPLUG_OPERATION],
|
|
6926
|
+
// Not surveyed: PayPlug tells only the merchant's server the result, and the browser returns whatever it was.
|
|
6927
|
+
settlementReadback: "not_surveyed",
|
|
6928
|
+
exactUrl: isPayplugEntryUrl,
|
|
6929
|
+
hostedEntry: checkPayplugEntry,
|
|
6930
|
+
limitations: [
|
|
6931
|
+
"The paused request is the merchant's redirect to PayPlug's payment page, a GET that carries only the payment's id and no card; the cardholder's device opens that page over the end-to-end TLS relay.",
|
|
6932
|
+
"The redirect names no merchant and no amount, so Agentcard takes one only from the checkout page of a merchant it reviewed, the approval names that merchant and the amount you send, and the cardholder's device pays only a PayPlug page that names that merchant and that amount.",
|
|
6933
|
+
"PayPlug runs 3-D Secure on the card. A challenge ends the payment on the device with nothing charged.",
|
|
6934
|
+
"PayPlug sends the buyer to the merchant's return page whether the payment succeeded or not, so the browser receives a submission notice, not the processor result."
|
|
6935
|
+
]
|
|
6936
|
+
});
|
|
6937
|
+
// src/processors/processout.js
|
|
6938
|
+
var PROCESSOUT_PSP = "processout";
|
|
6939
|
+
var PROCESSOUT_OPERATION = "processout.card_request";
|
|
6940
|
+
var URL_LIMIT15 = 512;
|
|
6941
|
+
var BODY_LIMIT40 = 4096;
|
|
6942
|
+
var CARD_URL2 = /^https:\/\/api\.processout\.com\/cards\?legacyrequest=true&project_id=((?:test-)?proj_[A-Za-z0-9]{16,64})&x-Content-Type=application\/json&x-API-Version=1\.3\.0\.0&x-Authorization=Basic%20([A-Za-z0-9+/]{4,256}={0,2})$/;
|
|
6943
|
+
var PAGE_KEYS2 = /* @__PURE__ */ Object.freeze(["name", "contact", "preferred_scheme"]);
|
|
6944
|
+
var CONTACT_KEYS = /* @__PURE__ */ Object.freeze(["address1", "address2", "city", "state", "country_code", "zip"]);
|
|
6945
|
+
var DEVICE_KEYS4 = /* @__PURE__ */ Object.freeze([
|
|
6946
|
+
"request_origin",
|
|
6947
|
+
"app_color_depth",
|
|
6948
|
+
"app_language",
|
|
6949
|
+
"app_screen_height",
|
|
6950
|
+
"app_screen_width",
|
|
6951
|
+
"app_timezone_offset",
|
|
6952
|
+
"app_java_enabled"
|
|
6953
|
+
]);
|
|
6954
|
+
var PROCESSOUT_CARD_KEYS = /* @__PURE__ */ Object.freeze(["number", "exp_month", "exp_year", "cvc2"]);
|
|
6955
|
+
var BODY_KEYS3 = /* @__PURE__ */ new Set([...PAGE_KEYS2, "device", ...DEVICE_KEYS4, ...PROCESSOUT_CARD_KEYS]);
|
|
6956
|
+
var NUMBER8 = /^[0-9]{12,19}$/;
|
|
6957
|
+
var MONTH21 = /^(?:[1-9]|1[0-2])$/;
|
|
6958
|
+
var YEAR22 = /^20[0-9]{2}$/;
|
|
6959
|
+
var CODE8 = /^[0-9]{3,4}$/;
|
|
6960
|
+
var TEXT_LIMIT14 = 256;
|
|
6961
|
+
var SCHEME = /^[A-Za-z][A-Za-z0-9 _-]{0,31}$/;
|
|
6962
|
+
var LANGUAGE5 = /^[A-Za-z]{1,8}(?:-[A-Za-z0-9]{1,8}){0,4}$/;
|
|
6963
|
+
var PAN_LIKE7 = /(?:[0-9][^0-9A-Za-z]*){12,}/;
|
|
6964
|
+
var record35 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
6965
|
+
var own16 = (value, key) => Object.prototype.hasOwnProperty.call(value, key);
|
|
6966
|
+
var refuse41 = (code) => Object.freeze({ verdict: "refuse", code });
|
|
6967
|
+
var CARD40 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
|
|
6968
|
+
var BASE646 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
6969
|
+
function base64Of(text9) {
|
|
6970
|
+
let out = "";
|
|
6971
|
+
for (let at = 0; at < text9.length; at += 3) {
|
|
6972
|
+
const a = text9.charCodeAt(at);
|
|
6973
|
+
const b = at + 1 < text9.length ? text9.charCodeAt(at + 1) : NaN;
|
|
6974
|
+
const c = at + 2 < text9.length ? text9.charCodeAt(at + 2) : NaN;
|
|
6975
|
+
out += BASE646[a >> 2] + BASE646[(a & 3) << 4 | (Number.isNaN(b) ? 0 : b >> 4)] + (Number.isNaN(b) ? "=" : BASE646[(b & 15) << 2 | (Number.isNaN(c) ? 0 : c >> 6)]) + (Number.isNaN(c) ? "=" : BASE646[c & 63]);
|
|
6976
|
+
}
|
|
6977
|
+
return out;
|
|
6978
|
+
}
|
|
6979
|
+
var basicOf = (projectId) => base64Of(`${projectId}:`);
|
|
6980
|
+
function luhn10(digits3) {
|
|
6981
|
+
let sum = 0;
|
|
6982
|
+
for (let at = 0; at < digits3.length; at += 1) {
|
|
6983
|
+
let digit = Number(digits3[digits3.length - 1 - at]);
|
|
6984
|
+
if (at % 2 === 1) {
|
|
6985
|
+
digit *= 2;
|
|
6986
|
+
if (digit > 9)
|
|
6987
|
+
digit -= 9;
|
|
6988
|
+
}
|
|
6989
|
+
sum += digit;
|
|
6990
|
+
}
|
|
6991
|
+
return sum % 10 === 0;
|
|
6992
|
+
}
|
|
6993
|
+
function processoutCardTarget(url) {
|
|
6994
|
+
if (typeof url !== "string" || url.length > URL_LIMIT15)
|
|
6995
|
+
return null;
|
|
6996
|
+
const match = CARD_URL2.exec(url);
|
|
6997
|
+
if (!match || match[2] !== basicOf(match[1]))
|
|
6998
|
+
return null;
|
|
6999
|
+
return Object.freeze({ projectId: match[1], environment: match[1].startsWith("test-") ? "sandbox" : "production" });
|
|
7000
|
+
}
|
|
7001
|
+
function isProcessoutCardUrl(url) {
|
|
7002
|
+
return processoutCardTarget(url) !== null;
|
|
7003
|
+
}
|
|
7004
|
+
function readBody24(body) {
|
|
7005
|
+
if (typeof body !== "string" || body === "" || body.length > BODY_LIMIT40)
|
|
7006
|
+
return null;
|
|
7007
|
+
try {
|
|
7008
|
+
const value = JSON.parse(body);
|
|
7009
|
+
return record35(value) && JSON.stringify(value) === body ? value : null;
|
|
7010
|
+
}
|
|
7011
|
+
catch {
|
|
7012
|
+
return null;
|
|
7013
|
+
}
|
|
7014
|
+
}
|
|
7015
|
+
var pageText2 = (value) => value === null || typeof value === "string" && value.length <= TEXT_LIMIT14 && !PAN_LIKE7.test(value);
|
|
7016
|
+
var DEVICE_RULES = /* @__PURE__ */ Object.freeze({
|
|
7017
|
+
request_origin: (value) => value === "web",
|
|
7018
|
+
app_color_depth: (value) => Number.isSafeInteger(value) && value >= 1 && value <= 64,
|
|
7019
|
+
app_language: (value) => typeof value === "string" && value.length <= 64 && LANGUAGE5.test(value),
|
|
7020
|
+
app_screen_height: (value) => Number.isSafeInteger(value) && value >= 1 && value <= 1e5,
|
|
7021
|
+
app_screen_width: (value) => Number.isSafeInteger(value) && value >= 1 && value <= 1e5,
|
|
7022
|
+
app_timezone_offset: (value) => Number.isSafeInteger(value) && value >= -1440 && value <= 1440,
|
|
7023
|
+
app_java_enabled: (value) => typeof value === "boolean"
|
|
7024
|
+
});
|
|
7025
|
+
function soundDevice3(value) {
|
|
7026
|
+
const device = value.device;
|
|
7027
|
+
if (!record35(device) || !own16(device, "request_origin") || !own16(device, "app_timezone_offset"))
|
|
7028
|
+
return false;
|
|
7029
|
+
return DEVICE_KEYS4.every((key) => own16(device, key) ? DEVICE_RULES[key](device[key]) && own16(value, key) && value[key] === device[key] : !own16(value, key)) && Object.keys(device).every((key) => DEVICE_KEYS4.includes(key));
|
|
7030
|
+
}
|
|
7031
|
+
function soundPageData(value) {
|
|
7032
|
+
if (own16(value, "name") && !pageText2(value.name))
|
|
7033
|
+
return false;
|
|
7034
|
+
if (own16(value, "preferred_scheme") && !(value.preferred_scheme === null || typeof value.preferred_scheme === "string" && SCHEME.test(value.preferred_scheme)))
|
|
7035
|
+
return false;
|
|
7036
|
+
const contact = value.contact;
|
|
7037
|
+
return record35(contact) && Object.keys(contact).every((key) => CONTACT_KEYS.includes(key) && pageText2(contact[key]));
|
|
7038
|
+
}
|
|
7039
|
+
function processoutBodyVerdict(body, url) {
|
|
7040
|
+
if (url !== void 0 && processoutCardTarget(url) === null)
|
|
7041
|
+
return refuse41("processout_url_refused");
|
|
7042
|
+
const value = readBody24(body);
|
|
7043
|
+
if (value === null || !Object.keys(value).every((key) => BODY_KEYS3.has(key)))
|
|
7044
|
+
return refuse41("processout_body_unsupported");
|
|
7045
|
+
if (!PROCESSOUT_CARD_KEYS.every((key) => typeof value[key] === "string"))
|
|
7046
|
+
return refuse41("processout_body_unsupported");
|
|
7047
|
+
if (!NUMBER8.test(value.number) || !luhn10(value.number) || !MONTH21.test(value.exp_month) || !YEAR22.test(value.exp_year) || !CODE8.test(value.cvc2))
|
|
7048
|
+
return refuse41("processout_body_unsupported");
|
|
7049
|
+
if (!soundPageData(value) || !soundDevice3(value))
|
|
7050
|
+
return refuse41("processout_body_unsupported");
|
|
7051
|
+
return CARD40;
|
|
7052
|
+
}
|
|
7053
|
+
var processout_default = /* @__PURE__ */ registerProcessor({
|
|
7054
|
+
psp: PROCESSOUT_PSP,
|
|
7055
|
+
definitions: [
|
|
7056
|
+
{
|
|
7057
|
+
psp: "processout",
|
|
7058
|
+
// ProcessOut.js's card request, as the header above reads it. One host serves every project, live and sandbox
|
|
7059
|
+
// alike, so no sandbox host is marked: the project id names the environment, and the device sends a sandbox
|
|
7060
|
+
// project only ProcessOut's documented test cards (processoutDeviceRefusal). The page gives up 20 seconds after
|
|
7061
|
+
// its tokenize message, so the lane is prepared only (preparationRequired). The match reads the host and the path,
|
|
7062
|
+
// and ends where the path does, as Pin Payments' does: a card's own record under /cards/, where the code refresh
|
|
7063
|
+
// goes, is never paused. The exact-URL rule below holds the query, the project id and its Basic credential among it.
|
|
7064
|
+
// Ships dark: served only to a client that declares `processout_card_token`, and gated off for every org until
|
|
7065
|
+
// the backend's gate names one.
|
|
7066
|
+
capability: "processout_card_token",
|
|
7067
|
+
match: "api\\.processout\\.com/cards(?![\\w/.%-])",
|
|
7068
|
+
hosts: ["^api\\.processout\\.com$"],
|
|
7069
|
+
preparationRequired: true,
|
|
7070
|
+
encoding: "json",
|
|
7071
|
+
// ProcessOut.js's own headers: the project's Basic credential and the API version. Origin, Referer and cookies
|
|
7072
|
+
// never ride.
|
|
7073
|
+
passthroughHeaders: ["^authorization$", "^api-version$"],
|
|
7074
|
+
jsonCardFields: [["number"]]
|
|
7075
|
+
}
|
|
7076
|
+
],
|
|
7077
|
+
// Only the cardholder's device sends a card, after a person approves; no reviewed list names processout.
|
|
7078
|
+
refusedOperations: [PROCESSOUT_OPERATION],
|
|
7079
|
+
// Not surveyed: the card request mints a token and moves no money; the store's server charges it under its own
|
|
7080
|
+
// secret key, which Agentcard never holds.
|
|
7081
|
+
settlementReadback: "not_surveyed",
|
|
7082
|
+
exactUrl: isProcessoutCardUrl,
|
|
7083
|
+
bodyGate: (url, body) => processoutBodyVerdict(body, url)
|
|
7084
|
+
});
|
|
7085
|
+
// src/processors/usaepay.js
|
|
7086
|
+
var USAEPAY_PSP = "usaepay";
|
|
7087
|
+
var USAEPAY_OPERATION = "usaepay.card_request";
|
|
7088
|
+
var USAEPAY_HOSTS = /* @__PURE__ */ Object.freeze({
|
|
7089
|
+
"www.usaepay.com": "production",
|
|
7090
|
+
"secure.usaepay.com": "production",
|
|
7091
|
+
"sandbox.usaepay.com": "sandbox"
|
|
7092
|
+
});
|
|
7093
|
+
var USAEPAY_PAYMENT_KEYS_PATH = "/api/v2/pub/payment_keys";
|
|
7094
|
+
var BODY_LIMIT41 = 512;
|
|
7095
|
+
var URL_LIMIT16 = 256;
|
|
7096
|
+
var CARD_NUMBER21 = /^[0-9]{13,19}$/;
|
|
7097
|
+
var EXPIRATION2 = /^(?:0[1-9]|1[0-2])[0-9]{2}$/;
|
|
7098
|
+
var SECURITY_CODE25 = /^(?:[0-9]{3,4})?$/;
|
|
7099
|
+
var record36 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
7100
|
+
var own17 = (value, key) => Object.prototype.hasOwnProperty.call(value, key);
|
|
7101
|
+
var refuse42 = (code) => Object.freeze({ verdict: "refuse", code });
|
|
7102
|
+
var CARD41 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
|
|
7103
|
+
function usaepayPaymentKeysUrl(url) {
|
|
7104
|
+
if (typeof url !== "string" || url.length > URL_LIMIT16 || url.includes("?") || url.includes("#"))
|
|
7105
|
+
return null;
|
|
7106
|
+
let parsed;
|
|
7107
|
+
try {
|
|
7108
|
+
parsed = new URL(url);
|
|
7109
|
+
}
|
|
7110
|
+
catch {
|
|
7111
|
+
return null;
|
|
7112
|
+
}
|
|
7113
|
+
if (parsed.href !== url || parsed.protocol !== "https:" || parsed.port || parsed.username || parsed.password || !own17(USAEPAY_HOSTS, parsed.hostname) || parsed.pathname !== USAEPAY_PAYMENT_KEYS_PATH)
|
|
7114
|
+
return null;
|
|
7115
|
+
return Object.freeze({ host: parsed.hostname, environment: USAEPAY_HOSTS[parsed.hostname] });
|
|
7116
|
+
}
|
|
7117
|
+
var isUsaepayPaymentKeysUrl = (url) => usaepayPaymentKeysUrl(url) !== null;
|
|
7118
|
+
function luhn11(digits3) {
|
|
7119
|
+
let sum = 0;
|
|
7120
|
+
for (let at = digits3.length - 1, double = false; at >= 0; at -= 1, double = !double) {
|
|
7121
|
+
let digit = digits3.charCodeAt(at) - 48;
|
|
7122
|
+
if (double)
|
|
7123
|
+
digit = digit * 2 > 9 ? digit * 2 - 9 : digit * 2;
|
|
7124
|
+
sum += digit;
|
|
7125
|
+
}
|
|
7126
|
+
return sum % 10 === 0;
|
|
7127
|
+
}
|
|
7128
|
+
function readBody25(body) {
|
|
7129
|
+
if (typeof body !== "string" || body === "" || body.length > BODY_LIMIT41)
|
|
7130
|
+
return null;
|
|
7131
|
+
try {
|
|
7132
|
+
const value = JSON.parse(body);
|
|
7133
|
+
return record36(value) && JSON.stringify(value) === body ? value : null;
|
|
7134
|
+
}
|
|
7135
|
+
catch {
|
|
7136
|
+
return null;
|
|
7137
|
+
}
|
|
7138
|
+
}
|
|
7139
|
+
function usaepayBodyVerdict(body) {
|
|
7140
|
+
const value = readBody25(body);
|
|
7141
|
+
const card = value === null ? null : value.creditcard;
|
|
7142
|
+
if (value === null || Object.keys(value).join() !== "creditcard" || !record36(card) || Object.keys(card).join() !== "number,expiration,cvc" || typeof card.number !== "string" || !CARD_NUMBER21.test(card.number) || !luhn11(card.number) || typeof card.expiration !== "string" || !EXPIRATION2.test(card.expiration) || typeof card.cvc !== "string" || !SECURITY_CODE25.test(card.cvc))
|
|
7143
|
+
return refuse42("usaepay_body_unsupported");
|
|
7144
|
+
return CARD41;
|
|
7145
|
+
}
|
|
7146
|
+
var usaepay_default = /* @__PURE__ */ registerProcessor({
|
|
7147
|
+
psp: USAEPAY_PSP,
|
|
7148
|
+
definitions: [
|
|
7149
|
+
{
|
|
7150
|
+
psp: "usaepay",
|
|
7151
|
+
// The frame's card request, as the header above reads it. sandbox.usaepay.com is USAePay's sandbox, pinned to test
|
|
7152
|
+
// rows, which send only USAePay's documented test cards (hostEnvironmentPinned, device-replay.js S7).
|
|
7153
|
+
// Ships dark: served only to a client that declares `usaepay_payment_key`, and only for a company the backend's
|
|
7154
|
+
// processor gate turns USAePay on for. `(?![\w/.%-])` ends the path for a consumer that tests `match` unanchored.
|
|
7155
|
+
capability: "usaepay_payment_key",
|
|
7156
|
+
match: "(?:www|secure|sandbox)\\.usaepay\\.com/api/v2/pub/payment_keys(?![\\w/.%-])",
|
|
7157
|
+
hosts: ["^www\\.usaepay\\.com$", "^secure\\.usaepay\\.com$", "^sandbox\\.usaepay\\.com$"],
|
|
7158
|
+
sandboxHosts: ["^sandbox\\.usaepay\\.com$"],
|
|
7159
|
+
hostEnvironmentPinned: true,
|
|
7160
|
+
encoding: "json",
|
|
7161
|
+
// The frame's Authorization, which carries the merchant's public key. Origin, Referer and cookies never ride.
|
|
7162
|
+
passthroughHeaders: ["^authorization$"],
|
|
7163
|
+
jsonCardFields: [["creditcard", "number"]]
|
|
7164
|
+
}
|
|
7165
|
+
],
|
|
7166
|
+
// Only the cardholder's device sends this card, after a person approves; no reviewed list names usaepay.
|
|
7167
|
+
refusedOperations: [USAEPAY_OPERATION],
|
|
7168
|
+
// The public key mints a payment key and reads nothing: the merchant's server runs the sale with its private key.
|
|
7169
|
+
settlementReadback: {
|
|
7170
|
+
answer: "none",
|
|
7171
|
+
reason: "tokenization_credential_cannot_read_charges",
|
|
7172
|
+
note: "The tokenization credential cannot read a charge; the shop charges the token later with its own credentials.",
|
|
7173
|
+
source: "https://help.usaepay.info/developer/payjs-v2/ , https://help.usaepay.info/api/rest/"
|
|
7174
|
+
},
|
|
7175
|
+
exactUrl: isUsaepayPaymentKeysUrl,
|
|
7176
|
+
bodyGate: (url, body) => url !== void 0 && !isUsaepayPaymentKeysUrl(url) ? refuse42("usaepay_url_refused") : usaepayBodyVerdict(body)
|
|
7177
|
+
// No amount reader: the request names none, so the agent's pair is the figure the cardholder approves.
|
|
7178
|
+
});
|
|
7179
|
+
// src/processors/vtex_payments.js
|
|
7180
|
+
var VTEX_PAYMENTS_PSP = "vtex_payments";
|
|
7181
|
+
var VTEX_PAYMENTS_OPERATION = "vtex_payments.card_request";
|
|
7182
|
+
var VTEX_PAYMENTS_FALLBACK_HOST = "api.vtexvault.com";
|
|
7183
|
+
var VTEX_PAYMENTS_LINE_KEYS = /* @__PURE__ */ Object.freeze([
|
|
7184
|
+
"currencyCode",
|
|
7185
|
+
"paymentSystem",
|
|
7186
|
+
"accountId",
|
|
7187
|
+
"value",
|
|
7188
|
+
"referenceValue",
|
|
7189
|
+
"installments",
|
|
7190
|
+
"installmentsInterestRate",
|
|
7191
|
+
"installmentsValue",
|
|
7192
|
+
"groupName",
|
|
7193
|
+
"fields",
|
|
7194
|
+
"transaction",
|
|
7195
|
+
"id"
|
|
7196
|
+
]);
|
|
7197
|
+
var VTEX_PAYMENTS_FIELD_KEYS = /* @__PURE__ */ Object.freeze([
|
|
7198
|
+
"address",
|
|
7199
|
+
"accountId",
|
|
7200
|
+
"validationCode",
|
|
7201
|
+
"metadata",
|
|
7202
|
+
"document",
|
|
7203
|
+
"holderName",
|
|
7204
|
+
"cardNumber",
|
|
7205
|
+
"dueDate",
|
|
7206
|
+
"deviceFingerprint",
|
|
7207
|
+
"addressId"
|
|
7208
|
+
]);
|
|
7209
|
+
var VTEX_PAYMENTS_ADDRESS_KEYS = /* @__PURE__ */ Object.freeze([
|
|
7210
|
+
"street",
|
|
7211
|
+
"complement",
|
|
7212
|
+
"number",
|
|
7213
|
+
"city",
|
|
7214
|
+
"reference",
|
|
7215
|
+
"addressType",
|
|
7216
|
+
"neighborhood",
|
|
7217
|
+
"addressId",
|
|
7218
|
+
"state",
|
|
7219
|
+
"country",
|
|
7220
|
+
"postalCode"
|
|
7221
|
+
]);
|
|
7222
|
+
var VTEX_PAYMENTS_NETWORKS = /* @__PURE__ */ Object.freeze({ 1: "amex", 2: "visa", 4: "mastercard", 5: "discover" });
|
|
7223
|
+
var VTEX_PAYMENTS_MERCHANT_PINS = /* @__PURE__ */ Object.freeze([
|
|
7224
|
+
Object.freeze({ account: "alssports", origin: "https://www.als.com", merchant: "Al's Sporting Goods", currency: "USD" }),
|
|
7225
|
+
Object.freeze({ account: "roadrunnersports", origin: "https://www.roadrunnersports.com", merchant: "Road Runner Sports", currency: "USD" })
|
|
7226
|
+
]);
|
|
7227
|
+
var BODY_LIMIT42 = 16384;
|
|
7228
|
+
var ACCOUNT_HOST = /^([a-z0-9]{1,63})\.vtexvault\.com$/;
|
|
7229
|
+
var PATH = /^\/api\/payments\/transactions\/([0-9A-Fa-f]{32})\/payments$/;
|
|
7230
|
+
var ORDER_GROUP = /^[0-9]{6,24}$/;
|
|
7231
|
+
var BASE647 = /^[A-Za-z0-9+/]{4,1020}={0,2}$/;
|
|
7232
|
+
var CARD_NUMBER22 = /^[0-9]{12,19}$/;
|
|
7233
|
+
var SECURITY_CODE26 = /^[0-9]{3,4}$/;
|
|
7234
|
+
var DUE_DATE = /^(?:0[1-9]|1[0-2])\/[0-9]{2}$/;
|
|
7235
|
+
var CURRENCY6 = /^[A-Z]{3}$/;
|
|
7236
|
+
var TRANSACTION_ID = /^[0-9A-Fa-f]{32}$/;
|
|
7237
|
+
var MERCHANT_NAME = /^[A-Za-z0-9_.-]{1,64}$/;
|
|
7238
|
+
var SHORT_ID = /^[A-Za-z0-9_-]{1,64}$/;
|
|
7239
|
+
var FINGERPRINT4 = /^[A-Za-z0-9_.:=+/-]{1,256}$/;
|
|
7240
|
+
var TEXT4 = /^[^\u0000-\u001f\u007f]{1,200}$/;
|
|
7241
|
+
var CARD_DIGITS2 = /[0-9]{12,}/;
|
|
7242
|
+
var DEVICE_INFO_KEYS = Object.freeze(["sw", "sh", "cd", "tz", "lang", "java", "sourceApplication"]);
|
|
7243
|
+
var record37 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
7244
|
+
var own18 = (value, key) => Object.prototype.hasOwnProperty.call(value, key);
|
|
7245
|
+
var refuse43 = (code) => Object.freeze({ verdict: "refuse", code });
|
|
7246
|
+
var CARD42 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
|
|
7247
|
+
var inOrder8 = (value, keys) => {
|
|
7248
|
+
let at = 0;
|
|
7249
|
+
for (const name of Object.keys(value)) {
|
|
7250
|
+
while (at < keys.length && keys[at] !== name)
|
|
7251
|
+
at += 1;
|
|
7252
|
+
if (at === keys.length)
|
|
7253
|
+
return false;
|
|
7254
|
+
at += 1;
|
|
7255
|
+
}
|
|
7256
|
+
return true;
|
|
7257
|
+
};
|
|
7258
|
+
var cardDigits2 = (text9) => CARD_DIGITS2.test(text9.replace(/[^0-9A-Za-z]/g, ""));
|
|
7259
|
+
var plainText8 = (value) => typeof value === "string" && TEXT4.test(value) && !cardDigits2(value);
|
|
7260
|
+
var count = (value) => Number.isSafeInteger(value) && value >= 0;
|
|
7261
|
+
var BASE64_ALPHABET2 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
7262
|
+
function base64Text2(input) {
|
|
7263
|
+
if (input.length % 4 !== 0)
|
|
7264
|
+
return null;
|
|
7265
|
+
const stripped = input.replace(/={1,2}$/, "");
|
|
7266
|
+
let out = "";
|
|
7267
|
+
let bits = 0;
|
|
7268
|
+
let value = 0;
|
|
7269
|
+
for (const character of stripped) {
|
|
7270
|
+
const sextet = BASE64_ALPHABET2.indexOf(character);
|
|
7271
|
+
if (sextet < 0)
|
|
7272
|
+
return null;
|
|
7273
|
+
value = value << 6 | sextet;
|
|
7274
|
+
bits += 6;
|
|
7275
|
+
if (bits >= 8) {
|
|
7276
|
+
bits -= 8;
|
|
7277
|
+
out += String.fromCharCode(value >> bits & 255);
|
|
7278
|
+
value &= (1 << bits) - 1;
|
|
7279
|
+
}
|
|
7280
|
+
}
|
|
7281
|
+
return out;
|
|
7282
|
+
}
|
|
7283
|
+
function deviceInfoSound(text9) {
|
|
7284
|
+
if (typeof text9 !== "string" || !BASE647.test(text9))
|
|
7285
|
+
return false;
|
|
7286
|
+
const decoded = base64Text2(text9);
|
|
7287
|
+
if (decoded === null)
|
|
7288
|
+
return false;
|
|
7289
|
+
let info;
|
|
7290
|
+
try {
|
|
7291
|
+
info = JSON.parse(decoded);
|
|
7292
|
+
}
|
|
7293
|
+
catch {
|
|
7294
|
+
return false;
|
|
7295
|
+
}
|
|
7296
|
+
if (!record37(info) || !Object.keys(info).every((key) => DEVICE_INFO_KEYS.includes(key)))
|
|
7297
|
+
return false;
|
|
7298
|
+
for (const key of ["sw", "sh", "cd"])
|
|
7299
|
+
if (own18(info, key) && !(count(info[key]) && info[key] <= 1e5))
|
|
7300
|
+
return false;
|
|
7301
|
+
if (own18(info, "tz") && !(Number.isSafeInteger(info.tz) && Math.abs(info.tz) <= 1440))
|
|
7302
|
+
return false;
|
|
7303
|
+
if (own18(info, "lang") && !(typeof info.lang === "string" && /^[A-Za-z]{0,8}$/.test(info.lang)))
|
|
7304
|
+
return false;
|
|
7305
|
+
if (own18(info, "java") && typeof info.java !== "boolean")
|
|
7306
|
+
return false;
|
|
7307
|
+
return !own18(info, "sourceApplication") || typeof info.sourceApplication === "string" && /^[A-Za-z0-9_.-]{1,32}$/.test(info.sourceApplication);
|
|
7308
|
+
}
|
|
7309
|
+
function vtexPaymentsCardTarget(url) {
|
|
7310
|
+
if (typeof url !== "string" || url.length > 8192)
|
|
7311
|
+
return null;
|
|
7312
|
+
let parsed;
|
|
7313
|
+
try {
|
|
7314
|
+
parsed = new URL(url);
|
|
7315
|
+
}
|
|
7316
|
+
catch {
|
|
7317
|
+
return null;
|
|
7318
|
+
}
|
|
7319
|
+
if (parsed.href !== url || parsed.protocol !== "https:" || parsed.port || parsed.username || parsed.password || parsed.hash)
|
|
7320
|
+
return null;
|
|
7321
|
+
const path = PATH.exec(parsed.pathname);
|
|
7322
|
+
const host = ACCOUNT_HOST.exec(parsed.hostname);
|
|
7323
|
+
if (!path || !host)
|
|
7324
|
+
return null;
|
|
7325
|
+
const fallback = parsed.hostname === VTEX_PAYMENTS_FALLBACK_HOST;
|
|
7326
|
+
const names = [...parsed.searchParams.keys()];
|
|
7327
|
+
const expected = ["orderId", "deviceInfo", ...parsed.searchParams.has("callbackUrl") ? ["callbackUrl"] : [], ...fallback ? ["an"] : []];
|
|
7328
|
+
if (names.length !== expected.length || names.some((name, i) => name !== expected[i]))
|
|
7329
|
+
return null;
|
|
7330
|
+
const orderId = parsed.searchParams.get("orderId");
|
|
7331
|
+
if (!ORDER_GROUP.test(orderId) || !deviceInfoSound(parsed.searchParams.get("deviceInfo")))
|
|
7332
|
+
return null;
|
|
7333
|
+
if (parsed.searchParams.has("callbackUrl")) {
|
|
7334
|
+
let callback;
|
|
7335
|
+
try {
|
|
7336
|
+
callback = new URL(parsed.searchParams.get("callbackUrl"));
|
|
7337
|
+
}
|
|
7338
|
+
catch {
|
|
7339
|
+
return null;
|
|
7340
|
+
}
|
|
7341
|
+
if (callback.protocol !== "https:" || callback.username || callback.password || callback.searchParams.get("step") !== "payment" || callback.searchParams.get("og") !== orderId)
|
|
7342
|
+
return null;
|
|
7343
|
+
}
|
|
7344
|
+
const account = fallback ? parsed.searchParams.get("an") : host[1];
|
|
7345
|
+
if (!/^[a-z0-9]{1,63}$/.test(account) || account === "api")
|
|
7346
|
+
return null;
|
|
7347
|
+
return Object.freeze({ account, transactionId: path[1], orderId, fallback });
|
|
7348
|
+
}
|
|
7349
|
+
function isVtexPaymentsCardUrl(url) {
|
|
7350
|
+
const target = vtexPaymentsCardTarget(url);
|
|
7351
|
+
return target !== null && !target.fallback;
|
|
7352
|
+
}
|
|
7353
|
+
function readBody26(body) {
|
|
7354
|
+
if (typeof body !== "string" || body === "" || body.length > BODY_LIMIT42)
|
|
7355
|
+
return null;
|
|
7356
|
+
let value;
|
|
7357
|
+
try {
|
|
7358
|
+
value = JSON.parse(body);
|
|
7359
|
+
if (!Array.isArray(value) || JSON.stringify(value) !== body)
|
|
7360
|
+
return null;
|
|
7361
|
+
}
|
|
7362
|
+
catch {
|
|
7363
|
+
return null;
|
|
7364
|
+
}
|
|
7365
|
+
return value;
|
|
7366
|
+
}
|
|
7367
|
+
function cardLine(line) {
|
|
7368
|
+
if (!record37(line))
|
|
7369
|
+
return false;
|
|
7370
|
+
const fields = record37(line.fields) ? line.fields : {};
|
|
7371
|
+
return line.groupName === "creditCardPaymentGroup" || line.groupName === "debitCardPaymentGroup" || own18(line, "accountId") || own18(fields, "accountId") || own18(fields, "cardNumber") || own18(fields, "validationCode") || own18(fields, "dueDate");
|
|
7372
|
+
}
|
|
7373
|
+
function addressSound(address2) {
|
|
7374
|
+
if (!record37(address2) || !inOrder8(address2, VTEX_PAYMENTS_ADDRESS_KEYS))
|
|
7375
|
+
return false;
|
|
7376
|
+
for (const [key, value] of Object.entries(address2)) {
|
|
7377
|
+
if (key === "addressType") {
|
|
7378
|
+
if (value !== "billing")
|
|
7379
|
+
return false;
|
|
7380
|
+
continue;
|
|
7381
|
+
}
|
|
7382
|
+
if (key === "addressId") {
|
|
7383
|
+
if (!(typeof value === "string" && SHORT_ID.test(value)))
|
|
7384
|
+
return false;
|
|
7385
|
+
continue;
|
|
7386
|
+
}
|
|
7387
|
+
if (value === null && (key === "complement" || key === "reference"))
|
|
7388
|
+
continue;
|
|
7389
|
+
if (!(value === "" || plainText8(value)))
|
|
7390
|
+
return false;
|
|
7391
|
+
}
|
|
7392
|
+
return true;
|
|
7393
|
+
}
|
|
7394
|
+
function fieldsSound(fields) {
|
|
7395
|
+
if (!record37(fields) || !inOrder8(fields, VTEX_PAYMENTS_FIELD_KEYS) || own18(fields, "metadata"))
|
|
7396
|
+
return false;
|
|
7397
|
+
if (!(typeof fields.cardNumber === "string" && CARD_NUMBER22.test(fields.cardNumber)))
|
|
7398
|
+
return false;
|
|
7399
|
+
if (!(typeof fields.validationCode === "string" && SECURITY_CODE26.test(fields.validationCode)))
|
|
7400
|
+
return false;
|
|
7401
|
+
if (!(typeof fields.dueDate === "string" && DUE_DATE.test(fields.dueDate)))
|
|
7402
|
+
return false;
|
|
7403
|
+
if (!plainText8(fields.holderName))
|
|
7404
|
+
return false;
|
|
7405
|
+
if (own18(fields, "document") && !(fields.document === "" || plainText8(fields.document) && fields.document.length <= 32))
|
|
7406
|
+
return false;
|
|
7407
|
+
if (own18(fields, "address") && !addressSound(fields.address))
|
|
7408
|
+
return false;
|
|
7409
|
+
if (own18(fields, "deviceFingerprint") && !(typeof fields.deviceFingerprint === "string" && FINGERPRINT4.test(fields.deviceFingerprint)))
|
|
7410
|
+
return false;
|
|
7411
|
+
return !own18(fields, "addressId") || typeof fields.addressId === "string" && SHORT_ID.test(fields.addressId);
|
|
7412
|
+
}
|
|
7413
|
+
function vtexPaymentsBodyVerdict(body, target) {
|
|
7414
|
+
const lines = readBody26(body);
|
|
7415
|
+
if (lines === null || lines.length === 0 || !lines.every(record37))
|
|
7416
|
+
return refuse43("vtex_payments_body_unsupported");
|
|
7417
|
+
const cards = lines.filter(cardLine);
|
|
7418
|
+
if (cards.some((line2) => own18(line2, "accountId") || own18(line2.fields ?? {}, "accountId")))
|
|
7419
|
+
return refuse43("vtex_payments_saved_card");
|
|
7420
|
+
if (cards.length === 0)
|
|
7421
|
+
return refuse43("vtex_payments_body_unsupported");
|
|
7422
|
+
if (lines.length !== 1 || own18(lines[0], "id"))
|
|
7423
|
+
return refuse43("vtex_payments_split_payment");
|
|
7424
|
+
const line = lines[0];
|
|
7425
|
+
if (!inOrder8(line, VTEX_PAYMENTS_LINE_KEYS) || line.groupName !== "creditCardPaymentGroup")
|
|
7426
|
+
return refuse43("vtex_payments_body_unsupported");
|
|
7427
|
+
if (!(typeof line.currencyCode === "string" && CURRENCY6.test(line.currencyCode)) || !own18(VTEX_PAYMENTS_NETWORKS, line.paymentSystem) || !Number.isSafeInteger(line.paymentSystem) || !(count(line.value) && line.value > 0))
|
|
7428
|
+
return refuse43("vtex_payments_body_unsupported");
|
|
7429
|
+
if (line.installments !== 1 || line.referenceValue !== line.value || own18(line, "installmentsInterestRate") && line.installmentsInterestRate !== 0 || own18(line, "installmentsValue") && line.installmentsValue !== line.value)
|
|
7430
|
+
return refuse43("vtex_payments_installments");
|
|
7431
|
+
const transaction = line.transaction;
|
|
7432
|
+
if (!record37(transaction) || Object.keys(transaction).join() !== "id,merchantName" || !(typeof transaction.id === "string" && TRANSACTION_ID.test(transaction.id)) || !(typeof transaction.merchantName === "string" && MERCHANT_NAME.test(transaction.merchantName)))
|
|
7433
|
+
return refuse43("vtex_payments_body_unsupported");
|
|
7434
|
+
if (target && transaction.id.toUpperCase() !== target.transactionId.toUpperCase())
|
|
7435
|
+
return refuse43("vtex_payments_split_payment");
|
|
7436
|
+
return fieldsSound(line.fields) ? CARD42 : refuse43("vtex_payments_body_unsupported");
|
|
7437
|
+
}
|
|
7438
|
+
function vtexPaymentsAmount(body) {
|
|
7439
|
+
if (vtexPaymentsBodyVerdict(body).verdict !== "card")
|
|
7440
|
+
return null;
|
|
7441
|
+
const [line] = JSON.parse(body);
|
|
7442
|
+
return { amountCents: line.value, currency: line.currencyCode.toLowerCase() };
|
|
7443
|
+
}
|
|
7444
|
+
var NETWORK_OF = Object.freeze({
|
|
7445
|
+
visa: (number) => /^4[0-9]{12}(?:[0-9]{3}){0,2}$/.test(number),
|
|
7446
|
+
mastercard: (number) => /^(?: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})$/.test(number),
|
|
7447
|
+
amex: (number) => /^3[47][0-9]{13}$/.test(number),
|
|
7448
|
+
discover: (number) => /^(?:6011[0-9]{12}|64[4-9][0-9]{13}|65[0-9]{14})$/.test(number)
|
|
7449
|
+
});
|
|
7450
|
+
var NETWORK_NAME = Object.freeze({ visa: "Visa", mastercard: "Mastercard", amex: "American Express", discover: "Discover" });
|
|
7451
|
+
var vtex_payments_default = /* @__PURE__ */ registerProcessor({
|
|
7452
|
+
psp: VTEX_PAYMENTS_PSP,
|
|
7453
|
+
definitions: [
|
|
7454
|
+
{
|
|
7455
|
+
psp: "vtex_payments",
|
|
7456
|
+
// Ollie's card post to a VTEX account's own vault, as the header above reads it, and the fallback host, which
|
|
7457
|
+
// the gate recognizes only to refuse, so the agent's placeholder never reaches it either. VTEX has no test host:
|
|
7458
|
+
// every request is live. Prepared only: Ollie gives the post 12 seconds. Ships dark: served only to a client that
|
|
7459
|
+
// declares `vtex_payments_card_payment`, on for Agentcard's own company alone (backend
|
|
7460
|
+
// checkout-processor-gate.ts), and autopilot never sends it.
|
|
7461
|
+
capability: "vtex_payments_card_payment",
|
|
7462
|
+
match: "[a-z0-9-]{1,63}\\.vtexvault\\.com/api/payments/transactions/[A-Za-z0-9-]{1,64}/payments(?![\\w/.%-])",
|
|
7463
|
+
hosts: ["^[a-z0-9-]{1,63}\\.vtexvault\\.com$"],
|
|
7464
|
+
preparationRequired: true,
|
|
7465
|
+
encoding: "json",
|
|
7466
|
+
// Ollie's fetch sets the JSON content type alone. Origin, Referer and cookies never ride.
|
|
7467
|
+
passthroughHeaders: [],
|
|
7468
|
+
jsonCardFields: [[0, "fields", "cardNumber"]]
|
|
7469
|
+
}
|
|
7470
|
+
],
|
|
7471
|
+
// Only the cardholder's device sends it, after a person approves; no reviewed list names vtex_payments.
|
|
7472
|
+
refusedOperations: [VTEX_PAYMENTS_OPERATION],
|
|
7473
|
+
// Not surveyed: VTEX names a payment's end only to the store's own API keys and at the gatewayCallback that follows.
|
|
7474
|
+
settlementReadback: "not_surveyed",
|
|
7475
|
+
exactUrl: isVtexPaymentsCardUrl,
|
|
7476
|
+
bodyGate: (url, body) => {
|
|
7477
|
+
if (url === void 0)
|
|
7478
|
+
return vtexPaymentsBodyVerdict(body);
|
|
7479
|
+
const target = vtexPaymentsCardTarget(url);
|
|
7480
|
+
if (target === null)
|
|
7481
|
+
return refuse43("vtex_payments_url_refused");
|
|
7482
|
+
return target.fallback ? refuse43("vtex_payments_fallback_refused") : vtexPaymentsBodyVerdict(body, target);
|
|
7483
|
+
},
|
|
7484
|
+
amount: (template) => record37(template) && isVtexPaymentsCardUrl(template.url) ? vtexPaymentsAmount(template.body) : null
|
|
7485
|
+
});
|
|
6217
7486
|
// src/processors/index.generated.js
|
|
6218
7487
|
var REGISTERED_MODULES = Object.freeze({
|
|
6219
|
-
|
|
7488
|
+
bluesnap: bluesnap_default,
|
|
7489
|
+
iyzico: iyzico_default,
|
|
7490
|
+
midtrans: midtrans_default,
|
|
7491
|
+
oceanpayment: oceanpayment_default,
|
|
7492
|
+
paymentwall: paymentwall_default,
|
|
7493
|
+
payplug: payplug_default,
|
|
7494
|
+
processout: processout_default,
|
|
7495
|
+
usaepay: usaepay_default,
|
|
7496
|
+
vtex_payments: vtex_payments_default
|
|
6220
7497
|
});
|
|
6221
7498
|
// src/registry.js
|
|
6222
7499
|
var REGISTERED_PROCESSORS = Object.values(REGISTERED_MODULES);
|
|
@@ -6404,7 +7681,7 @@ function carriesCardFields(recognizer, body) {
|
|
|
6404
7681
|
if (typeof body !== "string" || body === "")
|
|
6405
7682
|
return false;
|
|
6406
7683
|
const anyCase = recognizer.caseInsensitiveFormKeys === true;
|
|
6407
|
-
const wanted = anyCase ? fields.map((
|
|
7684
|
+
const wanted = anyCase ? fields.map((field3) => String(field3).toLowerCase()) : fields;
|
|
6408
7685
|
for (const chunk of body.split("&")) {
|
|
6409
7686
|
const eq = chunk.indexOf("=");
|
|
6410
7687
|
if (eq <= 0 || eq === chunk.length - 1)
|
|
@@ -6484,15 +7761,28 @@ function namesCardNumber(root, declared) {
|
|
|
6484
7761
|
}
|
|
6485
7762
|
function splitCardLeg(recognizer, body) {
|
|
6486
7763
|
const split = recognizer && recognizer.splitCard;
|
|
6487
|
-
if (!split || typeof split !== "object" ||
|
|
7764
|
+
if (!split || typeof split !== "object" || typeof body !== "string" || body === "")
|
|
7765
|
+
return null;
|
|
7766
|
+
const gate = processorGate(recognizer, void 0, body);
|
|
7767
|
+
if (gate !== null ? gate.verdict !== "continue" : carriesCardFields(recognizer, body))
|
|
6488
7768
|
return null;
|
|
6489
|
-
|
|
7769
|
+
const keys = recognizer.encoding === "form" ? formKeys(body) : recognizer.encoding === "json" ? jsonKeys(body) : null;
|
|
7770
|
+
if (keys === null)
|
|
6490
7771
|
return null;
|
|
6491
7772
|
const list = (value) => Array.isArray(value) ? value.filter((key) => typeof key === "string" && key !== "") : [];
|
|
6492
7773
|
const absorb = list(split.absorb);
|
|
6493
7774
|
const pass = list(split.pass);
|
|
6494
7775
|
const sibling = list(split.siblingKeys);
|
|
6495
|
-
const
|
|
7776
|
+
const own19 = keys.filter((key) => !sibling.includes(key));
|
|
7777
|
+
if (own19.length === 0)
|
|
7778
|
+
return null;
|
|
7779
|
+
if (own19.every((key) => absorb.includes(key)))
|
|
7780
|
+
return "absorb";
|
|
7781
|
+
if (own19.every((key) => pass.includes(key)))
|
|
7782
|
+
return "pass";
|
|
7783
|
+
return null;
|
|
7784
|
+
}
|
|
7785
|
+
function formKeys(body) {
|
|
6496
7786
|
const seen = /* @__PURE__ */ new Set();
|
|
6497
7787
|
for (const chunk of body.split("&")) {
|
|
6498
7788
|
const eq = chunk.indexOf("=");
|
|
@@ -6508,16 +7798,18 @@ function splitCardLeg(recognizer, body) {
|
|
|
6508
7798
|
if (seen.has(key))
|
|
6509
7799
|
return null;
|
|
6510
7800
|
seen.add(key);
|
|
6511
|
-
if (!sibling.includes(key))
|
|
6512
|
-
own13.push(key);
|
|
6513
7801
|
}
|
|
6514
|
-
|
|
7802
|
+
return [...seen];
|
|
7803
|
+
}
|
|
7804
|
+
function jsonKeys(body) {
|
|
7805
|
+
let parsed;
|
|
7806
|
+
try {
|
|
7807
|
+
parsed = JSON.parse(body);
|
|
7808
|
+
}
|
|
7809
|
+
catch {
|
|
6515
7810
|
return null;
|
|
6516
|
-
|
|
6517
|
-
|
|
6518
|
-
if (own13.every((key) => pass.includes(key)))
|
|
6519
|
-
return "pass";
|
|
6520
|
-
return null;
|
|
7811
|
+
}
|
|
7812
|
+
return isPlainObject(parsed) && JSON.stringify(parsed) === body ? Object.keys(parsed) : null;
|
|
6521
7813
|
}
|
|
6522
7814
|
function requestWithoutCard(recognizer, url, body) {
|
|
6523
7815
|
const gate = processorGate(recognizer, url, body);
|