@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: af4808cd3a159d4e1fe63628b365f7f48968b9b8e7bdd1f8c89f648fa0ce1e92
|
|
4
4
|
// src/deep-freeze.js
|
|
5
5
|
function deepFreeze(value) {
|
|
6
6
|
if (value && typeof value === "object" && !Object.isFrozen(value)) {
|
|
@@ -11,7 +11,17 @@ function deepFreeze(value) {
|
|
|
11
11
|
return value;
|
|
12
12
|
}
|
|
13
13
|
// src/registration.js
|
|
14
|
-
var PARTS = {
|
|
14
|
+
var PARTS = {
|
|
15
|
+
psp: "id",
|
|
16
|
+
definitions: "list",
|
|
17
|
+
refusedOperations: "list",
|
|
18
|
+
settlementReadback: "any",
|
|
19
|
+
exactUrl: "rule",
|
|
20
|
+
bodyGate: "rule",
|
|
21
|
+
amount: "rule",
|
|
22
|
+
hostedEntry: "rule",
|
|
23
|
+
limitations: "sentences"
|
|
24
|
+
};
|
|
15
25
|
var PSP_ID = /^[a-z][a-z0-9_]*$/;
|
|
16
26
|
var registrationProblems = (spec) => problemsOf(spec, PARTS);
|
|
17
27
|
function problemsOf(spec, parts) {
|
|
@@ -27,46 +37,1141 @@ function problemsOf(spec, parts) {
|
|
|
27
37
|
continue;
|
|
28
38
|
if (kind === "rule" && typeof value !== "function")
|
|
29
39
|
problems2.push(`${psp}: ${key} is not a function`);
|
|
40
|
+
if (kind === "flag" && value !== true)
|
|
41
|
+
problems2.push(`${psp}: ${key} is not true`);
|
|
30
42
|
if (kind === "numbers" && !((Array.isArray(value) || value instanceof Set) && [...value].every((n) => typeof n === "string" && /^\d{12,19}$/.test(n)))) {
|
|
31
43
|
problems2.push(`${psp}: ${key} is not a list of card numbers`);
|
|
32
44
|
}
|
|
45
|
+
if (kind === "sentences" && !(Array.isArray(value) && value.length > 0 && value.every((s) => typeof s === "string" && s.trim() !== ""))) {
|
|
46
|
+
problems2.push(`${psp}: ${key} is not a list of sentences`);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
if ("definitions" in parts) {
|
|
50
|
+
if (!Array.isArray(spec.definitions) || spec.definitions.length === 0)
|
|
51
|
+
problems2.push(`${psp}: names no definition`);
|
|
52
|
+
else if (spec.definitions.some((definition) => definition?.psp !== psp))
|
|
53
|
+
problems2.push(`${psp}: a definition names another processor`);
|
|
54
|
+
for (const id of spec.refusedOperations ?? []) {
|
|
55
|
+
if (typeof id !== "string" || !id.startsWith(`${psp}.`))
|
|
56
|
+
problems2.push(`${psp}: ${JSON.stringify(id)} is not one of its operations`);
|
|
57
|
+
}
|
|
58
|
+
const pages = Array.isArray(spec.definitions) ? spec.definitions.filter((d) => d?.hostedForm?.cardIn === "processor_page") : [];
|
|
59
|
+
if (spec.hostedEntry !== void 0 && (pages.length === 0 || pages.some((d) => d.hostedForm.policy !== void 0))) {
|
|
60
|
+
problems2.push(`${psp}: hostedEntry needs a definition whose hosted form takes the card on the processor's page and names no policy`);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return problems2;
|
|
64
|
+
}
|
|
65
|
+
function registered(spec, parts) {
|
|
66
|
+
const problems2 = problemsOf(spec, parts);
|
|
67
|
+
if (problems2.length)
|
|
68
|
+
throw new Error(`payment-core registration refused: ${problems2.join("; ")}`);
|
|
69
|
+
return deepFreeze({ ...spec });
|
|
70
|
+
}
|
|
71
|
+
function registerProcessor(spec) {
|
|
72
|
+
return registered(spec, PARTS);
|
|
73
|
+
}
|
|
74
|
+
// src/processors/bluesnap.js
|
|
75
|
+
var BLUESNAP_PSP = "bluesnap";
|
|
76
|
+
var BLUESNAP_OPERATION = "bluesnap.card_request";
|
|
77
|
+
var BLUESNAP_HOSTS = /* @__PURE__ */ Object.freeze({ 1: "ws1.bluesnap.com", 2: "ws2.bluesnap.com", _: "sandpay.bluesnap.com" });
|
|
78
|
+
var BLUESNAP_SANDBOX_HOST = "sandpay.bluesnap.com";
|
|
79
|
+
var BLUESNAP_CARD_KEYS = /* @__PURE__ */ Object.freeze(["cvv", "ccNumber", "expDate"]);
|
|
80
|
+
var BLUESNAP_LEG_KEYS = /* @__PURE__ */ Object.freeze(["cvv", "expDate"]);
|
|
81
|
+
var BODY_LIMIT = 1024;
|
|
82
|
+
var TOKEN_URL = /^https:\/\/(ws1|ws2|sandpay)\.bluesnap\.com\/services\/2\/payment-fields-tokens\/([0-9a-f]{64}_[12]?)$/;
|
|
83
|
+
var CARD_NUMBER = /^[0-9]{12,19}$/;
|
|
84
|
+
var SECURITY_CODE = /^[0-9]{3,4}$/;
|
|
85
|
+
var EXPIRY = /^(?:0[1-9]|1[0-2])\/20[0-9]{2}$/;
|
|
86
|
+
var SAVED_CARD_KEYS = ["last4Digits", "lastFourDigits", "ccType"];
|
|
87
|
+
var record = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
88
|
+
var own = (value, key) => Object.prototype.hasOwnProperty.call(value, key);
|
|
89
|
+
var refuse = (code) => Object.freeze({ verdict: "refuse", code });
|
|
90
|
+
var CARD = /* @__PURE__ */ Object.freeze({ verdict: "card" });
|
|
91
|
+
var LEG = /* @__PURE__ */ Object.freeze({ verdict: "continue" });
|
|
92
|
+
function bluesnapTokenUrl(url) {
|
|
93
|
+
const match = typeof url === "string" ? TOKEN_URL.exec(url) : null;
|
|
94
|
+
if (!match || BLUESNAP_HOSTS[match[2].slice(-1)] !== `${match[1]}.bluesnap.com`)
|
|
95
|
+
return null;
|
|
96
|
+
const host = `${match[1]}.bluesnap.com`;
|
|
97
|
+
return Object.freeze({ host, token: match[2], environment: host === BLUESNAP_SANDBOX_HOST ? "sandbox" : "production" });
|
|
98
|
+
}
|
|
99
|
+
function isBluesnapTokenUrl(url) {
|
|
100
|
+
return bluesnapTokenUrl(url) !== null;
|
|
101
|
+
}
|
|
102
|
+
function readBody(body) {
|
|
103
|
+
if (typeof body !== "string" || body === "" || body.length > BODY_LIMIT)
|
|
104
|
+
return null;
|
|
105
|
+
try {
|
|
106
|
+
const value = JSON.parse(body);
|
|
107
|
+
return record(value) && JSON.stringify(value) === body ? value : null;
|
|
108
|
+
}
|
|
109
|
+
catch {
|
|
110
|
+
return null;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
function bluesnapBodyVerdict(body) {
|
|
114
|
+
const value = readBody(body);
|
|
115
|
+
if (value === null)
|
|
116
|
+
return refuse("bluesnap_body_unsupported");
|
|
117
|
+
const keys = Object.keys(value);
|
|
118
|
+
if (keys.some((key) => SAVED_CARD_KEYS.includes(key)))
|
|
119
|
+
return refuse(own(value, "ccNumber") ? "bluesnap_body_unsupported" : "bluesnap_saved_card");
|
|
120
|
+
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))) {
|
|
121
|
+
return refuse("bluesnap_body_unsupported");
|
|
122
|
+
}
|
|
123
|
+
if (own(value, "ccNumber") && !(typeof value.ccNumber === "string" && CARD_NUMBER.test(value.ccNumber)) || own(value, "cvv") && !(typeof value.cvv === "string" && SECURITY_CODE.test(value.cvv)) || own(value, "expDate") && !(typeof value.expDate === "string" && EXPIRY.test(value.expDate)))
|
|
124
|
+
return refuse("bluesnap_body_unsupported");
|
|
125
|
+
return own(value, "ccNumber") ? CARD : LEG;
|
|
126
|
+
}
|
|
127
|
+
var bluesnap_default = /* @__PURE__ */ registerProcessor({
|
|
128
|
+
psp: BLUESNAP_PSP,
|
|
129
|
+
definitions: [
|
|
130
|
+
{
|
|
131
|
+
psp: "bluesnap",
|
|
132
|
+
// The card fields' PUTs, as the header above reads them. The sandbox has its own server, so the device sends a
|
|
133
|
+
// test-mode request only documented test cards (hostEnvironmentPinned, device-replay.js S7). `(?![\w/.%-])`
|
|
134
|
+
// ends the token for a consumer that tests `match` unanchored; the exact-URL rule pins each server to its suffix.
|
|
135
|
+
// Ships dark: served only to a client that declares `bluesnap_hosted_payment_fields`, and the backend's gate turns
|
|
136
|
+
// it on for Agentcard's own company alone, in code.
|
|
137
|
+
capability: "bluesnap_hosted_payment_fields",
|
|
138
|
+
match: "(?:ws1|ws2|sandpay)\\.bluesnap\\.com/services/2/payment-fields-tokens/[0-9a-f]{64}_[12]?(?![\\w/.%-])",
|
|
139
|
+
hosts: ["^ws1\\.bluesnap\\.com$", "^ws2\\.bluesnap\\.com$", "^sandpay\\.bluesnap\\.com$"],
|
|
140
|
+
sandboxHosts: ["^sandpay\\.bluesnap\\.com$"],
|
|
141
|
+
hostEnvironmentPinned: true,
|
|
142
|
+
encoding: "json",
|
|
143
|
+
// The frames' own headers, each held to its shape by bluesnapRequestRefusal. Origin, Referer and cookies never
|
|
144
|
+
// ride (the frames send no cookie).
|
|
145
|
+
passthroughHeaders: ["^authorization$", "^bluesnap_version_header$", "^bluesnap_origin_version_header$", "^bluesnap_origin_header$"],
|
|
146
|
+
jsonCardFields: [["ccNumber"]],
|
|
147
|
+
// The expiry and code frames' PUTs: held by the checkout SDK and answered with the card request's answer.
|
|
148
|
+
splitCard: { absorb: [...BLUESNAP_LEG_KEYS], pass: [], siblingKeys: [] },
|
|
149
|
+
request: { method: "PUT", cardIn: "body", response: "json" }
|
|
150
|
+
}
|
|
151
|
+
],
|
|
152
|
+
// Only the cardholder's device sends the card, after a person approves; no reviewed list names bluesnap.
|
|
153
|
+
refusedOperations: [BLUESNAP_OPERATION],
|
|
154
|
+
// Not surveyed: the PUT moves no money, and the merchant's own charge is a server call Agentcard never sees.
|
|
155
|
+
settlementReadback: "not_surveyed",
|
|
156
|
+
exactUrl: isBluesnapTokenUrl,
|
|
157
|
+
bodyGate: (url, body) => url !== void 0 && !isBluesnapTokenUrl(url) ? { verdict: "refuse", code: "bluesnap_url_refused" } : bluesnapBodyVerdict(body)
|
|
158
|
+
});
|
|
159
|
+
// src/processors/iyzico.js
|
|
160
|
+
var IYZICO_PSP = "iyzico";
|
|
161
|
+
var IYZICO_OPERATION = "iyzico.card_request";
|
|
162
|
+
var PATHS = ["/payment/iyzipos/checkoutform/auth/ecom", "/payment/iyzipos/checkoutform/initialize3ds/ecom"];
|
|
163
|
+
var IYZICO_CARD_URLS = /* @__PURE__ */ Object.freeze(["https://api.iyzipay.com", "https://sandbox-api.iyzipay.com"].flatMap((origin) => PATHS.map((path) => `${origin}${path}`)));
|
|
164
|
+
var IYZICO_BODY_KEYS = /* @__PURE__ */ Object.freeze([
|
|
165
|
+
"installment",
|
|
166
|
+
"paidPrice",
|
|
167
|
+
"paymentChannel",
|
|
168
|
+
"paymentCard",
|
|
169
|
+
"buyerProtected",
|
|
170
|
+
"gsmNumber",
|
|
171
|
+
"dccPayment",
|
|
172
|
+
"dccQueryRrn",
|
|
173
|
+
"pwiMetadata"
|
|
174
|
+
]);
|
|
175
|
+
var IYZICO_CARD_KEYS = /* @__PURE__ */ Object.freeze([
|
|
176
|
+
"cardNumber",
|
|
177
|
+
"cardHolderName",
|
|
178
|
+
"expireYear",
|
|
179
|
+
"expireMonth",
|
|
180
|
+
"cvc",
|
|
181
|
+
"registerConsumerCard",
|
|
182
|
+
"registerCard"
|
|
183
|
+
]);
|
|
184
|
+
var BODY_LIMIT2 = 4096;
|
|
185
|
+
var CARD_NUMBER2 = /^[0-9]{12,19}$/;
|
|
186
|
+
var SECURITY_CODE2 = /^[0-9]{3,4}$/;
|
|
187
|
+
var MONTH = /^(?:0?[1-9]|1[0-2])$/;
|
|
188
|
+
var YEAR = /^(?:[0-9]{2}|20[0-9]{2})$/;
|
|
189
|
+
var PRICE = /^([1-9][0-9]{0,8}|0)(?:\.([0-9]{1,2}))?$/;
|
|
190
|
+
var CHANNELS = /* @__PURE__ */ Object.freeze(["WEB", "MOBILE_WEB", "MOBILE_IOS", "MOBILE_ANDROID", "MOBILE_WINDOWS"]);
|
|
191
|
+
var METADATA_KEYS = /* @__PURE__ */ Object.freeze(["lightRedesign", "pwiGrowthActionDisabled"]);
|
|
192
|
+
var FLAG = /^[A-Za-z_]{1,16}$/;
|
|
193
|
+
var HOLDER = /^[^\x00-\x1f\x7f0-9]{3,100}$/u;
|
|
194
|
+
var record2 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
195
|
+
var own2 = (value, key) => Object.prototype.hasOwnProperty.call(value, key);
|
|
196
|
+
var inOrder = (value, keys) => {
|
|
197
|
+
let at = 0;
|
|
198
|
+
for (const name of Object.keys(value)) {
|
|
199
|
+
while (at < keys.length && keys[at] !== name)
|
|
200
|
+
at += 1;
|
|
201
|
+
if (at === keys.length)
|
|
202
|
+
return false;
|
|
203
|
+
at += 1;
|
|
204
|
+
}
|
|
205
|
+
return true;
|
|
206
|
+
};
|
|
207
|
+
var refuse2 = (code) => Object.freeze({ verdict: "refuse", code });
|
|
208
|
+
var CARD2 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
|
|
209
|
+
function isIyzicoCardUrl(url) {
|
|
210
|
+
return typeof url === "string" && IYZICO_CARD_URLS.includes(url);
|
|
211
|
+
}
|
|
212
|
+
function readBody2(body) {
|
|
213
|
+
if (typeof body !== "string" || body === "" || body.length > BODY_LIMIT2)
|
|
214
|
+
return null;
|
|
215
|
+
try {
|
|
216
|
+
const value = JSON.parse(body);
|
|
217
|
+
return record2(value) && JSON.stringify(value) === body ? value : null;
|
|
218
|
+
}
|
|
219
|
+
catch {
|
|
220
|
+
return null;
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
function hundredths(price) {
|
|
224
|
+
const match = typeof price === "number" && Number.isFinite(price) ? PRICE.exec(String(price)) : null;
|
|
225
|
+
const value = match ? Number(match[1]) * 100 + Number((match[2] ?? "").padEnd(2, "0")) : 0;
|
|
226
|
+
return value > 0 ? value : null;
|
|
227
|
+
}
|
|
228
|
+
var holderName = (name) => typeof name === "string" && HOLDER.test(name) && name.trim().split(/\s+/).filter((word) => word.length > 1).length > 1;
|
|
229
|
+
var metadata = (value) => record2(value) && inOrder(value, METADATA_KEYS) && Object.values(value).every((flag) => Array.isArray(flag) && flag.length === 1 && typeof flag[0] === "string" && FLAG.test(flag[0]));
|
|
230
|
+
function iyzicoBodyVerdict(body) {
|
|
231
|
+
const value = readBody2(body);
|
|
232
|
+
if (value === null)
|
|
233
|
+
return refuse2("iyzico_body_unsupported");
|
|
234
|
+
const card = value.paymentCard;
|
|
235
|
+
if (record2(card) && (own2(card, "cardToken") || own2(card, "ucsToken") || own2(card, "consumerToken")) && !own2(card, "cardNumber"))
|
|
236
|
+
return refuse2("iyzico_saved_card");
|
|
237
|
+
if (own2(value, "dccPayment") || own2(value, "dccQueryRrn"))
|
|
238
|
+
return refuse2("iyzico_dcc_refused");
|
|
239
|
+
if (own2(value, "gsmNumber") || own2(value, "buyerProtected") && value.buyerProtected !== false || record2(card) && (own2(card, "registerCard") && card.registerCard !== 0 || own2(card, "registerConsumerCard") && card.registerConsumerCard !== false)) {
|
|
240
|
+
return refuse2("iyzico_keeps_card");
|
|
241
|
+
}
|
|
242
|
+
if (Number.isSafeInteger(value.installment) && value.installment > 1)
|
|
243
|
+
return refuse2("iyzico_installments_refused");
|
|
244
|
+
if (!inOrder(value, IYZICO_BODY_KEYS) || !["installment", "paidPrice", "paymentChannel", "paymentCard"].every((key) => own2(value, key)) || value.installment !== 1 || hundredths(value.paidPrice) === null || !CHANNELS.includes(value.paymentChannel) || own2(value, "pwiMetadata") && !metadata(value.pwiMetadata))
|
|
245
|
+
return refuse2("iyzico_body_unsupported");
|
|
246
|
+
if (!record2(card) || Object.keys(card).join() !== IYZICO_CARD_KEYS.join() || typeof card.cardNumber !== "string" || !CARD_NUMBER2.test(card.cardNumber) || !holderName(card.cardHolderName) || typeof card.expireYear !== "string" || !YEAR.test(card.expireYear) || typeof card.expireMonth !== "string" || !MONTH.test(card.expireMonth) || typeof card.cvc !== "string" || !SECURITY_CODE2.test(card.cvc))
|
|
247
|
+
return refuse2("iyzico_body_unsupported");
|
|
248
|
+
return CARD2;
|
|
249
|
+
}
|
|
250
|
+
var iyzico_default = /* @__PURE__ */ registerProcessor({
|
|
251
|
+
psp: IYZICO_PSP,
|
|
252
|
+
definitions: [
|
|
253
|
+
{
|
|
254
|
+
psp: "iyzico",
|
|
255
|
+
// The Checkout Form's card payment, as the header above reads it. Sandbox has its own host, so the device sends
|
|
256
|
+
// a test-mode payment only iyzico's documented test cards (hostEnvironmentPinned, device-replay.js S7). Ships dark:
|
|
257
|
+
// served only to a client that declares `iyzico_checkout_form`, for a company the backend's gate turns iyzico on
|
|
258
|
+
// for, and autopilot never sends it.
|
|
259
|
+
capability: "iyzico_checkout_form",
|
|
260
|
+
match: "(?:sandbox-)?api\\.iyzipay\\.com/payment/iyzipos/checkoutform/(?:auth|initialize3ds)/ecom",
|
|
261
|
+
hosts: ["^api\\.iyzipay\\.com$", "^sandbox-api\\.iyzipay\\.com$"],
|
|
262
|
+
sandboxHosts: ["^sandbox-api\\.iyzipay\\.com$"],
|
|
263
|
+
hostEnvironmentPinned: true,
|
|
264
|
+
encoding: "json",
|
|
265
|
+
// The form's session token and its Accept. Origin, Referer and cookies never ride, and neither does IYZI_LC,
|
|
266
|
+
// which iyzico's preflight does not allow.
|
|
267
|
+
passthroughHeaders: ["^x-iyzi-token$", "^accept$"],
|
|
268
|
+
jsonCardFields: [["paymentCard", "cardNumber"]]
|
|
269
|
+
}
|
|
270
|
+
],
|
|
271
|
+
// Only the cardholder's device sends it, after a person approves; 3-D Secure needs that person at the browser.
|
|
272
|
+
refusedOperations: [IYZICO_OPERATION],
|
|
273
|
+
// iyzico answers the form's result (CF retrieve) only to the merchant's API key and secret.
|
|
274
|
+
settlementReadback: {
|
|
275
|
+
answer: "none",
|
|
276
|
+
reason: "merchant_credential_required",
|
|
277
|
+
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.",
|
|
278
|
+
source: "https://docs.iyzico.com/en/payment-methods/checkoutform/cf-implementation/cf-retrieve"
|
|
279
|
+
},
|
|
280
|
+
exactUrl: isIyzicoCardUrl,
|
|
281
|
+
bodyGate: (url, body) => url !== void 0 && !isIyzicoCardUrl(url) ? refuse2("iyzico_url_refused") : iyzicoBodyVerdict(body)
|
|
282
|
+
});
|
|
283
|
+
// src/processors/midtrans.js
|
|
284
|
+
var MIDTRANS_PSP = "midtrans";
|
|
285
|
+
var MIDTRANS_OPERATION = "midtrans.card_request";
|
|
286
|
+
var MIDTRANS_TOKEN_URL = "https://api.midtrans.com/v2/token";
|
|
287
|
+
var MIDTRANS_SANDBOX_TOKEN_URL = "https://api.sandbox.midtrans.com/v2/token";
|
|
288
|
+
var MIDTRANS_TOKEN_KEYS = /* @__PURE__ */ Object.freeze(["card_cvv", "card_number", "card_exp_month", "card_exp_year", "installment_term"]);
|
|
289
|
+
var BODY_LIMIT3 = 4096;
|
|
290
|
+
var CARD_NUMBER3 = /^[0-9]{12,19}$/;
|
|
291
|
+
var SECURITY_CODE3 = /^[0-9]{3,4}$/;
|
|
292
|
+
var MONTH2 = /^(?:0[1-9]|1[0-2])$/;
|
|
293
|
+
var YEAR2 = /^20[0-9]{2}$/;
|
|
294
|
+
var TERM = /^[0-9]{1,3}$/;
|
|
295
|
+
var record3 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
296
|
+
var own3 = (value, key) => Object.prototype.hasOwnProperty.call(value, key);
|
|
297
|
+
var inOrder2 = (value, keys) => {
|
|
298
|
+
let at = 0;
|
|
299
|
+
for (const name of Object.keys(value)) {
|
|
300
|
+
while (at < keys.length && keys[at] !== name)
|
|
301
|
+
at += 1;
|
|
302
|
+
if (at === keys.length)
|
|
303
|
+
return false;
|
|
304
|
+
at += 1;
|
|
305
|
+
}
|
|
306
|
+
return true;
|
|
307
|
+
};
|
|
308
|
+
var refuse3 = (code) => Object.freeze({ verdict: "refuse", code });
|
|
309
|
+
var CARD3 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
|
|
310
|
+
function isMidtransTokenUrl(url) {
|
|
311
|
+
return url === MIDTRANS_TOKEN_URL || url === MIDTRANS_SANDBOX_TOKEN_URL;
|
|
312
|
+
}
|
|
313
|
+
function readBody3(body) {
|
|
314
|
+
if (typeof body !== "string" || body === "" || body.length > BODY_LIMIT3)
|
|
315
|
+
return null;
|
|
316
|
+
let value;
|
|
317
|
+
try {
|
|
318
|
+
value = JSON.parse(body);
|
|
319
|
+
if (!record3(value) || JSON.stringify(value) !== body)
|
|
320
|
+
return null;
|
|
321
|
+
}
|
|
322
|
+
catch {
|
|
323
|
+
return null;
|
|
324
|
+
}
|
|
325
|
+
return value;
|
|
326
|
+
}
|
|
327
|
+
function midtransBodyVerdict(body) {
|
|
328
|
+
const value = readBody3(body);
|
|
329
|
+
if (value === null || !inOrder2(value, MIDTRANS_TOKEN_KEYS)) {
|
|
330
|
+
if (record3(value) && (own3(value, "token_id") || own3(value, "two_click")) && !own3(value, "card_number"))
|
|
331
|
+
return refuse3("midtrans_saved_card");
|
|
332
|
+
return refuse3("midtrans_body_unsupported");
|
|
333
|
+
}
|
|
334
|
+
if (!own3(value, "card_cvv") || !own3(value, "card_number") || !own3(value, "card_exp_month") || !own3(value, "card_exp_year")) {
|
|
335
|
+
return refuse3("midtrans_body_unsupported");
|
|
336
|
+
}
|
|
337
|
+
if (typeof value.card_cvv !== "string" || !SECURITY_CODE3.test(value.card_cvv) || typeof value.card_number !== "string" || !CARD_NUMBER3.test(value.card_number) || typeof value.card_exp_month !== "string" || !MONTH2.test(value.card_exp_month) || typeof value.card_exp_year !== "string" || !YEAR2.test(value.card_exp_year))
|
|
338
|
+
return refuse3("midtrans_body_unsupported");
|
|
339
|
+
if (own3(value, "installment_term") && (typeof value.installment_term !== "string" || !TERM.test(value.installment_term)))
|
|
340
|
+
return refuse3("midtrans_body_unsupported");
|
|
341
|
+
return CARD3;
|
|
342
|
+
}
|
|
343
|
+
var midtrans_default = /* @__PURE__ */ registerProcessor({
|
|
344
|
+
psp: MIDTRANS_PSP,
|
|
345
|
+
definitions: [
|
|
346
|
+
{
|
|
347
|
+
psp: "midtrans",
|
|
348
|
+
// Snap's token request, as the header above reads it. Sandbox has its own host, so the device sends a
|
|
349
|
+
// test-mode request only Midtrans' documented test cards (hostEnvironmentPinned, device-replay.js S7).
|
|
350
|
+
// Ships dark: served only to a client that declares `midtrans_card_token`, gated off for every org until an
|
|
351
|
+
// operator lists one (`midtrans:<org>`), and the backend's gate serves only Agentcard's own company until the
|
|
352
|
+
// token's publishable key is bound to the merchant (backend config.ts MIDTRANS_KEY_BOUND_TO_MERCHANT).
|
|
353
|
+
capability: "midtrans_card_token",
|
|
354
|
+
match: "api\\.(?:sandbox\\.)?midtrans\\.com/v2/token",
|
|
355
|
+
hosts: ["^api\\.midtrans\\.com$", "^api\\.sandbox\\.midtrans\\.com$"],
|
|
356
|
+
sandboxHosts: ["^api\\.sandbox\\.midtrans\\.com$"],
|
|
357
|
+
hostEnvironmentPinned: true,
|
|
358
|
+
encoding: "json",
|
|
359
|
+
// Snap's own headers: the publishable client key (Authorization Basic) and X-Service. Origin, Referer and
|
|
360
|
+
// cookies never ride.
|
|
361
|
+
passthroughHeaders: ["^authorization$", "^x-service$"],
|
|
362
|
+
jsonCardFields: [["card_number"]]
|
|
363
|
+
}
|
|
364
|
+
],
|
|
365
|
+
// Only the cardholder's device sends a token, after a person approves; no reviewed list names midtrans.
|
|
366
|
+
refusedOperations: [MIDTRANS_OPERATION],
|
|
367
|
+
// Not surveyed: the token moves no money, and the merchant's own charge names its status by the order id alone.
|
|
368
|
+
settlementReadback: "not_surveyed",
|
|
369
|
+
exactUrl: isMidtransTokenUrl,
|
|
370
|
+
bodyGate: (url, body) => url !== void 0 && !isMidtransTokenUrl(url) ? { verdict: "refuse", code: "midtrans_url_refused" } : midtransBodyVerdict(body)
|
|
371
|
+
});
|
|
372
|
+
// src/processors/oceanpayment.js
|
|
373
|
+
var OCEANPAYMENT_PSP = "oceanpayment";
|
|
374
|
+
var OCEANPAYMENT_OPERATION = "oceanpayment.card_request";
|
|
375
|
+
var OCEANPAYMENT_HOSTS = /* @__PURE__ */ Object.freeze({ "secure.oceanpayment.com": "production", "test-secure.oceanpayment.com": "sandbox" });
|
|
376
|
+
var OCEANPAYMENT_FORM_FIELDS = /* @__PURE__ */ Object.freeze([
|
|
377
|
+
"card_number_three",
|
|
378
|
+
"card_number_two",
|
|
379
|
+
"card_number_temp",
|
|
380
|
+
"card_number",
|
|
381
|
+
"card_date",
|
|
382
|
+
"card_year",
|
|
383
|
+
"card_month",
|
|
384
|
+
"card_secureCode",
|
|
385
|
+
"copyCard",
|
|
386
|
+
"closePage",
|
|
387
|
+
"starttime",
|
|
388
|
+
"endtime",
|
|
389
|
+
"comloadpage",
|
|
390
|
+
"timezone",
|
|
391
|
+
"OSLang",
|
|
392
|
+
"os",
|
|
393
|
+
"brower",
|
|
394
|
+
"BrowerLang",
|
|
395
|
+
"resolution",
|
|
396
|
+
"methods",
|
|
397
|
+
"reference_id",
|
|
398
|
+
"methods",
|
|
399
|
+
"reference"
|
|
400
|
+
]);
|
|
401
|
+
var URL_LIMIT = 2048;
|
|
402
|
+
var BODY_LIMIT4 = 8192;
|
|
403
|
+
var SEND_PAY = /^\/gateway\/sendPay;jsessionid=[A-Za-z0-9._!-]{16,128}$/;
|
|
404
|
+
var own4 = (value, key) => Object.prototype.hasOwnProperty.call(value, key);
|
|
405
|
+
var exact = (pattern, value) => typeof value === "string" && pattern.test(value);
|
|
406
|
+
var CARD_RUN = /[0-9]{12}/;
|
|
407
|
+
var printable = (max) => (value) => typeof value === "string" && value.length <= max && /^[\x20-\x7e]*$/.test(value) && !CARD_RUN.test(value);
|
|
408
|
+
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})$/;
|
|
409
|
+
var LANGUAGE = /^(?:|[A-Za-z]{2,8}(?:[-_][A-Za-z0-9]{1,8}){0,3})$/;
|
|
410
|
+
var SHAPES = /* @__PURE__ */ new Map([
|
|
411
|
+
["customerCardType", (v) => v === ""],
|
|
412
|
+
// The page's paste and typing markers: "0" until typed, the number's length when its key handler read it, or "N"
|
|
413
|
+
// after a paste.
|
|
414
|
+
["card_number_three", (v) => exact(/^(?:0|N|[1-9]|1[0-9])$/, v)],
|
|
415
|
+
["card_number_two", (v) => exact(/^(?:0|[1-9]|1[0-9])$/, v)],
|
|
416
|
+
["card_number_temp", (v) => exact(/^[0-9]{4}(?: ?[0-9]{4}){3}$/, v)],
|
|
417
|
+
["card_number", (v) => exact(/^[0-9]{16}$/, v)],
|
|
418
|
+
["card_date", (v) => exact(/^(?:0[1-9]|1[0-2])\/[0-9]{2}$/, v)],
|
|
419
|
+
["card_year", (v) => exact(/^20[0-9]{2}$/, v)],
|
|
420
|
+
["card_month", (v) => exact(/^(?:0[1-9]|1[0-2])$/, v)],
|
|
421
|
+
["card_secureCode", (v) => exact(/^[0-9]{3,4}$/, v)],
|
|
422
|
+
["copyCard", (v) => v === "" || v === "0" || v === "1"],
|
|
423
|
+
// PAY NOW's handler sets it to 1 before the page submits.
|
|
424
|
+
["closePage", (v) => v === "1"],
|
|
425
|
+
["starttime", (v) => exact(STAMP, v)],
|
|
426
|
+
["endtime", (v) => exact(STAMP, v)],
|
|
427
|
+
["comloadpage", (v) => v === "0" || v === "1"],
|
|
428
|
+
// getTimezoneOffset()/60*-1: whole or fractional hours.
|
|
429
|
+
["timezone", (v) => exact(/^(?:|-?(?:[0-9]|1[0-4])(?:\.[0-9]{1,2})?)$/, v)],
|
|
430
|
+
["OSLang", (v) => exact(LANGUAGE, v)],
|
|
431
|
+
["os", printable(64)],
|
|
432
|
+
["brower", printable(128)],
|
|
433
|
+
["BrowerLang", (v) => exact(LANGUAGE, v)],
|
|
434
|
+
["resolution", printable(32)],
|
|
435
|
+
["methods", (v) => v === "1"],
|
|
436
|
+
["reference_id", (v) => v === ""],
|
|
437
|
+
// The page's own trade number.
|
|
438
|
+
["reference", (v) => exact(/^[0-9]{1,40}$/, v)],
|
|
439
|
+
["button", (v) => v === ""]
|
|
440
|
+
]);
|
|
441
|
+
function oceanpaymentSendPayUrl(url) {
|
|
442
|
+
if (typeof url !== "string" || url.length > URL_LIMIT || url.includes("?") || url.includes("#"))
|
|
443
|
+
return null;
|
|
444
|
+
let parsed;
|
|
445
|
+
try {
|
|
446
|
+
parsed = new URL(url);
|
|
447
|
+
}
|
|
448
|
+
catch {
|
|
449
|
+
return null;
|
|
450
|
+
}
|
|
451
|
+
if (parsed.href !== url || parsed.protocol !== "https:" || parsed.port || parsed.username || parsed.password || !own4(OCEANPAYMENT_HOSTS, parsed.hostname) || !SEND_PAY.test(parsed.pathname))
|
|
452
|
+
return null;
|
|
453
|
+
return Object.freeze({ host: parsed.hostname, environment: OCEANPAYMENT_HOSTS[parsed.hostname] });
|
|
454
|
+
}
|
|
455
|
+
var isOceanpaymentSendPayUrl = (url) => oceanpaymentSendPayUrl(url) !== null;
|
|
456
|
+
function formEncode(value) {
|
|
457
|
+
let encoded;
|
|
458
|
+
try {
|
|
459
|
+
encoded = encodeURIComponent(value);
|
|
460
|
+
}
|
|
461
|
+
catch {
|
|
462
|
+
return null;
|
|
463
|
+
}
|
|
464
|
+
return encoded.replace(/[!'()~]/g, (ch) => `%${ch.charCodeAt(0).toString(16).toUpperCase()}`).replace(/%20/g, "+");
|
|
465
|
+
}
|
|
466
|
+
function formDecode(raw) {
|
|
467
|
+
if (!/^(?:[A-Za-z0-9*._+-]|%[0-9A-F]{2})*$/.test(raw))
|
|
468
|
+
return null;
|
|
469
|
+
let value;
|
|
470
|
+
try {
|
|
471
|
+
value = decodeURIComponent(raw.replace(/\+/g, "%20"));
|
|
472
|
+
}
|
|
473
|
+
catch {
|
|
474
|
+
return null;
|
|
475
|
+
}
|
|
476
|
+
return formEncode(value) === raw ? value : null;
|
|
477
|
+
}
|
|
478
|
+
function readPairs(body) {
|
|
479
|
+
if (typeof body !== "string" || body === "" || body.length > BODY_LIMIT4)
|
|
480
|
+
return null;
|
|
481
|
+
const pairs = [];
|
|
482
|
+
for (const chunk of body.split("&")) {
|
|
483
|
+
const separator = chunk.indexOf("=");
|
|
484
|
+
if (separator < 1)
|
|
485
|
+
return null;
|
|
486
|
+
const rawName = chunk.slice(0, separator), raw = chunk.slice(separator + 1);
|
|
487
|
+
const name = formDecode(rawName), value = formDecode(raw);
|
|
488
|
+
if (name === null || value === null)
|
|
489
|
+
return null;
|
|
490
|
+
pairs.push({ name, rawName, raw, value });
|
|
491
|
+
}
|
|
492
|
+
return pairs;
|
|
493
|
+
}
|
|
494
|
+
function formPairs(body) {
|
|
495
|
+
const pairs = readPairs(body);
|
|
496
|
+
if (!pairs)
|
|
497
|
+
return null;
|
|
498
|
+
const start = pairs[0].name === "customerCardType" ? 1 : 0;
|
|
499
|
+
const end = pairs[pairs.length - 1].name === "button" ? pairs.length - 1 : pairs.length;
|
|
500
|
+
if (end - start !== OCEANPAYMENT_FORM_FIELDS.length || OCEANPAYMENT_FORM_FIELDS.some((name, i) => pairs[start + i].name !== name))
|
|
501
|
+
return null;
|
|
502
|
+
return pairs;
|
|
503
|
+
}
|
|
504
|
+
var valueOf = (pairs, name) => pairs.find((pair) => pair.name === name)?.value;
|
|
505
|
+
function bodyRefusal(body) {
|
|
506
|
+
const pairs = formPairs(body);
|
|
507
|
+
if (!pairs)
|
|
508
|
+
return "oceanpayment_body_unsupported";
|
|
509
|
+
if (pairs[0].name === "customerCardType" && pairs[0].value !== "")
|
|
510
|
+
return "oceanpayment_card_brand_refused";
|
|
511
|
+
if (valueOf(pairs, "reference_id") !== "")
|
|
512
|
+
return "oceanpayment_device_data_refused";
|
|
513
|
+
if (pairs.some(({ name, value }) => !SHAPES.get(name)(value)))
|
|
514
|
+
return "oceanpayment_body_unsupported";
|
|
515
|
+
const number = valueOf(pairs, "card_number");
|
|
516
|
+
const temp = valueOf(pairs, "card_number_temp");
|
|
517
|
+
const [month, year] = valueOf(pairs, "card_date").split("/");
|
|
518
|
+
if (temp.replace(/ /g, "") !== number || temp !== number && temp !== spaced(number))
|
|
519
|
+
return "oceanpayment_body_unsupported";
|
|
520
|
+
if (valueOf(pairs, "card_month") !== month || valueOf(pairs, "card_year") !== `20${year}`)
|
|
521
|
+
return "oceanpayment_body_unsupported";
|
|
522
|
+
return null;
|
|
523
|
+
}
|
|
524
|
+
var spaced = (number) => number.replace(/([0-9]{4})(?=[0-9])/g, "$1 ");
|
|
525
|
+
function oceanpaymentBodyVerdict(body) {
|
|
526
|
+
const code = bodyRefusal(body);
|
|
527
|
+
return code ? Object.freeze({ verdict: "refuse", code }) : Object.freeze({ verdict: "card" });
|
|
528
|
+
}
|
|
529
|
+
var oceanpayment_default = /* @__PURE__ */ registerProcessor({
|
|
530
|
+
psp: OCEANPAYMENT_PSP,
|
|
531
|
+
definitions: [
|
|
532
|
+
{
|
|
533
|
+
psp: "oceanpayment",
|
|
534
|
+
// The hosted page's card post, as the header above reads it. The sandbox has its own host, so a test row's device
|
|
535
|
+
// sends only Oceanpayment's documented test cards (hostEnvironmentPinned, device-replay.js S7).
|
|
536
|
+
// Ships dark: served only to a client that declares `oceanpayment_hosted_payment_page`, and only for a company the
|
|
537
|
+
// backend's processor gate turns Oceanpayment on for. `(?![\w/.%;=!-])` ends the path for a consumer that tests
|
|
538
|
+
// `match` unanchored.
|
|
539
|
+
capability: "oceanpayment_hosted_payment_page",
|
|
540
|
+
match: "(?:test-)?secure\\.oceanpayment\\.com/gateway/sendPay;jsessionid=[A-Za-z0-9._!-]{16,128}(?![\\w/.%;=!-])",
|
|
541
|
+
hosts: ["^secure\\.oceanpayment\\.com$", "^test-secure\\.oceanpayment\\.com$"],
|
|
542
|
+
sandboxHosts: ["^test-secure\\.oceanpayment\\.com$"],
|
|
543
|
+
hostEnvironmentPinned: true,
|
|
544
|
+
encoding: "form",
|
|
545
|
+
// A form navigation: nothing but its type is replayed. Origin, Referer and cookies never ride.
|
|
546
|
+
passthroughHeaders: [],
|
|
547
|
+
cardFields: ["card_number"]
|
|
548
|
+
}
|
|
549
|
+
],
|
|
550
|
+
// Only the cardholder's device sends this card, after a person approves; no reviewed list names oceanpayment.
|
|
551
|
+
refusedOperations: [OCEANPAYMENT_OPERATION],
|
|
552
|
+
// Not surveyed: Oceanpayment tells the merchant's server the result (its noticeUrl), and reading a payment back takes the
|
|
553
|
+
// merchant's own secure code, which Agentcard never holds.
|
|
554
|
+
settlementReadback: "not_surveyed",
|
|
555
|
+
exactUrl: isOceanpaymentSendPayUrl,
|
|
556
|
+
bodyGate: (url, body) => url !== void 0 && !isOceanpaymentSendPayUrl(url) ? Object.freeze({ verdict: "refuse", code: "oceanpayment_url_refused" }) : oceanpaymentBodyVerdict(body)
|
|
557
|
+
// No amount reader: the post names none, so the agent's pair is the figure the cardholder approves.
|
|
558
|
+
});
|
|
559
|
+
// src/processors/paymentwall.js
|
|
560
|
+
var PAYMENTWALL_PSP = "paymentwall";
|
|
561
|
+
var PAYMENTWALL_OPERATION = "paymentwall.card_request";
|
|
562
|
+
var PAYMENTWALL_TOKEN_URL = "https://pwgateway.com/api/token";
|
|
563
|
+
var PAYMENTWALL_SANDBOX_TOKEN_URL = "https://api.paymentwall.com/api/brick/token";
|
|
564
|
+
var BODY_LIMIT5 = 2048;
|
|
565
|
+
var KEY = "public_key";
|
|
566
|
+
var PUBLIC_KEY = /^(?:t_)?[A-Za-z0-9]{16,64}$/;
|
|
567
|
+
var SHAPES2 = /* @__PURE__ */ Object.freeze({
|
|
568
|
+
[KEY]: PUBLIC_KEY,
|
|
569
|
+
"card[number]": /^[0-9]{12,19}$/,
|
|
570
|
+
"card[exp_month]": /^(?:0?[1-9]|1[0-2])$/,
|
|
571
|
+
"card[exp_year]": /^(?:[0-9]{2}|20[0-9]{2})$/,
|
|
572
|
+
"card[cvv]": /^[0-9]{3,4}$/
|
|
573
|
+
});
|
|
574
|
+
var refuse4 = (code) => Object.freeze({ verdict: "refuse", code });
|
|
575
|
+
var CARD4 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
|
|
576
|
+
function luhn(digits2) {
|
|
577
|
+
let sum = 0;
|
|
578
|
+
for (let at = 0; at < digits2.length; at += 1) {
|
|
579
|
+
let digit = Number(digits2[digits2.length - 1 - at]);
|
|
580
|
+
if (at % 2 === 1) {
|
|
581
|
+
digit *= 2;
|
|
582
|
+
if (digit > 9)
|
|
583
|
+
digit -= 9;
|
|
584
|
+
}
|
|
585
|
+
sum += digit;
|
|
586
|
+
}
|
|
587
|
+
return sum % 10 === 0;
|
|
588
|
+
}
|
|
589
|
+
function paymentwallUrlEnvironment(url) {
|
|
590
|
+
if (url === PAYMENTWALL_TOKEN_URL)
|
|
591
|
+
return "production";
|
|
592
|
+
return url === PAYMENTWALL_SANDBOX_TOKEN_URL ? "sandbox" : null;
|
|
593
|
+
}
|
|
594
|
+
function isPaymentwallTokenUrl(url) {
|
|
595
|
+
return paymentwallUrlEnvironment(url) !== null;
|
|
596
|
+
}
|
|
597
|
+
function paymentwallKeyEnvironment(publicKey) {
|
|
598
|
+
if (typeof publicKey !== "string" || !PUBLIC_KEY.test(publicKey))
|
|
599
|
+
return null;
|
|
600
|
+
return publicKey.startsWith("t_") ? "sandbox" : "production";
|
|
601
|
+
}
|
|
602
|
+
function readPairs2(body) {
|
|
603
|
+
if (typeof body !== "string" || body === "" || body.length > BODY_LIMIT5 || !/^[A-Za-z0-9_[\]=&]+$/.test(body))
|
|
604
|
+
return null;
|
|
605
|
+
const pairs = /* @__PURE__ */ new Map();
|
|
606
|
+
for (const chunk of body.split("&")) {
|
|
607
|
+
const eq = chunk.indexOf("=");
|
|
608
|
+
if (eq <= 0 || chunk.indexOf("=", eq + 1) !== -1)
|
|
609
|
+
return null;
|
|
610
|
+
const key = chunk.slice(0, eq);
|
|
611
|
+
if (pairs.has(key))
|
|
612
|
+
return null;
|
|
613
|
+
pairs.set(key, chunk.slice(eq + 1));
|
|
614
|
+
}
|
|
615
|
+
return pairs;
|
|
616
|
+
}
|
|
617
|
+
function paymentwallBodyVerdict(body, url) {
|
|
618
|
+
if (url !== void 0 && !isPaymentwallTokenUrl(url))
|
|
619
|
+
return refuse4("paymentwall_url_refused");
|
|
620
|
+
const pairs = readPairs2(body);
|
|
621
|
+
if (pairs === null)
|
|
622
|
+
return refuse4("paymentwall_body_unsupported");
|
|
623
|
+
if (pairs.has("card[token]") && !pairs.has("card[number]"))
|
|
624
|
+
return refuse4("paymentwall_saved_card");
|
|
625
|
+
const keys = Object.keys(SHAPES2);
|
|
626
|
+
if (pairs.size !== keys.length || !keys.every((key) => pairs.has(key) && SHAPES2[key].test(pairs.get(key)))) {
|
|
627
|
+
return refuse4("paymentwall_body_unsupported");
|
|
628
|
+
}
|
|
629
|
+
if (!luhn(pairs.get("card[number]")))
|
|
630
|
+
return refuse4("paymentwall_body_unsupported");
|
|
631
|
+
if (url !== void 0 && paymentwallKeyEnvironment(pairs.get(KEY)) !== paymentwallUrlEnvironment(url))
|
|
632
|
+
return refuse4("paymentwall_key_refused");
|
|
633
|
+
return CARD4;
|
|
634
|
+
}
|
|
635
|
+
var paymentwall_default = /* @__PURE__ */ registerProcessor({
|
|
636
|
+
psp: PAYMENTWALL_PSP,
|
|
637
|
+
definitions: [
|
|
638
|
+
{
|
|
639
|
+
psp: "paymentwall",
|
|
640
|
+
// Brick's token request, as the header above reads it. A test key's request has its own host, so the device sends
|
|
641
|
+
// it only Paymentwall's documented test cards (hostEnvironmentPinned, device-replay.js S7). Ships dark: served only
|
|
642
|
+
// to a client that declares `paymentwall_card_token`, for a company the backend's gate turns it on for
|
|
643
|
+
// (checkout-processor-gate.ts), and the device sends a live card only under a key a reviewed pin names.
|
|
644
|
+
capability: "paymentwall_card_token",
|
|
645
|
+
match: "(?:pwgateway\\.com/api/token|api\\.paymentwall\\.com/api/brick/token)",
|
|
646
|
+
hosts: ["^pwgateway\\.com$", "^api\\.paymentwall\\.com$"],
|
|
647
|
+
sandboxHosts: ["^api\\.paymentwall\\.com$"],
|
|
648
|
+
hostEnvironmentPinned: true,
|
|
649
|
+
encoding: "form",
|
|
650
|
+
// Brick's XHR sets the form Content-Type alone, and that always rides. Origin, Referer and cookies never do.
|
|
651
|
+
passthroughHeaders: [],
|
|
652
|
+
cardFields: ["card[number]"]
|
|
653
|
+
}
|
|
654
|
+
],
|
|
655
|
+
// Only the cardholder's device sends a card request, after a person approves; no reviewed list names paymentwall.
|
|
656
|
+
refusedOperations: [PAYMENTWALL_OPERATION],
|
|
657
|
+
// Not surveyed: the token moves no money, and the charge that spends it happens out of this request.
|
|
658
|
+
settlementReadback: "not_surveyed",
|
|
659
|
+
exactUrl: isPaymentwallTokenUrl,
|
|
660
|
+
bodyGate: (url, body) => paymentwallBodyVerdict(body, url)
|
|
661
|
+
});
|
|
662
|
+
// src/processors/ekashu.js
|
|
663
|
+
var EKASHU_HOSTS = Object.freeze(["live.ekashu.com", "test.ekashu.com"]);
|
|
664
|
+
var EKASHU_TEST_PANS = Object.freeze(["4100000000000100", "5100000000000107"]);
|
|
665
|
+
var EKASHU_SIGNED_FIELDS = Object.freeze([
|
|
666
|
+
"ekashu_3d_secure_verify",
|
|
667
|
+
"ekashu_amount",
|
|
668
|
+
"ekashu_amount_format",
|
|
669
|
+
"ekashu_auto_confirm",
|
|
670
|
+
"ekashu_callback_failure_url",
|
|
671
|
+
"ekashu_callback_include_post",
|
|
672
|
+
"ekashu_callback_success_url",
|
|
673
|
+
"ekashu_card_address_editable",
|
|
674
|
+
"ekashu_card_address_required",
|
|
675
|
+
"ekashu_card_address_verify",
|
|
676
|
+
"ekashu_card_email_address_mandatory",
|
|
677
|
+
"ekashu_card_phone_number_mandatory",
|
|
678
|
+
"ekashu_card_title_mandatory",
|
|
679
|
+
"ekashu_card_zip_code_verify",
|
|
680
|
+
"ekashu_currency",
|
|
681
|
+
"ekashu_delivery_address_editable",
|
|
682
|
+
"ekashu_delivery_address_required",
|
|
683
|
+
"ekashu_delivery_email_address_mandatory",
|
|
684
|
+
"ekashu_delivery_phone_number_mandatory",
|
|
685
|
+
"ekashu_delivery_title_mandatory",
|
|
686
|
+
"ekashu_description",
|
|
687
|
+
"ekashu_device",
|
|
688
|
+
"ekashu_duplicate_check",
|
|
689
|
+
"ekashu_duplicate_minutes",
|
|
690
|
+
"ekashu_failure_return_text",
|
|
691
|
+
"ekashu_failure_url",
|
|
692
|
+
"ekashu_hash_code_format",
|
|
693
|
+
"ekashu_hash_code_type",
|
|
694
|
+
"ekashu_hash_code_version",
|
|
695
|
+
"ekashu_include_post",
|
|
696
|
+
"ekashu_invoice_address_editable",
|
|
697
|
+
"ekashu_invoice_address_required",
|
|
698
|
+
"ekashu_invoice_email_address_mandatory",
|
|
699
|
+
"ekashu_invoice_phone_number_mandatory",
|
|
700
|
+
"ekashu_invoice_title_mandatory",
|
|
701
|
+
"ekashu_locale",
|
|
702
|
+
"ekashu_payment_methods",
|
|
703
|
+
"ekashu_reference",
|
|
704
|
+
"ekashu_request_type",
|
|
705
|
+
"ekashu_return_text",
|
|
706
|
+
"ekashu_seller_address",
|
|
707
|
+
"ekashu_seller_email_address",
|
|
708
|
+
"ekashu_seller_id",
|
|
709
|
+
"ekashu_seller_key",
|
|
710
|
+
"ekashu_seller_name",
|
|
711
|
+
"ekashu_shortcut_icon",
|
|
712
|
+
"ekashu_style_sheet",
|
|
713
|
+
"ekashu_success_url",
|
|
714
|
+
"ekashu_title",
|
|
715
|
+
"ekashu_verification_value_mask",
|
|
716
|
+
"ekashu_verification_value_verify",
|
|
717
|
+
"ekashu_viewport"
|
|
718
|
+
]);
|
|
719
|
+
var REQUIRED = Object.freeze([
|
|
720
|
+
"ekashu_seller_id",
|
|
721
|
+
"ekashu_seller_key",
|
|
722
|
+
"ekashu_amount",
|
|
723
|
+
"ekashu_currency",
|
|
724
|
+
"ekashu_reference",
|
|
725
|
+
"ekashu_hash_code",
|
|
726
|
+
"ekashu_hash_code_type",
|
|
727
|
+
"ekashu_hash_code_version",
|
|
728
|
+
"ekashu_success_url",
|
|
729
|
+
"ekashu_failure_url",
|
|
730
|
+
"ekashu_callback_success_url"
|
|
731
|
+
]);
|
|
732
|
+
var CARD_KEYS = Object.freeze([
|
|
733
|
+
"ekashu_card_number",
|
|
734
|
+
"ekashu_expires_end_month",
|
|
735
|
+
"ekashu_expires_end_year",
|
|
736
|
+
"ekashu_verification_value",
|
|
737
|
+
"ekashu_valid_from_month",
|
|
738
|
+
"ekashu_valid_from_year",
|
|
739
|
+
"ekashu_issue_number"
|
|
740
|
+
]);
|
|
741
|
+
var PAGE_KEYS = Object.freeze(["ekashu_stage", "ekashu_context", "ekashu_submission_id"]);
|
|
742
|
+
var STORED_KEYS = Object.freeze(["ekashu_card_hash", "ekashu_card_reference", "ekashu_cof_initiated_by", "ekashu_cof_reason", "ekashu_cof_id"]);
|
|
743
|
+
var REDIRECT_KEYS = Object.freeze(["ekashu_success_url", "ekashu_failure_url", "ekashu_return_url"]);
|
|
744
|
+
var CALLBACK_KEYS = Object.freeze(["ekashu_callback_success_url", "ekashu_callback_failure_url"]);
|
|
745
|
+
var MAX_ENTRY = 16 * 1024;
|
|
746
|
+
var MAX_PAGE = 256 * 1024;
|
|
747
|
+
var EKASHU_SELLERS = Object.freeze([
|
|
748
|
+
Object.freeze({ sellerId: "25060100", merchant: "Heathrow Drop-off", entryHost: "heathrowdropoff.apcoa.com", callbackHost: "incomingapi.apcoa.co.uk" })
|
|
749
|
+
]);
|
|
750
|
+
var CARD_FIELDS = Object.freeze({
|
|
751
|
+
number: "ekashu_card_number",
|
|
752
|
+
month: "ekashu_expires_end_month",
|
|
753
|
+
year: "ekashu_expires_end_year",
|
|
754
|
+
cvc: "ekashu_verification_value"
|
|
755
|
+
});
|
|
756
|
+
var NAME_FIELDS = Object.freeze({ first: "ekashu_card_first_name", last: "ekashu_card_last_name" });
|
|
757
|
+
var LEFT_EMPTY = Object.freeze(["ekashu_card_title", "ekashu_valid_from_month", "ekashu_valid_from_year", "ekashu_issue_number"]);
|
|
758
|
+
var VISIBLE = /* @__PURE__ */ new Set([...Object.values(CARD_FIELDS), ...Object.values(NAME_FIELDS), ...LEFT_EMPTY]);
|
|
759
|
+
// src/processors/payplug.js
|
|
760
|
+
var PAYPLUG_PSP = "payplug";
|
|
761
|
+
var PAYPLUG_OPERATION = "payplug.hosted_sale";
|
|
762
|
+
var PAYPLUG_HOST = "secure.payplug.com";
|
|
763
|
+
var ENTRY_PATH = /^\/pay\/(?:(test)\/)?([A-Za-z0-9]{22})$/;
|
|
764
|
+
var MAX_URL = 256;
|
|
765
|
+
var field = (name, reason) => ({ ok: false, code: "hosted_form_field_refused", field: name, reason });
|
|
766
|
+
function payplugEntry(raw) {
|
|
767
|
+
if (typeof raw !== "string" || raw.length > MAX_URL || raw.includes("?") || raw.includes("#"))
|
|
768
|
+
return null;
|
|
769
|
+
let url;
|
|
770
|
+
try {
|
|
771
|
+
url = new URL(raw);
|
|
772
|
+
}
|
|
773
|
+
catch {
|
|
774
|
+
return null;
|
|
775
|
+
}
|
|
776
|
+
if (url.href !== raw || url.protocol !== "https:" || url.hostname !== PAYPLUG_HOST || url.port || url.username || url.password)
|
|
777
|
+
return null;
|
|
778
|
+
const match = ENTRY_PATH.exec(url.pathname);
|
|
779
|
+
return match ? Object.freeze({ id: match[2], test: match[1] === "test" }) : null;
|
|
780
|
+
}
|
|
781
|
+
function isPayplugEntryUrl(raw) {
|
|
782
|
+
return payplugEntry(raw) !== null;
|
|
783
|
+
}
|
|
784
|
+
var PAYPLUG_MERCHANTS = Object.freeze([
|
|
785
|
+
Object.freeze({ merchant: "Lazartigue", origins: Object.freeze(["https://lazartigue.com"]), payee: null, account: null })
|
|
786
|
+
]);
|
|
787
|
+
var ACCOUNT_ID = /^[A-Za-z0-9-]{1,64}$/;
|
|
788
|
+
function payplugMerchant(checkoutOrigin, merchants = PAYPLUG_MERCHANTS) {
|
|
789
|
+
if (typeof checkoutOrigin !== "string" || checkoutOrigin.length > MAX_URL || !Array.isArray(merchants))
|
|
790
|
+
return null;
|
|
791
|
+
let url;
|
|
792
|
+
try {
|
|
793
|
+
url = new URL(checkoutOrigin);
|
|
794
|
+
}
|
|
795
|
+
catch {
|
|
796
|
+
return null;
|
|
797
|
+
}
|
|
798
|
+
if (url.protocol !== "https:" || url.origin !== checkoutOrigin || url.port)
|
|
799
|
+
return null;
|
|
800
|
+
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));
|
|
801
|
+
return found.length === 1 ? found[0] : null;
|
|
802
|
+
}
|
|
803
|
+
function checkPayplugEntry(body, { url = null, checkoutOrigin = null, merchants = PAYPLUG_MERCHANTS } = {}) {
|
|
804
|
+
if (body !== void 0 && body !== null && body !== "")
|
|
805
|
+
return field("(body)", "not_an_entry");
|
|
806
|
+
const entry = payplugEntry(url);
|
|
807
|
+
if (!entry)
|
|
808
|
+
return field("(url)", "malformed_field");
|
|
809
|
+
const seller = payplugMerchant(checkoutOrigin, merchants);
|
|
810
|
+
if (!seller)
|
|
811
|
+
return field("(checkout_origin)", "seller_unreviewed");
|
|
812
|
+
return { ok: true, pairs: [], gated: false, dedupe: [entry.id], paymentId: entry.id, sandbox: entry.test, seller };
|
|
813
|
+
}
|
|
814
|
+
var MAX_PAGE2 = 512 * 1024;
|
|
815
|
+
var PAYPLUG_REFUSALS = Object.freeze(["payplug_failed", "payplug_expired", "payplug_cancelled"]);
|
|
816
|
+
var payplug_default = /* @__PURE__ */ registerProcessor({
|
|
817
|
+
psp: PAYPLUG_PSP,
|
|
818
|
+
definitions: [
|
|
819
|
+
{
|
|
820
|
+
psp: "payplug",
|
|
821
|
+
// The merchant's redirect to PayPlug's payment page, as the header above reads it: a Document navigation that
|
|
822
|
+
// carries no card. The cardholder's device repeats it over the end-to-end TLS relay and pays on the page PayPlug
|
|
823
|
+
// returns to it, and the runtime resolves the paused navigation with the hosted_form notice. Only the entry is
|
|
824
|
+
// matched (isPayplugEntryUrl): the page's card post and its 3-D Secure steps share the host, and none of them is
|
|
825
|
+
// the entry. Test and live payments share the host, and the entry's path says which it is. Ships dark: served
|
|
826
|
+
// only to a client that declares `payplug_hosted_payment_page`, and the backend's gate serves only Agentcard's
|
|
827
|
+
// own company until a reviewed merchant pays.
|
|
828
|
+
capability: "payplug_hosted_payment_page",
|
|
829
|
+
match: "secure\\.payplug\\.com/pay/(?:test/)?[A-Za-z0-9]{22}",
|
|
830
|
+
hosts: ["^secure\\.payplug\\.com$"],
|
|
831
|
+
// `encoding` describes the page's own card post, which the device makes as the page does, since the entry has no
|
|
832
|
+
// body. No captured header is ever replayed.
|
|
833
|
+
encoding: "form",
|
|
834
|
+
passthroughHeaders: [],
|
|
835
|
+
request: { method: "GET", cardIn: "none", response: "html_page" },
|
|
836
|
+
mode: "hosted_form",
|
|
837
|
+
hostedForm: {
|
|
838
|
+
// The card goes into PayPlug's page on the device, never into the entry, which carries no body at all. The
|
|
839
|
+
// entry's own rules come with this registration (hostedEntry below), so no policy is named here.
|
|
840
|
+
cardIn: "processor_page",
|
|
841
|
+
required: [],
|
|
842
|
+
// The page's card inputs, by the data-payplug role its script reads them by: they carry no name, and the
|
|
843
|
+
// script posts the card only as its ciphertext, encryptedCard.
|
|
844
|
+
card: { number: "card_number", expiry: "card_month_year", cvc: "card_cvv" },
|
|
845
|
+
// The payment's id in the entry's URL names the one payment the merchant created; the entry's rules read it
|
|
846
|
+
// there (checkPayplugEntry's dedupe), since no form field holds it.
|
|
847
|
+
dedupe: ["(paymentId)"]
|
|
848
|
+
}
|
|
849
|
+
}
|
|
850
|
+
],
|
|
851
|
+
// Only the cardholder's device repeats an entry, after a person approves; no reviewed list names payplug.
|
|
852
|
+
refusedOperations: [PAYPLUG_OPERATION],
|
|
853
|
+
// Not surveyed: PayPlug tells only the merchant's server the result, and the browser returns whatever it was.
|
|
854
|
+
settlementReadback: "not_surveyed",
|
|
855
|
+
exactUrl: isPayplugEntryUrl,
|
|
856
|
+
hostedEntry: checkPayplugEntry,
|
|
857
|
+
limitations: [
|
|
858
|
+
"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.",
|
|
859
|
+
"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.",
|
|
860
|
+
"PayPlug runs 3-D Secure on the card. A challenge ends the payment on the device with nothing charged.",
|
|
861
|
+
"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."
|
|
862
|
+
]
|
|
863
|
+
});
|
|
864
|
+
// src/processors/processout.js
|
|
865
|
+
var PROCESSOUT_PSP = "processout";
|
|
866
|
+
var PROCESSOUT_OPERATION = "processout.card_request";
|
|
867
|
+
var URL_LIMIT2 = 512;
|
|
868
|
+
var BODY_LIMIT6 = 4096;
|
|
869
|
+
var CARD_URL = /^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})$/;
|
|
870
|
+
var PAGE_KEYS2 = /* @__PURE__ */ Object.freeze(["name", "contact", "preferred_scheme"]);
|
|
871
|
+
var CONTACT_KEYS = /* @__PURE__ */ Object.freeze(["address1", "address2", "city", "state", "country_code", "zip"]);
|
|
872
|
+
var DEVICE_KEYS = /* @__PURE__ */ Object.freeze([
|
|
873
|
+
"request_origin",
|
|
874
|
+
"app_color_depth",
|
|
875
|
+
"app_language",
|
|
876
|
+
"app_screen_height",
|
|
877
|
+
"app_screen_width",
|
|
878
|
+
"app_timezone_offset",
|
|
879
|
+
"app_java_enabled"
|
|
880
|
+
]);
|
|
881
|
+
var PROCESSOUT_CARD_KEYS = /* @__PURE__ */ Object.freeze(["number", "exp_month", "exp_year", "cvc2"]);
|
|
882
|
+
var BODY_KEYS = /* @__PURE__ */ new Set([...PAGE_KEYS2, "device", ...DEVICE_KEYS, ...PROCESSOUT_CARD_KEYS]);
|
|
883
|
+
var NUMBER = /^[0-9]{12,19}$/;
|
|
884
|
+
var MONTH3 = /^(?:[1-9]|1[0-2])$/;
|
|
885
|
+
var YEAR3 = /^20[0-9]{2}$/;
|
|
886
|
+
var CODE = /^[0-9]{3,4}$/;
|
|
887
|
+
var TEXT_LIMIT = 256;
|
|
888
|
+
var SCHEME = /^[A-Za-z][A-Za-z0-9 _-]{0,31}$/;
|
|
889
|
+
var LANGUAGE2 = /^[A-Za-z]{1,8}(?:-[A-Za-z0-9]{1,8}){0,4}$/;
|
|
890
|
+
var PAN_LIKE = /(?:[0-9][^0-9A-Za-z]*){12,}/;
|
|
891
|
+
var record4 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
892
|
+
var own5 = (value, key) => Object.prototype.hasOwnProperty.call(value, key);
|
|
893
|
+
var refuse5 = (code) => Object.freeze({ verdict: "refuse", code });
|
|
894
|
+
var CARD5 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
|
|
895
|
+
var BASE64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
896
|
+
function base64Of(text2) {
|
|
897
|
+
let out = "";
|
|
898
|
+
for (let at = 0; at < text2.length; at += 3) {
|
|
899
|
+
const a = text2.charCodeAt(at);
|
|
900
|
+
const b = at + 1 < text2.length ? text2.charCodeAt(at + 1) : NaN;
|
|
901
|
+
const c = at + 2 < text2.length ? text2.charCodeAt(at + 2) : NaN;
|
|
902
|
+
out += BASE64[a >> 2] + BASE64[(a & 3) << 4 | (Number.isNaN(b) ? 0 : b >> 4)] + (Number.isNaN(b) ? "=" : BASE64[(b & 15) << 2 | (Number.isNaN(c) ? 0 : c >> 6)]) + (Number.isNaN(c) ? "=" : BASE64[c & 63]);
|
|
903
|
+
}
|
|
904
|
+
return out;
|
|
905
|
+
}
|
|
906
|
+
var basicOf = (projectId) => base64Of(`${projectId}:`);
|
|
907
|
+
function luhn2(digits2) {
|
|
908
|
+
let sum = 0;
|
|
909
|
+
for (let at = 0; at < digits2.length; at += 1) {
|
|
910
|
+
let digit = Number(digits2[digits2.length - 1 - at]);
|
|
911
|
+
if (at % 2 === 1) {
|
|
912
|
+
digit *= 2;
|
|
913
|
+
if (digit > 9)
|
|
914
|
+
digit -= 9;
|
|
915
|
+
}
|
|
916
|
+
sum += digit;
|
|
917
|
+
}
|
|
918
|
+
return sum % 10 === 0;
|
|
919
|
+
}
|
|
920
|
+
function processoutCardTarget(url) {
|
|
921
|
+
if (typeof url !== "string" || url.length > URL_LIMIT2)
|
|
922
|
+
return null;
|
|
923
|
+
const match = CARD_URL.exec(url);
|
|
924
|
+
if (!match || match[2] !== basicOf(match[1]))
|
|
925
|
+
return null;
|
|
926
|
+
return Object.freeze({ projectId: match[1], environment: match[1].startsWith("test-") ? "sandbox" : "production" });
|
|
927
|
+
}
|
|
928
|
+
function isProcessoutCardUrl(url) {
|
|
929
|
+
return processoutCardTarget(url) !== null;
|
|
930
|
+
}
|
|
931
|
+
function readBody4(body) {
|
|
932
|
+
if (typeof body !== "string" || body === "" || body.length > BODY_LIMIT6)
|
|
933
|
+
return null;
|
|
934
|
+
try {
|
|
935
|
+
const value = JSON.parse(body);
|
|
936
|
+
return record4(value) && JSON.stringify(value) === body ? value : null;
|
|
937
|
+
}
|
|
938
|
+
catch {
|
|
939
|
+
return null;
|
|
940
|
+
}
|
|
941
|
+
}
|
|
942
|
+
var pageText = (value) => value === null || typeof value === "string" && value.length <= TEXT_LIMIT && !PAN_LIKE.test(value);
|
|
943
|
+
var DEVICE_RULES = /* @__PURE__ */ Object.freeze({
|
|
944
|
+
request_origin: (value) => value === "web",
|
|
945
|
+
app_color_depth: (value) => Number.isSafeInteger(value) && value >= 1 && value <= 64,
|
|
946
|
+
app_language: (value) => typeof value === "string" && value.length <= 64 && LANGUAGE2.test(value),
|
|
947
|
+
app_screen_height: (value) => Number.isSafeInteger(value) && value >= 1 && value <= 1e5,
|
|
948
|
+
app_screen_width: (value) => Number.isSafeInteger(value) && value >= 1 && value <= 1e5,
|
|
949
|
+
app_timezone_offset: (value) => Number.isSafeInteger(value) && value >= -1440 && value <= 1440,
|
|
950
|
+
app_java_enabled: (value) => typeof value === "boolean"
|
|
951
|
+
});
|
|
952
|
+
function soundDevice(value) {
|
|
953
|
+
const device = value.device;
|
|
954
|
+
if (!record4(device) || !own5(device, "request_origin") || !own5(device, "app_timezone_offset"))
|
|
955
|
+
return false;
|
|
956
|
+
return DEVICE_KEYS.every((key) => own5(device, key) ? DEVICE_RULES[key](device[key]) && own5(value, key) && value[key] === device[key] : !own5(value, key)) && Object.keys(device).every((key) => DEVICE_KEYS.includes(key));
|
|
957
|
+
}
|
|
958
|
+
function soundPageData(value) {
|
|
959
|
+
if (own5(value, "name") && !pageText(value.name))
|
|
960
|
+
return false;
|
|
961
|
+
if (own5(value, "preferred_scheme") && !(value.preferred_scheme === null || typeof value.preferred_scheme === "string" && SCHEME.test(value.preferred_scheme)))
|
|
962
|
+
return false;
|
|
963
|
+
const contact = value.contact;
|
|
964
|
+
return record4(contact) && Object.keys(contact).every((key) => CONTACT_KEYS.includes(key) && pageText(contact[key]));
|
|
965
|
+
}
|
|
966
|
+
function processoutBodyVerdict(body, url) {
|
|
967
|
+
if (url !== void 0 && processoutCardTarget(url) === null)
|
|
968
|
+
return refuse5("processout_url_refused");
|
|
969
|
+
const value = readBody4(body);
|
|
970
|
+
if (value === null || !Object.keys(value).every((key) => BODY_KEYS.has(key)))
|
|
971
|
+
return refuse5("processout_body_unsupported");
|
|
972
|
+
if (!PROCESSOUT_CARD_KEYS.every((key) => typeof value[key] === "string"))
|
|
973
|
+
return refuse5("processout_body_unsupported");
|
|
974
|
+
if (!NUMBER.test(value.number) || !luhn2(value.number) || !MONTH3.test(value.exp_month) || !YEAR3.test(value.exp_year) || !CODE.test(value.cvc2))
|
|
975
|
+
return refuse5("processout_body_unsupported");
|
|
976
|
+
if (!soundPageData(value) || !soundDevice(value))
|
|
977
|
+
return refuse5("processout_body_unsupported");
|
|
978
|
+
return CARD5;
|
|
979
|
+
}
|
|
980
|
+
var processout_default = /* @__PURE__ */ registerProcessor({
|
|
981
|
+
psp: PROCESSOUT_PSP,
|
|
982
|
+
definitions: [
|
|
983
|
+
{
|
|
984
|
+
psp: "processout",
|
|
985
|
+
// ProcessOut.js's card request, as the header above reads it. One host serves every project, live and sandbox
|
|
986
|
+
// alike, so no sandbox host is marked: the project id names the environment, and the device sends a sandbox
|
|
987
|
+
// project only ProcessOut's documented test cards (processoutDeviceRefusal). The page gives up 20 seconds after
|
|
988
|
+
// its tokenize message, so the lane is prepared only (preparationRequired). The match reads the host and the path,
|
|
989
|
+
// and ends where the path does, as Pin Payments' does: a card's own record under /cards/, where the code refresh
|
|
990
|
+
// goes, is never paused. The exact-URL rule below holds the query, the project id and its Basic credential among it.
|
|
991
|
+
// Ships dark: served only to a client that declares `processout_card_token`, and gated off for every org until
|
|
992
|
+
// the backend's gate names one.
|
|
993
|
+
capability: "processout_card_token",
|
|
994
|
+
match: "api\\.processout\\.com/cards(?![\\w/.%-])",
|
|
995
|
+
hosts: ["^api\\.processout\\.com$"],
|
|
996
|
+
preparationRequired: true,
|
|
997
|
+
encoding: "json",
|
|
998
|
+
// ProcessOut.js's own headers: the project's Basic credential and the API version. Origin, Referer and cookies
|
|
999
|
+
// never ride.
|
|
1000
|
+
passthroughHeaders: ["^authorization$", "^api-version$"],
|
|
1001
|
+
jsonCardFields: [["number"]]
|
|
1002
|
+
}
|
|
1003
|
+
],
|
|
1004
|
+
// Only the cardholder's device sends a card, after a person approves; no reviewed list names processout.
|
|
1005
|
+
refusedOperations: [PROCESSOUT_OPERATION],
|
|
1006
|
+
// Not surveyed: the card request mints a token and moves no money; the store's server charges it under its own
|
|
1007
|
+
// secret key, which Agentcard never holds.
|
|
1008
|
+
settlementReadback: "not_surveyed",
|
|
1009
|
+
exactUrl: isProcessoutCardUrl,
|
|
1010
|
+
bodyGate: (url, body) => processoutBodyVerdict(body, url)
|
|
1011
|
+
});
|
|
1012
|
+
// src/processors/usaepay.js
|
|
1013
|
+
var USAEPAY_PSP = "usaepay";
|
|
1014
|
+
var USAEPAY_OPERATION = "usaepay.card_request";
|
|
1015
|
+
var USAEPAY_HOSTS = /* @__PURE__ */ Object.freeze({
|
|
1016
|
+
"www.usaepay.com": "production",
|
|
1017
|
+
"secure.usaepay.com": "production",
|
|
1018
|
+
"sandbox.usaepay.com": "sandbox"
|
|
1019
|
+
});
|
|
1020
|
+
var USAEPAY_PAYMENT_KEYS_PATH = "/api/v2/pub/payment_keys";
|
|
1021
|
+
var BODY_LIMIT7 = 512;
|
|
1022
|
+
var URL_LIMIT3 = 256;
|
|
1023
|
+
var CARD_NUMBER4 = /^[0-9]{13,19}$/;
|
|
1024
|
+
var EXPIRATION = /^(?:0[1-9]|1[0-2])[0-9]{2}$/;
|
|
1025
|
+
var SECURITY_CODE4 = /^(?:[0-9]{3,4})?$/;
|
|
1026
|
+
var record5 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
1027
|
+
var own6 = (value, key) => Object.prototype.hasOwnProperty.call(value, key);
|
|
1028
|
+
var refuse6 = (code) => Object.freeze({ verdict: "refuse", code });
|
|
1029
|
+
var CARD6 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
|
|
1030
|
+
function usaepayPaymentKeysUrl(url) {
|
|
1031
|
+
if (typeof url !== "string" || url.length > URL_LIMIT3 || url.includes("?") || url.includes("#"))
|
|
1032
|
+
return null;
|
|
1033
|
+
let parsed;
|
|
1034
|
+
try {
|
|
1035
|
+
parsed = new URL(url);
|
|
33
1036
|
}
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
problems2.push(`${psp}: names no definition`);
|
|
37
|
-
else if (spec.definitions.some((definition) => definition?.psp !== psp))
|
|
38
|
-
problems2.push(`${psp}: a definition names another processor`);
|
|
39
|
-
for (const id of spec.refusedOperations ?? []) {
|
|
40
|
-
if (typeof id !== "string" || !id.startsWith(`${psp}.`))
|
|
41
|
-
problems2.push(`${psp}: ${JSON.stringify(id)} is not one of its operations`);
|
|
42
|
-
}
|
|
1037
|
+
catch {
|
|
1038
|
+
return null;
|
|
43
1039
|
}
|
|
44
|
-
|
|
1040
|
+
if (parsed.href !== url || parsed.protocol !== "https:" || parsed.port || parsed.username || parsed.password || !own6(USAEPAY_HOSTS, parsed.hostname) || parsed.pathname !== USAEPAY_PAYMENT_KEYS_PATH)
|
|
1041
|
+
return null;
|
|
1042
|
+
return Object.freeze({ host: parsed.hostname, environment: USAEPAY_HOSTS[parsed.hostname] });
|
|
45
1043
|
}
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
1044
|
+
var isUsaepayPaymentKeysUrl = (url) => usaepayPaymentKeysUrl(url) !== null;
|
|
1045
|
+
function luhn3(digits2) {
|
|
1046
|
+
let sum = 0;
|
|
1047
|
+
for (let at = digits2.length - 1, double = false; at >= 0; at -= 1, double = !double) {
|
|
1048
|
+
let digit = digits2.charCodeAt(at) - 48;
|
|
1049
|
+
if (double)
|
|
1050
|
+
digit = digit * 2 > 9 ? digit * 2 - 9 : digit * 2;
|
|
1051
|
+
sum += digit;
|
|
1052
|
+
}
|
|
1053
|
+
return sum % 10 === 0;
|
|
51
1054
|
}
|
|
52
|
-
function
|
|
53
|
-
|
|
1055
|
+
function readBody5(body) {
|
|
1056
|
+
if (typeof body !== "string" || body === "" || body.length > BODY_LIMIT7)
|
|
1057
|
+
return null;
|
|
1058
|
+
try {
|
|
1059
|
+
const value = JSON.parse(body);
|
|
1060
|
+
return record5(value) && JSON.stringify(value) === body ? value : null;
|
|
1061
|
+
}
|
|
1062
|
+
catch {
|
|
1063
|
+
return null;
|
|
1064
|
+
}
|
|
54
1065
|
}
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
var
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
1066
|
+
function usaepayBodyVerdict(body) {
|
|
1067
|
+
const value = readBody5(body);
|
|
1068
|
+
const card = value === null ? null : value.creditcard;
|
|
1069
|
+
if (value === null || Object.keys(value).join() !== "creditcard" || !record5(card) || Object.keys(card).join() !== "number,expiration,cvc" || typeof card.number !== "string" || !CARD_NUMBER4.test(card.number) || !luhn3(card.number) || typeof card.expiration !== "string" || !EXPIRATION.test(card.expiration) || typeof card.cvc !== "string" || !SECURITY_CODE4.test(card.cvc))
|
|
1070
|
+
return refuse6("usaepay_body_unsupported");
|
|
1071
|
+
return CARD6;
|
|
1072
|
+
}
|
|
1073
|
+
var usaepay_default = /* @__PURE__ */ registerProcessor({
|
|
1074
|
+
psp: USAEPAY_PSP,
|
|
1075
|
+
definitions: [
|
|
1076
|
+
{
|
|
1077
|
+
psp: "usaepay",
|
|
1078
|
+
// The frame's card request, as the header above reads it. sandbox.usaepay.com is USAePay's sandbox, pinned to test
|
|
1079
|
+
// rows, which send only USAePay's documented test cards (hostEnvironmentPinned, device-replay.js S7).
|
|
1080
|
+
// Ships dark: served only to a client that declares `usaepay_payment_key`, and only for a company the backend's
|
|
1081
|
+
// processor gate turns USAePay on for. `(?![\w/.%-])` ends the path for a consumer that tests `match` unanchored.
|
|
1082
|
+
capability: "usaepay_payment_key",
|
|
1083
|
+
match: "(?:www|secure|sandbox)\\.usaepay\\.com/api/v2/pub/payment_keys(?![\\w/.%-])",
|
|
1084
|
+
hosts: ["^www\\.usaepay\\.com$", "^secure\\.usaepay\\.com$", "^sandbox\\.usaepay\\.com$"],
|
|
1085
|
+
sandboxHosts: ["^sandbox\\.usaepay\\.com$"],
|
|
1086
|
+
hostEnvironmentPinned: true,
|
|
1087
|
+
encoding: "json",
|
|
1088
|
+
// The frame's Authorization, which carries the merchant's public key. Origin, Referer and cookies never ride.
|
|
1089
|
+
passthroughHeaders: ["^authorization$"],
|
|
1090
|
+
jsonCardFields: [["creditcard", "number"]]
|
|
1091
|
+
}
|
|
1092
|
+
],
|
|
1093
|
+
// Only the cardholder's device sends this card, after a person approves; no reviewed list names usaepay.
|
|
1094
|
+
refusedOperations: [USAEPAY_OPERATION],
|
|
1095
|
+
// The public key mints a payment key and reads nothing: the merchant's server runs the sale with its private key.
|
|
1096
|
+
settlementReadback: {
|
|
1097
|
+
answer: "none",
|
|
1098
|
+
reason: "tokenization_credential_cannot_read_charges",
|
|
1099
|
+
note: "The tokenization credential cannot read a charge; the shop charges the token later with its own credentials.",
|
|
1100
|
+
source: "https://help.usaepay.info/developer/payjs-v2/ , https://help.usaepay.info/api/rest/"
|
|
1101
|
+
},
|
|
1102
|
+
exactUrl: isUsaepayPaymentKeysUrl,
|
|
1103
|
+
bodyGate: (url, body) => url !== void 0 && !isUsaepayPaymentKeysUrl(url) ? refuse6("usaepay_url_refused") : usaepayBodyVerdict(body)
|
|
1104
|
+
// No amount reader: the request names none, so the agent's pair is the figure the cardholder approves.
|
|
1105
|
+
});
|
|
1106
|
+
// src/processors/vtex_payments.js
|
|
1107
|
+
var VTEX_PAYMENTS_PSP = "vtex_payments";
|
|
1108
|
+
var VTEX_PAYMENTS_OPERATION = "vtex_payments.card_request";
|
|
1109
|
+
var VTEX_PAYMENTS_FALLBACK_HOST = "api.vtexvault.com";
|
|
1110
|
+
var VTEX_PAYMENTS_LINE_KEYS = /* @__PURE__ */ Object.freeze([
|
|
1111
|
+
"currencyCode",
|
|
1112
|
+
"paymentSystem",
|
|
1113
|
+
"accountId",
|
|
1114
|
+
"value",
|
|
1115
|
+
"referenceValue",
|
|
1116
|
+
"installments",
|
|
1117
|
+
"installmentsInterestRate",
|
|
1118
|
+
"installmentsValue",
|
|
1119
|
+
"groupName",
|
|
1120
|
+
"fields",
|
|
1121
|
+
"transaction",
|
|
1122
|
+
"id"
|
|
1123
|
+
]);
|
|
1124
|
+
var VTEX_PAYMENTS_FIELD_KEYS = /* @__PURE__ */ Object.freeze([
|
|
1125
|
+
"address",
|
|
1126
|
+
"accountId",
|
|
1127
|
+
"validationCode",
|
|
1128
|
+
"metadata",
|
|
1129
|
+
"document",
|
|
1130
|
+
"holderName",
|
|
1131
|
+
"cardNumber",
|
|
1132
|
+
"dueDate",
|
|
1133
|
+
"deviceFingerprint",
|
|
1134
|
+
"addressId"
|
|
1135
|
+
]);
|
|
1136
|
+
var VTEX_PAYMENTS_ADDRESS_KEYS = /* @__PURE__ */ Object.freeze([
|
|
1137
|
+
"street",
|
|
1138
|
+
"complement",
|
|
1139
|
+
"number",
|
|
1140
|
+
"city",
|
|
1141
|
+
"reference",
|
|
1142
|
+
"addressType",
|
|
1143
|
+
"neighborhood",
|
|
1144
|
+
"addressId",
|
|
1145
|
+
"state",
|
|
1146
|
+
"country",
|
|
1147
|
+
"postalCode"
|
|
1148
|
+
]);
|
|
1149
|
+
var VTEX_PAYMENTS_NETWORKS = /* @__PURE__ */ Object.freeze({ 1: "amex", 2: "visa", 4: "mastercard", 5: "discover" });
|
|
1150
|
+
var VTEX_PAYMENTS_MERCHANT_PINS = /* @__PURE__ */ Object.freeze([
|
|
1151
|
+
Object.freeze({ account: "alssports", origin: "https://www.als.com", merchant: "Al's Sporting Goods", currency: "USD" }),
|
|
1152
|
+
Object.freeze({ account: "roadrunnersports", origin: "https://www.roadrunnersports.com", merchant: "Road Runner Sports", currency: "USD" })
|
|
1153
|
+
]);
|
|
1154
|
+
var BODY_LIMIT8 = 16384;
|
|
1155
|
+
var ACCOUNT_HOST = /^([a-z0-9]{1,63})\.vtexvault\.com$/;
|
|
1156
|
+
var PATH = /^\/api\/payments\/transactions\/([0-9A-Fa-f]{32})\/payments$/;
|
|
1157
|
+
var ORDER_GROUP = /^[0-9]{6,24}$/;
|
|
1158
|
+
var BASE642 = /^[A-Za-z0-9+/]{4,1020}={0,2}$/;
|
|
1159
|
+
var CARD_NUMBER5 = /^[0-9]{12,19}$/;
|
|
1160
|
+
var SECURITY_CODE5 = /^[0-9]{3,4}$/;
|
|
1161
|
+
var DUE_DATE = /^(?:0[1-9]|1[0-2])\/[0-9]{2}$/;
|
|
1162
|
+
var CURRENCY = /^[A-Z]{3}$/;
|
|
1163
|
+
var TRANSACTION_ID = /^[0-9A-Fa-f]{32}$/;
|
|
1164
|
+
var MERCHANT_NAME = /^[A-Za-z0-9_.-]{1,64}$/;
|
|
1165
|
+
var SHORT_ID = /^[A-Za-z0-9_-]{1,64}$/;
|
|
1166
|
+
var FINGERPRINT = /^[A-Za-z0-9_.:=+/-]{1,256}$/;
|
|
1167
|
+
var TEXT = /^[^\u0000-\u001f\u007f]{1,200}$/;
|
|
1168
|
+
var CARD_DIGITS = /[0-9]{12,}/;
|
|
1169
|
+
var DEVICE_INFO_KEYS = Object.freeze(["sw", "sh", "cd", "tz", "lang", "java", "sourceApplication"]);
|
|
1170
|
+
var record6 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
1171
|
+
var own7 = (value, key) => Object.prototype.hasOwnProperty.call(value, key);
|
|
1172
|
+
var refuse7 = (code) => Object.freeze({ verdict: "refuse", code });
|
|
1173
|
+
var CARD7 = /* @__PURE__ */ Object.freeze({ verdict: "card" });
|
|
1174
|
+
var inOrder3 = (value, keys) => {
|
|
70
1175
|
let at = 0;
|
|
71
1176
|
for (const name of Object.keys(value)) {
|
|
72
1177
|
while (at < keys.length && keys[at] !== name)
|
|
@@ -77,18 +1182,108 @@ var inOrder = (value, keys) => {
|
|
|
77
1182
|
}
|
|
78
1183
|
return true;
|
|
79
1184
|
};
|
|
80
|
-
var
|
|
81
|
-
var
|
|
82
|
-
|
|
83
|
-
|
|
1185
|
+
var cardDigits = (text2) => CARD_DIGITS.test(text2.replace(/[^0-9A-Za-z]/g, ""));
|
|
1186
|
+
var plainText = (value) => typeof value === "string" && TEXT.test(value) && !cardDigits(value);
|
|
1187
|
+
var count = (value) => Number.isSafeInteger(value) && value >= 0;
|
|
1188
|
+
var BASE64_ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
1189
|
+
function base64Text(input) {
|
|
1190
|
+
if (input.length % 4 !== 0)
|
|
1191
|
+
return null;
|
|
1192
|
+
const stripped = input.replace(/={1,2}$/, "");
|
|
1193
|
+
let out = "";
|
|
1194
|
+
let bits = 0;
|
|
1195
|
+
let value = 0;
|
|
1196
|
+
for (const character of stripped) {
|
|
1197
|
+
const sextet = BASE64_ALPHABET.indexOf(character);
|
|
1198
|
+
if (sextet < 0)
|
|
1199
|
+
return null;
|
|
1200
|
+
value = value << 6 | sextet;
|
|
1201
|
+
bits += 6;
|
|
1202
|
+
if (bits >= 8) {
|
|
1203
|
+
bits -= 8;
|
|
1204
|
+
out += String.fromCharCode(value >> bits & 255);
|
|
1205
|
+
value &= (1 << bits) - 1;
|
|
1206
|
+
}
|
|
1207
|
+
}
|
|
1208
|
+
return out;
|
|
84
1209
|
}
|
|
85
|
-
function
|
|
86
|
-
if (typeof
|
|
1210
|
+
function deviceInfoSound(text2) {
|
|
1211
|
+
if (typeof text2 !== "string" || !BASE642.test(text2))
|
|
1212
|
+
return false;
|
|
1213
|
+
const decoded = base64Text(text2);
|
|
1214
|
+
if (decoded === null)
|
|
1215
|
+
return false;
|
|
1216
|
+
let info;
|
|
1217
|
+
try {
|
|
1218
|
+
info = JSON.parse(decoded);
|
|
1219
|
+
}
|
|
1220
|
+
catch {
|
|
1221
|
+
return false;
|
|
1222
|
+
}
|
|
1223
|
+
if (!record6(info) || !Object.keys(info).every((key) => DEVICE_INFO_KEYS.includes(key)))
|
|
1224
|
+
return false;
|
|
1225
|
+
for (const key of ["sw", "sh", "cd"])
|
|
1226
|
+
if (own7(info, key) && !(count(info[key]) && info[key] <= 1e5))
|
|
1227
|
+
return false;
|
|
1228
|
+
if (own7(info, "tz") && !(Number.isSafeInteger(info.tz) && Math.abs(info.tz) <= 1440))
|
|
1229
|
+
return false;
|
|
1230
|
+
if (own7(info, "lang") && !(typeof info.lang === "string" && /^[A-Za-z]{0,8}$/.test(info.lang)))
|
|
1231
|
+
return false;
|
|
1232
|
+
if (own7(info, "java") && typeof info.java !== "boolean")
|
|
1233
|
+
return false;
|
|
1234
|
+
return !own7(info, "sourceApplication") || typeof info.sourceApplication === "string" && /^[A-Za-z0-9_.-]{1,32}$/.test(info.sourceApplication);
|
|
1235
|
+
}
|
|
1236
|
+
function vtexPaymentsCardTarget(url) {
|
|
1237
|
+
if (typeof url !== "string" || url.length > 8192)
|
|
1238
|
+
return null;
|
|
1239
|
+
let parsed;
|
|
1240
|
+
try {
|
|
1241
|
+
parsed = new URL(url);
|
|
1242
|
+
}
|
|
1243
|
+
catch {
|
|
1244
|
+
return null;
|
|
1245
|
+
}
|
|
1246
|
+
if (parsed.href !== url || parsed.protocol !== "https:" || parsed.port || parsed.username || parsed.password || parsed.hash)
|
|
1247
|
+
return null;
|
|
1248
|
+
const path = PATH.exec(parsed.pathname);
|
|
1249
|
+
const host = ACCOUNT_HOST.exec(parsed.hostname);
|
|
1250
|
+
if (!path || !host)
|
|
1251
|
+
return null;
|
|
1252
|
+
const fallback = parsed.hostname === VTEX_PAYMENTS_FALLBACK_HOST;
|
|
1253
|
+
const names = [...parsed.searchParams.keys()];
|
|
1254
|
+
const expected = ["orderId", "deviceInfo", ...parsed.searchParams.has("callbackUrl") ? ["callbackUrl"] : [], ...fallback ? ["an"] : []];
|
|
1255
|
+
if (names.length !== expected.length || names.some((name, i) => name !== expected[i]))
|
|
1256
|
+
return null;
|
|
1257
|
+
const orderId = parsed.searchParams.get("orderId");
|
|
1258
|
+
if (!ORDER_GROUP.test(orderId) || !deviceInfoSound(parsed.searchParams.get("deviceInfo")))
|
|
1259
|
+
return null;
|
|
1260
|
+
if (parsed.searchParams.has("callbackUrl")) {
|
|
1261
|
+
let callback;
|
|
1262
|
+
try {
|
|
1263
|
+
callback = new URL(parsed.searchParams.get("callbackUrl"));
|
|
1264
|
+
}
|
|
1265
|
+
catch {
|
|
1266
|
+
return null;
|
|
1267
|
+
}
|
|
1268
|
+
if (callback.protocol !== "https:" || callback.username || callback.password || callback.searchParams.get("step") !== "payment" || callback.searchParams.get("og") !== orderId)
|
|
1269
|
+
return null;
|
|
1270
|
+
}
|
|
1271
|
+
const account = fallback ? parsed.searchParams.get("an") : host[1];
|
|
1272
|
+
if (!/^[a-z0-9]{1,63}$/.test(account) || account === "api")
|
|
1273
|
+
return null;
|
|
1274
|
+
return Object.freeze({ account, transactionId: path[1], orderId, fallback });
|
|
1275
|
+
}
|
|
1276
|
+
function isVtexPaymentsCardUrl(url) {
|
|
1277
|
+
const target = vtexPaymentsCardTarget(url);
|
|
1278
|
+
return target !== null && !target.fallback;
|
|
1279
|
+
}
|
|
1280
|
+
function readBody6(body) {
|
|
1281
|
+
if (typeof body !== "string" || body === "" || body.length > BODY_LIMIT8)
|
|
87
1282
|
return null;
|
|
88
1283
|
let value;
|
|
89
1284
|
try {
|
|
90
1285
|
value = JSON.parse(body);
|
|
91
|
-
if (!
|
|
1286
|
+
if (!Array.isArray(value) || JSON.stringify(value) !== body)
|
|
92
1287
|
return null;
|
|
93
1288
|
}
|
|
94
1289
|
catch {
|
|
@@ -96,54 +1291,136 @@ function readBody(body) {
|
|
|
96
1291
|
}
|
|
97
1292
|
return value;
|
|
98
1293
|
}
|
|
99
|
-
function
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
if (!
|
|
107
|
-
return
|
|
1294
|
+
function cardLine(line) {
|
|
1295
|
+
if (!record6(line))
|
|
1296
|
+
return false;
|
|
1297
|
+
const fields = record6(line.fields) ? line.fields : {};
|
|
1298
|
+
return line.groupName === "creditCardPaymentGroup" || line.groupName === "debitCardPaymentGroup" || own7(line, "accountId") || own7(fields, "accountId") || own7(fields, "cardNumber") || own7(fields, "validationCode") || own7(fields, "dueDate");
|
|
1299
|
+
}
|
|
1300
|
+
function addressSound(address) {
|
|
1301
|
+
if (!record6(address) || !inOrder3(address, VTEX_PAYMENTS_ADDRESS_KEYS))
|
|
1302
|
+
return false;
|
|
1303
|
+
for (const [key, value] of Object.entries(address)) {
|
|
1304
|
+
if (key === "addressType") {
|
|
1305
|
+
if (value !== "billing")
|
|
1306
|
+
return false;
|
|
1307
|
+
continue;
|
|
1308
|
+
}
|
|
1309
|
+
if (key === "addressId") {
|
|
1310
|
+
if (!(typeof value === "string" && SHORT_ID.test(value)))
|
|
1311
|
+
return false;
|
|
1312
|
+
continue;
|
|
1313
|
+
}
|
|
1314
|
+
if (value === null && (key === "complement" || key === "reference"))
|
|
1315
|
+
continue;
|
|
1316
|
+
if (!(value === "" || plainText(value)))
|
|
1317
|
+
return false;
|
|
108
1318
|
}
|
|
109
|
-
|
|
110
|
-
return refuse("midtrans_body_unsupported");
|
|
111
|
-
if (own(value, "installment_term") && (typeof value.installment_term !== "string" || !TERM.test(value.installment_term)))
|
|
112
|
-
return refuse("midtrans_body_unsupported");
|
|
113
|
-
return CARD;
|
|
1319
|
+
return true;
|
|
114
1320
|
}
|
|
115
|
-
|
|
116
|
-
|
|
1321
|
+
function fieldsSound(fields) {
|
|
1322
|
+
if (!record6(fields) || !inOrder3(fields, VTEX_PAYMENTS_FIELD_KEYS) || own7(fields, "metadata"))
|
|
1323
|
+
return false;
|
|
1324
|
+
if (!(typeof fields.cardNumber === "string" && CARD_NUMBER5.test(fields.cardNumber)))
|
|
1325
|
+
return false;
|
|
1326
|
+
if (!(typeof fields.validationCode === "string" && SECURITY_CODE5.test(fields.validationCode)))
|
|
1327
|
+
return false;
|
|
1328
|
+
if (!(typeof fields.dueDate === "string" && DUE_DATE.test(fields.dueDate)))
|
|
1329
|
+
return false;
|
|
1330
|
+
if (!plainText(fields.holderName))
|
|
1331
|
+
return false;
|
|
1332
|
+
if (own7(fields, "document") && !(fields.document === "" || plainText(fields.document) && fields.document.length <= 32))
|
|
1333
|
+
return false;
|
|
1334
|
+
if (own7(fields, "address") && !addressSound(fields.address))
|
|
1335
|
+
return false;
|
|
1336
|
+
if (own7(fields, "deviceFingerprint") && !(typeof fields.deviceFingerprint === "string" && FINGERPRINT.test(fields.deviceFingerprint)))
|
|
1337
|
+
return false;
|
|
1338
|
+
return !own7(fields, "addressId") || typeof fields.addressId === "string" && SHORT_ID.test(fields.addressId);
|
|
1339
|
+
}
|
|
1340
|
+
function vtexPaymentsBodyVerdict(body, target) {
|
|
1341
|
+
const lines = readBody6(body);
|
|
1342
|
+
if (lines === null || lines.length === 0 || !lines.every(record6))
|
|
1343
|
+
return refuse7("vtex_payments_body_unsupported");
|
|
1344
|
+
const cards = lines.filter(cardLine);
|
|
1345
|
+
if (cards.some((line2) => own7(line2, "accountId") || own7(line2.fields ?? {}, "accountId")))
|
|
1346
|
+
return refuse7("vtex_payments_saved_card");
|
|
1347
|
+
if (cards.length === 0)
|
|
1348
|
+
return refuse7("vtex_payments_body_unsupported");
|
|
1349
|
+
if (lines.length !== 1 || own7(lines[0], "id"))
|
|
1350
|
+
return refuse7("vtex_payments_split_payment");
|
|
1351
|
+
const line = lines[0];
|
|
1352
|
+
if (!inOrder3(line, VTEX_PAYMENTS_LINE_KEYS) || line.groupName !== "creditCardPaymentGroup")
|
|
1353
|
+
return refuse7("vtex_payments_body_unsupported");
|
|
1354
|
+
if (!(typeof line.currencyCode === "string" && CURRENCY.test(line.currencyCode)) || !own7(VTEX_PAYMENTS_NETWORKS, line.paymentSystem) || !Number.isSafeInteger(line.paymentSystem) || !(count(line.value) && line.value > 0))
|
|
1355
|
+
return refuse7("vtex_payments_body_unsupported");
|
|
1356
|
+
if (line.installments !== 1 || line.referenceValue !== line.value || own7(line, "installmentsInterestRate") && line.installmentsInterestRate !== 0 || own7(line, "installmentsValue") && line.installmentsValue !== line.value)
|
|
1357
|
+
return refuse7("vtex_payments_installments");
|
|
1358
|
+
const transaction = line.transaction;
|
|
1359
|
+
if (!record6(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)))
|
|
1360
|
+
return refuse7("vtex_payments_body_unsupported");
|
|
1361
|
+
if (target && transaction.id.toUpperCase() !== target.transactionId.toUpperCase())
|
|
1362
|
+
return refuse7("vtex_payments_split_payment");
|
|
1363
|
+
return fieldsSound(line.fields) ? CARD7 : refuse7("vtex_payments_body_unsupported");
|
|
1364
|
+
}
|
|
1365
|
+
function vtexPaymentsAmount(body) {
|
|
1366
|
+
if (vtexPaymentsBodyVerdict(body).verdict !== "card")
|
|
1367
|
+
return null;
|
|
1368
|
+
const [line] = JSON.parse(body);
|
|
1369
|
+
return { amountCents: line.value, currency: line.currencyCode.toLowerCase() };
|
|
1370
|
+
}
|
|
1371
|
+
var NETWORK_OF = Object.freeze({
|
|
1372
|
+
visa: (number) => /^4[0-9]{12}(?:[0-9]{3}){0,2}$/.test(number),
|
|
1373
|
+
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),
|
|
1374
|
+
amex: (number) => /^3[47][0-9]{13}$/.test(number),
|
|
1375
|
+
discover: (number) => /^(?:6011[0-9]{12}|64[4-9][0-9]{13}|65[0-9]{14})$/.test(number)
|
|
1376
|
+
});
|
|
1377
|
+
var NETWORK_NAME = Object.freeze({ visa: "Visa", mastercard: "Mastercard", amex: "American Express", discover: "Discover" });
|
|
1378
|
+
var vtex_payments_default = /* @__PURE__ */ registerProcessor({
|
|
1379
|
+
psp: VTEX_PAYMENTS_PSP,
|
|
117
1380
|
definitions: [
|
|
118
1381
|
{
|
|
119
|
-
psp: "
|
|
120
|
-
//
|
|
121
|
-
//
|
|
122
|
-
//
|
|
123
|
-
//
|
|
124
|
-
//
|
|
125
|
-
capability: "
|
|
126
|
-
match: "
|
|
127
|
-
hosts: ["^
|
|
128
|
-
|
|
129
|
-
hostEnvironmentPinned: true,
|
|
1382
|
+
psp: "vtex_payments",
|
|
1383
|
+
// Ollie's card post to a VTEX account's own vault, as the header above reads it, and the fallback host, which
|
|
1384
|
+
// the gate recognizes only to refuse, so the agent's placeholder never reaches it either. VTEX has no test host:
|
|
1385
|
+
// every request is live. Prepared only: Ollie gives the post 12 seconds. Ships dark: served only to a client that
|
|
1386
|
+
// declares `vtex_payments_card_payment`, on for Agentcard's own company alone (backend
|
|
1387
|
+
// checkout-processor-gate.ts), and autopilot never sends it.
|
|
1388
|
+
capability: "vtex_payments_card_payment",
|
|
1389
|
+
match: "[a-z0-9-]{1,63}\\.vtexvault\\.com/api/payments/transactions/[A-Za-z0-9-]{1,64}/payments(?![\\w/.%-])",
|
|
1390
|
+
hosts: ["^[a-z0-9-]{1,63}\\.vtexvault\\.com$"],
|
|
1391
|
+
preparationRequired: true,
|
|
130
1392
|
encoding: "json",
|
|
131
|
-
//
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
jsonCardFields: [["card_number"]]
|
|
1393
|
+
// Ollie's fetch sets the JSON content type alone. Origin, Referer and cookies never ride.
|
|
1394
|
+
passthroughHeaders: [],
|
|
1395
|
+
jsonCardFields: [[0, "fields", "cardNumber"]]
|
|
135
1396
|
}
|
|
136
1397
|
],
|
|
137
|
-
// Only the cardholder's device sends
|
|
138
|
-
refusedOperations: [
|
|
139
|
-
// Not surveyed:
|
|
1398
|
+
// Only the cardholder's device sends it, after a person approves; no reviewed list names vtex_payments.
|
|
1399
|
+
refusedOperations: [VTEX_PAYMENTS_OPERATION],
|
|
1400
|
+
// Not surveyed: VTEX names a payment's end only to the store's own API keys and at the gatewayCallback that follows.
|
|
140
1401
|
settlementReadback: "not_surveyed",
|
|
141
|
-
exactUrl:
|
|
142
|
-
bodyGate: (url, body) =>
|
|
1402
|
+
exactUrl: isVtexPaymentsCardUrl,
|
|
1403
|
+
bodyGate: (url, body) => {
|
|
1404
|
+
if (url === void 0)
|
|
1405
|
+
return vtexPaymentsBodyVerdict(body);
|
|
1406
|
+
const target = vtexPaymentsCardTarget(url);
|
|
1407
|
+
if (target === null)
|
|
1408
|
+
return refuse7("vtex_payments_url_refused");
|
|
1409
|
+
return target.fallback ? refuse7("vtex_payments_fallback_refused") : vtexPaymentsBodyVerdict(body, target);
|
|
1410
|
+
},
|
|
1411
|
+
amount: (template) => record6(template) && isVtexPaymentsCardUrl(template.url) ? vtexPaymentsAmount(template.body) : null
|
|
143
1412
|
});
|
|
144
1413
|
// src/processors/index.generated.js
|
|
145
1414
|
var REGISTERED_MODULES = Object.freeze({
|
|
146
|
-
|
|
1415
|
+
bluesnap: bluesnap_default,
|
|
1416
|
+
iyzico: iyzico_default,
|
|
1417
|
+
midtrans: midtrans_default,
|
|
1418
|
+
oceanpayment: oceanpayment_default,
|
|
1419
|
+
paymentwall: paymentwall_default,
|
|
1420
|
+
payplug: payplug_default,
|
|
1421
|
+
processout: processout_default,
|
|
1422
|
+
usaepay: usaepay_default,
|
|
1423
|
+
vtex_payments: vtex_payments_default
|
|
147
1424
|
});
|
|
148
1425
|
// src/registry.js
|
|
149
1426
|
var REGISTERED_PROCESSORS = Object.values(REGISTERED_MODULES);
|
|
@@ -964,15 +2241,6 @@ var PROCESSOR_DEFINITIONS = deepFreeze([
|
|
|
964
2241
|
jsonCardFields: [["paymentOption", "card", "cardNumber"], ["cardData", "cardNumber"]],
|
|
965
2242
|
passWithoutCard: "(?:secure|ppp-test)\\.safecharge\\.com/ppp/api/v1/(?:clientPayment|websdk/initPaymentWithCardTokenization)\\.do"
|
|
966
2243
|
},
|
|
967
|
-
// bluesnap: DELIBERATELY NOT SHIPPED — it cannot be intercepted at all. Its tokenizer is a PUT, and isCardRequest
|
|
968
|
-
// gates on POST — but accepting PUT is not enough on its own. hpf.js fires the
|
|
969
|
-
// same token PUT SEVERAL TIMES per checkout (blur and submit each send a delta
|
|
970
|
-
// body), so intercepting it would raise one approval prompt per fire and hand the
|
|
971
|
-
// device partial card data. An entry that cannot actually be intercepted does not
|
|
972
|
-
// belong in an allowlist that advertises interception: it reads as support we do
|
|
973
|
-
// not have, and on the CDP path it arms Fetch.enable, gets refused by the POST
|
|
974
|
-
// gate, and is then continued straight to the PSP while the integrator believes
|
|
975
|
-
// the card was protected. Ship it when the multi-fire semantics are handled.
|
|
976
2244
|
{
|
|
977
2245
|
psp: "airwallex",
|
|
978
2246
|
// PAN@ payment_method.card.number (payment_intents/confirm,
|
|
@@ -3173,7 +4441,7 @@ var PADDLE_VGS_MERCHANT_PINS = /* @__PURE__ */ Object.freeze([
|
|
|
3173
4441
|
pin2({ id: "rectangle_pro", merchant: "Rectangle Pro", origins: ["https://rectangleapp.com"], sellerClaim: null })
|
|
3174
4442
|
]);
|
|
3175
4443
|
var FACT_KEYS = /* @__PURE__ */ Object.freeze(["card_first_six", "card_last_four", "expiry_month", "expiry_year", "card_brand"]);
|
|
3176
|
-
var
|
|
4444
|
+
var METADATA_KEYS2 = /* @__PURE__ */ Object.freeze(["cardholder_name", ...FACT_KEYS]);
|
|
3177
4445
|
// src/payfast.js
|
|
3178
4446
|
var PAYFAST_PAY_HOSTS = /* @__PURE__ */ Object.freeze({
|
|
3179
4447
|
production: Object.freeze(["payment.payfast.io", "www.payfast.co.za"]),
|
|
@@ -3208,7 +4476,7 @@ var PADDLE_TOKENEX_KEYS = /* @__PURE__ */ Object.freeze({
|
|
|
3208
4476
|
});
|
|
3209
4477
|
// src/paddle-tokenex.js
|
|
3210
4478
|
var PADDLE_TOKENEX_FACT_KEYS = /* @__PURE__ */ Object.freeze(["card_first_six", "card_last_four", "expiry_month", "expiry_year", "card_brand"]);
|
|
3211
|
-
var
|
|
4479
|
+
var METADATA_KEYS3 = /* @__PURE__ */ Object.freeze(["cardholder_name", ...PADDLE_TOKENEX_FACT_KEYS]);
|
|
3212
4480
|
var CARD_PATH = /* @__PURE__ */ Object.freeze(["data", "payment_method_data", "card"]);
|
|
3213
4481
|
var TOKENEX_PATH = /* @__PURE__ */ Object.freeze([...CARD_PATH, "tokenex_card"]);
|
|
3214
4482
|
// src/lyra.js
|
|
@@ -3297,7 +4565,7 @@ var HIPAY_MERCHANT_PINS = /* @__PURE__ */ Object.freeze([
|
|
|
3297
4565
|
pin6({ id: "happybulle", merchant: "HappyBulle", origins: ["https://www.happybulle.com"], usernames: ["94683309.secure-gateway.hipay-tpp.com"] })
|
|
3298
4566
|
]);
|
|
3299
4567
|
// src/amazon-payment-services.js
|
|
3300
|
-
var
|
|
4568
|
+
var BODY_LIMIT9 = 32 * 1024;
|
|
3301
4569
|
var ANSWER_LIMIT = 64 * 1024;
|
|
3302
4570
|
// src/clover.js
|
|
3303
4571
|
var REQUIRED_KEYS = /* @__PURE__ */ Object.freeze(["encrypted_pan", "exp_month", "exp_year", "cvv", "first6", "last4", "brand"]);
|
|
@@ -3308,8 +4576,8 @@ var LETTERS = "A-Za-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u017F";
|
|
|
3308
4576
|
var PAGE_NAME = new RegExp(`^[${LETTERS} .'-]{1,64}$`);
|
|
3309
4577
|
var HAS_LETTER = new RegExp(`[${LETTERS}]`);
|
|
3310
4578
|
var ADDRESS_VALUE = new RegExp(`^[\\x20-\\x7e\\u00a0-\\u017f]{0,128}$`);
|
|
3311
|
-
var
|
|
3312
|
-
var
|
|
4579
|
+
var PAN_LIKE2 = new RegExp(`(?:[0-9][^0-9${LETTERS}]*){12,}`);
|
|
4580
|
+
var HOLDER2 = new RegExp(`^[${LETTERS}](?:[${LETTERS} .'-]{0,62}[${LETTERS}.])?$`);
|
|
3313
4581
|
var ERROR_TYPE_STATUS = /* @__PURE__ */ Object.freeze({
|
|
3314
4582
|
malformed_request_error: 400,
|
|
3315
4583
|
authentication_error: 401,
|
|
@@ -3354,7 +4622,7 @@ var TOKENEX_IFRAME_ACCOUNT_NAMES = Object.freeze({
|
|
|
3354
4622
|
"htp.tokenex.com": Object.freeze({ "9014311640612780": "JetBlue" }),
|
|
3355
4623
|
"test-htp.tokenex.com": Object.freeze({})
|
|
3356
4624
|
});
|
|
3357
|
-
var
|
|
4625
|
+
var exact2 = (pattern, value) => typeof value === "string" && pattern.exec(value)?.[0] === value;
|
|
3358
4626
|
var text = (value, max) => typeof value === "string" && value.length <= max && !/[\u0000-\u001f\u007f]/.test(value);
|
|
3359
4627
|
var digits = (value, min, max) => typeof value === "string" && value.length >= min && value.length <= max && !/[^0-9]/.test(value);
|
|
3360
4628
|
var panLike = (value) => (value.match(/\p{Nd}/gu) ?? []).length >= 12;
|
|
@@ -3373,10 +4641,10 @@ function isOrigin(value) {
|
|
|
3373
4641
|
}
|
|
3374
4642
|
}
|
|
3375
4643
|
var BOUND = {
|
|
3376
|
-
TokenExID: (value) =>
|
|
4644
|
+
TokenExID: (value) => exact2(TOKENEX_ID, value),
|
|
3377
4645
|
Origin: isOrigin,
|
|
3378
|
-
AuthenticationKey: (value) =>
|
|
3379
|
-
Timestamp: (value) =>
|
|
4646
|
+
AuthenticationKey: (value) => exact2(AUTHENTICATION_KEY, value),
|
|
4647
|
+
Timestamp: (value) => exact2(TIMESTAMP, value),
|
|
3380
4648
|
TokenScheme: (value) => TOKENEX_IFRAME_TOKEN_SCHEMES.includes(value)
|
|
3381
4649
|
};
|
|
3382
4650
|
var BOUND_KEYS = Object.keys(BOUND);
|
|
@@ -3384,19 +4652,19 @@ var BOOLEAN = /^(?:true|false)$/i;
|
|
|
3384
4652
|
var QUERY_RULES = {
|
|
3385
4653
|
...BOUND,
|
|
3386
4654
|
Mode: (value) => value === "Data",
|
|
3387
|
-
PCI: (value) =>
|
|
3388
|
-
CVV: (value) =>
|
|
3389
|
-
Container: (value) =>
|
|
3390
|
-
CvvContainer: (value) =>
|
|
3391
|
-
EnforceLuhnCompliance: (value) =>
|
|
4655
|
+
PCI: (value) => exact2(/^true$/i, value),
|
|
4656
|
+
CVV: (value) => exact2(/^true$/i, value),
|
|
4657
|
+
Container: (value) => exact2(/^[A-Za-z][A-Za-z0-9_-]{0,63}$/, value),
|
|
4658
|
+
CvvContainer: (value) => exact2(/^[A-Za-z][A-Za-z0-9_-]{0,63}$/, value),
|
|
4659
|
+
EnforceLuhnCompliance: (value) => exact2(BOOLEAN, value),
|
|
3392
4660
|
CustomDataLabel: (value) => plain(value, 64),
|
|
3393
4661
|
CustomCvvDataLabel: (value) => plain(value, 64),
|
|
3394
|
-
ExpiresInSeconds: (value) =>
|
|
3395
|
-
ReturnAutoCompleteValues: (value) =>
|
|
4662
|
+
ExpiresInSeconds: (value) => exact2(/^[1-9][0-9]{0,3}$/, value),
|
|
4663
|
+
ReturnAutoCompleteValues: (value) => exact2(BOOLEAN, value)
|
|
3396
4664
|
};
|
|
3397
4665
|
var QUERY_REQUIRED = [...BOUND_KEYS, "Mode", "PCI", "CVV"];
|
|
3398
4666
|
var PLACEHOLDER = /^[0-9]{1,19}(?: [0-9]{1,19}){0,5}$/;
|
|
3399
|
-
var placeholderDigits = (value) =>
|
|
4667
|
+
var placeholderDigits = (value) => exact2(PLACEHOLDER, value) && value.length <= 23 ? value.replace(/ /g, "") : null;
|
|
3400
4668
|
var RULES = {
|
|
3401
4669
|
...BOUND,
|
|
3402
4670
|
Data: (value) => {
|
|
@@ -3423,8 +4691,8 @@ var SUCCESS_RULES = {
|
|
|
3423
4691
|
token: (value) => digits(value, 13, 19),
|
|
3424
4692
|
firstSix: (value) => digits(value, 6, 6),
|
|
3425
4693
|
lastFour: (value) => digits(value, 4, 4),
|
|
3426
|
-
referenceNumber: (value) =>
|
|
3427
|
-
tokenHMAC: (value) =>
|
|
4694
|
+
referenceNumber: (value) => exact2(/^[A-Za-z0-9-]{1,64}$/, value),
|
|
4695
|
+
tokenHMAC: (value) => exact2(/^[A-Za-z0-9+/]{1,128}={0,2}$/, value),
|
|
3428
4696
|
cvvIncluded: (value) => typeof value === "boolean"
|
|
3429
4697
|
};
|
|
3430
4698
|
var SUCCESS_KEYS = Object.keys(SUCCESS_RULES);
|
|
@@ -3433,7 +4701,7 @@ var LETTERS2 = "A-Za-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u017F";
|
|
|
3433
4701
|
var PAGE_NAME2 = new RegExp(`^[${LETTERS2} .'-]{1,64}$`);
|
|
3434
4702
|
var HAS_LETTER2 = new RegExp(`[${LETTERS2}]`);
|
|
3435
4703
|
var ADDRESS_VALUE2 = new RegExp(`^[\\x20-\\x7e\\u00a0-\\u017f]{0,128}$`);
|
|
3436
|
-
var
|
|
4704
|
+
var PAN_LIKE3 = new RegExp(`(?:[0-9][^0-9${LETTERS2}]*){12,}`);
|
|
3437
4705
|
var pin7 = (fields) => Object.freeze({ ...fields, origins: Object.freeze([...fields.origins]), publicKeys: Object.freeze([...fields.publicKeys]) });
|
|
3438
4706
|
var OPENPAY_MERCHANT_PINS = /* @__PURE__ */ Object.freeze([
|
|
3439
4707
|
pin7({
|
|
@@ -3487,7 +4755,7 @@ var FASTSPRING_STORE_PINS = /* @__PURE__ */ Object.freeze([
|
|
|
3487
4755
|
Object.freeze({ environment: "production", store: "stardock", storefront: "/popup-store", merchant: "Stardock" })
|
|
3488
4756
|
]);
|
|
3489
4757
|
var STORE = "[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?";
|
|
3490
|
-
var
|
|
4758
|
+
var CARD_URL2 = new RegExp(`^https://(${STORE})(\\.test)?\\.onfastspring\\.com((?:/(?:popup|embedded)-[A-Za-z0-9_-]{1,64})?)/session/([A-Za-z0-9_-]{16,64})/payment$`);
|
|
3491
4759
|
// src/omise.js
|
|
3492
4760
|
var pin9 = (fields) => Object.freeze({ ...fields, origins: Object.freeze([...fields.origins]), keys: Object.freeze([...fields.keys]) });
|
|
3493
4761
|
var OMISE_MERCHANT_PINS = /* @__PURE__ */ Object.freeze([
|
|
@@ -3649,7 +4917,7 @@ var RECORD_MEMBERS = /* @__PURE__ */ Object.freeze({
|
|
|
3649
4917
|
]
|
|
3650
4918
|
});
|
|
3651
4919
|
// src/pin-payments.js
|
|
3652
|
-
var
|
|
4920
|
+
var CARD_KEYS2 = /* @__PURE__ */ Object.freeze(["name", "number", "cvc", "expiry_month", "expiry_year"]);
|
|
3653
4921
|
var ADDRESS_KEYS = /* @__PURE__ */ Object.freeze([
|
|
3654
4922
|
"address_line1",
|
|
3655
4923
|
"address_line2",
|
|
@@ -3658,9 +4926,9 @@ var ADDRESS_KEYS = /* @__PURE__ */ Object.freeze([
|
|
|
3658
4926
|
"address_state",
|
|
3659
4927
|
"address_country"
|
|
3660
4928
|
]);
|
|
3661
|
-
var
|
|
4929
|
+
var KEY2 = "publishable_api_key";
|
|
3662
4930
|
var METHOD = "_method";
|
|
3663
|
-
var DOCUMENTED = /* @__PURE__ */ new Set([
|
|
4931
|
+
var DOCUMENTED = /* @__PURE__ */ new Set([KEY2, METHOD, ...CARD_KEYS2, ...ADDRESS_KEYS]);
|
|
3664
4932
|
var TOKEN_FACTS = /* @__PURE__ */ Object.freeze([
|
|
3665
4933
|
"token",
|
|
3666
4934
|
"scheme",
|
|
@@ -3747,103 +5015,6 @@ var DECLINE_LABELS = Object.freeze(["label_error_payment", "label_error_bin", "l
|
|
|
3747
5015
|
var EXPIRED_LABELS = Object.freeze(["session_timeout", "ppid_expired"]);
|
|
3748
5016
|
var REF_KEYS = Object.freeze(["recloc", "orderId", "mopId", "pri", "approvalcode", "externalId", "paymentMerchantReference", "prr"]);
|
|
3749
5017
|
var PAYMENT_INFORMATION_KEYS = Object.freeze(["approvalcode", "pri", "externalId", "mopId"]);
|
|
3750
|
-
// src/processors/ekashu.js
|
|
3751
|
-
var EKASHU_HOSTS = Object.freeze(["live.ekashu.com", "test.ekashu.com"]);
|
|
3752
|
-
var EKASHU_TEST_PANS = Object.freeze(["4100000000000100", "5100000000000107"]);
|
|
3753
|
-
var EKASHU_SIGNED_FIELDS = Object.freeze([
|
|
3754
|
-
"ekashu_3d_secure_verify",
|
|
3755
|
-
"ekashu_amount",
|
|
3756
|
-
"ekashu_amount_format",
|
|
3757
|
-
"ekashu_auto_confirm",
|
|
3758
|
-
"ekashu_callback_failure_url",
|
|
3759
|
-
"ekashu_callback_include_post",
|
|
3760
|
-
"ekashu_callback_success_url",
|
|
3761
|
-
"ekashu_card_address_editable",
|
|
3762
|
-
"ekashu_card_address_required",
|
|
3763
|
-
"ekashu_card_address_verify",
|
|
3764
|
-
"ekashu_card_email_address_mandatory",
|
|
3765
|
-
"ekashu_card_phone_number_mandatory",
|
|
3766
|
-
"ekashu_card_title_mandatory",
|
|
3767
|
-
"ekashu_card_zip_code_verify",
|
|
3768
|
-
"ekashu_currency",
|
|
3769
|
-
"ekashu_delivery_address_editable",
|
|
3770
|
-
"ekashu_delivery_address_required",
|
|
3771
|
-
"ekashu_delivery_email_address_mandatory",
|
|
3772
|
-
"ekashu_delivery_phone_number_mandatory",
|
|
3773
|
-
"ekashu_delivery_title_mandatory",
|
|
3774
|
-
"ekashu_description",
|
|
3775
|
-
"ekashu_device",
|
|
3776
|
-
"ekashu_duplicate_check",
|
|
3777
|
-
"ekashu_duplicate_minutes",
|
|
3778
|
-
"ekashu_failure_return_text",
|
|
3779
|
-
"ekashu_failure_url",
|
|
3780
|
-
"ekashu_hash_code_format",
|
|
3781
|
-
"ekashu_hash_code_type",
|
|
3782
|
-
"ekashu_hash_code_version",
|
|
3783
|
-
"ekashu_include_post",
|
|
3784
|
-
"ekashu_invoice_address_editable",
|
|
3785
|
-
"ekashu_invoice_address_required",
|
|
3786
|
-
"ekashu_invoice_email_address_mandatory",
|
|
3787
|
-
"ekashu_invoice_phone_number_mandatory",
|
|
3788
|
-
"ekashu_invoice_title_mandatory",
|
|
3789
|
-
"ekashu_locale",
|
|
3790
|
-
"ekashu_payment_methods",
|
|
3791
|
-
"ekashu_reference",
|
|
3792
|
-
"ekashu_request_type",
|
|
3793
|
-
"ekashu_return_text",
|
|
3794
|
-
"ekashu_seller_address",
|
|
3795
|
-
"ekashu_seller_email_address",
|
|
3796
|
-
"ekashu_seller_id",
|
|
3797
|
-
"ekashu_seller_key",
|
|
3798
|
-
"ekashu_seller_name",
|
|
3799
|
-
"ekashu_shortcut_icon",
|
|
3800
|
-
"ekashu_style_sheet",
|
|
3801
|
-
"ekashu_success_url",
|
|
3802
|
-
"ekashu_title",
|
|
3803
|
-
"ekashu_verification_value_mask",
|
|
3804
|
-
"ekashu_verification_value_verify",
|
|
3805
|
-
"ekashu_viewport"
|
|
3806
|
-
]);
|
|
3807
|
-
var REQUIRED = Object.freeze([
|
|
3808
|
-
"ekashu_seller_id",
|
|
3809
|
-
"ekashu_seller_key",
|
|
3810
|
-
"ekashu_amount",
|
|
3811
|
-
"ekashu_currency",
|
|
3812
|
-
"ekashu_reference",
|
|
3813
|
-
"ekashu_hash_code",
|
|
3814
|
-
"ekashu_hash_code_type",
|
|
3815
|
-
"ekashu_hash_code_version",
|
|
3816
|
-
"ekashu_success_url",
|
|
3817
|
-
"ekashu_failure_url",
|
|
3818
|
-
"ekashu_callback_success_url"
|
|
3819
|
-
]);
|
|
3820
|
-
var CARD_KEYS2 = Object.freeze([
|
|
3821
|
-
"ekashu_card_number",
|
|
3822
|
-
"ekashu_expires_end_month",
|
|
3823
|
-
"ekashu_expires_end_year",
|
|
3824
|
-
"ekashu_verification_value",
|
|
3825
|
-
"ekashu_valid_from_month",
|
|
3826
|
-
"ekashu_valid_from_year",
|
|
3827
|
-
"ekashu_issue_number"
|
|
3828
|
-
]);
|
|
3829
|
-
var PAGE_KEYS = Object.freeze(["ekashu_stage", "ekashu_context", "ekashu_submission_id"]);
|
|
3830
|
-
var STORED_KEYS = Object.freeze(["ekashu_card_hash", "ekashu_card_reference", "ekashu_cof_initiated_by", "ekashu_cof_reason", "ekashu_cof_id"]);
|
|
3831
|
-
var REDIRECT_KEYS = Object.freeze(["ekashu_success_url", "ekashu_failure_url", "ekashu_return_url"]);
|
|
3832
|
-
var CALLBACK_KEYS = Object.freeze(["ekashu_callback_success_url", "ekashu_callback_failure_url"]);
|
|
3833
|
-
var MAX_ENTRY = 16 * 1024;
|
|
3834
|
-
var MAX_PAGE = 256 * 1024;
|
|
3835
|
-
var EKASHU_SELLERS = Object.freeze([
|
|
3836
|
-
Object.freeze({ sellerId: "25060100", merchant: "Heathrow Drop-off", entryHost: "heathrowdropoff.apcoa.com", callbackHost: "incomingapi.apcoa.co.uk" })
|
|
3837
|
-
]);
|
|
3838
|
-
var CARD_FIELDS = Object.freeze({
|
|
3839
|
-
number: "ekashu_card_number",
|
|
3840
|
-
month: "ekashu_expires_end_month",
|
|
3841
|
-
year: "ekashu_expires_end_year",
|
|
3842
|
-
cvc: "ekashu_verification_value"
|
|
3843
|
-
});
|
|
3844
|
-
var NAME_FIELDS = Object.freeze({ first: "ekashu_card_first_name", last: "ekashu_card_last_name" });
|
|
3845
|
-
var LEFT_EMPTY = Object.freeze(["ekashu_card_title", "ekashu_valid_from_month", "ekashu_valid_from_year", "ekashu_issue_number"]);
|
|
3846
|
-
var VISIBLE = /* @__PURE__ */ new Set([...Object.values(CARD_FIELDS), ...Object.values(NAME_FIELDS), ...LEFT_EMPTY]);
|
|
3847
5018
|
// src/processors/redsys.js
|
|
3848
5019
|
var REDSYS_HOSTS = Object.freeze(["sis.redsys.es"]);
|
|
3849
5020
|
var REDSYS_ENTRY_PATHS = Object.freeze(["/sis/realizarPago", "/sis/realizarPago/utf-8"]);
|
|
@@ -3878,7 +5049,7 @@ var SPECIAL = Object.freeze([
|
|
|
3878
5049
|
]);
|
|
3879
5050
|
var CARD_PARAMETERS = Object.freeze(["DS_MERCHANT_PAN", "DS_MERCHANT_EXPIRYDATE", "DS_MERCHANT_CVV2"]);
|
|
3880
5051
|
var CURRENCIES = Object.freeze({ 978: "eur", 840: "usd", 826: "gbp", 756: "chf" });
|
|
3881
|
-
var
|
|
5052
|
+
var MAX_PAGE3 = 256 * 1024;
|
|
3882
5053
|
var CARD_FIELDS2 = Object.freeze({
|
|
3883
5054
|
shown: "Sis_card-number",
|
|
3884
5055
|
expiry: "SIS_card-expiration",
|
|
@@ -3947,7 +5118,7 @@ var SCALARS = /* @__PURE__ */ new Set([
|
|
|
3947
5118
|
"shipping_address_selection"
|
|
3948
5119
|
]);
|
|
3949
5120
|
var CURRENCIES2 = Object.freeze({ DKK: "dkk", EUR: "eur", USD: "usd", SEK: "sek", NOK: "nok", GBP: "gbp", CHF: "chf", PLN: "pln" });
|
|
3950
|
-
var
|
|
5121
|
+
var MAX_PAGE4 = 256 * 1024;
|
|
3951
5122
|
var CARD_FIELDS3 = Object.freeze({ number: "cardnumber", month: "expiration[month]", year: "expiration[year]", cvc: "cvd", holder: "cardholder" });
|
|
3952
5123
|
var TYPED = /* @__PURE__ */ new Set([CARD_FIELDS3.number, CARD_FIELDS3.month, CARD_FIELDS3.year, CARD_FIELDS3.cvc]);
|
|
3953
5124
|
var CARD_PAGE2 = /* @__PURE__ */ new Set(["session_id", ...TYPED]);
|
|
@@ -3982,7 +5153,7 @@ var PRZELEWY24_SANDBOX_HOSTS = Object.freeze(["sandbox.przelewy24.pl"]);
|
|
|
3982
5153
|
var PRZELEWY24_MERCHANTS = Object.freeze([
|
|
3983
5154
|
Object.freeze({ id: "kupbilet", merchant: "KupBilet.pl", merchantId: null, origins: Object.freeze(["https://www.kupbilet.pl"]) })
|
|
3984
5155
|
]);
|
|
3985
|
-
var
|
|
5156
|
+
var MAX_PAGE5 = 256 * 1024;
|
|
3986
5157
|
var CURRENCIES3 = Object.freeze(["PLN", "EUR", "GBP", "USD", "CZK", "CHF", "DKK", "NOK", "SEK", "RON", "BGN", "HUF"]);
|
|
3987
5158
|
var PRZELEWY24_AJAX_HEADERS = Object.freeze({ Accept: "*/*", "X-Requested-With": "XMLHttpRequest" });
|
|
3988
5159
|
var MONTHS = Object.freeze(["01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12"]);
|
|
@@ -4014,7 +5185,7 @@ var TRANSBANK_MERCHANTS = Object.freeze([
|
|
|
4014
5185
|
returnUrl: null
|
|
4015
5186
|
})
|
|
4016
5187
|
]);
|
|
4017
|
-
var
|
|
5188
|
+
var MAX_PAGE6 = 64 * 1024;
|
|
4018
5189
|
var JSON_HEADERS = Object.freeze({ "content-type": "application/json", accept: "application/json, text/plain, */*" });
|
|
4019
5190
|
var FORM_HEADERS = Object.freeze({ "content-type": "application/x-www-form-urlencoded", accept: "application/json, text/plain, */*" });
|
|
4020
5191
|
var TRANSBANK_REFUSALS = Object.freeze(["transbank_3ds_challenge", "transbank_aborted", "transbank_error"]);
|
|
@@ -4034,11 +5205,11 @@ var PAYTRAIL_MERCHANTS = Object.freeze([
|
|
|
4034
5205
|
]);
|
|
4035
5206
|
var UUID_SOURCE = "[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}";
|
|
4036
5207
|
var UUID2 = new RegExp(`^${UUID_SOURCE}$`);
|
|
4037
|
-
var
|
|
5208
|
+
var ENTRY_PATH2 = new RegExp(`^/payments/(${UUID_SOURCE})/click-to-pay/loading-and-redirect$`);
|
|
4038
5209
|
var SIGNATURES = Object.freeze({ sha256: /^[0-9a-f]{64}$/, sha512: /^[0-9a-f]{128}$/ });
|
|
4039
5210
|
var PAYMENT_HIGHWAY_HOSTS = Object.freeze(["v1.api.paymenthighway.io"]);
|
|
4040
5211
|
var CARD_PAGE_PATH = new RegExp(`^/form/(${UUID_SOURCE})/pay_with_click_to_pay$`);
|
|
4041
|
-
var
|
|
5212
|
+
var MAX_PAGE7 = 256 * 1024;
|
|
4042
5213
|
var PAYTRAIL_CARD_HEADERS = Object.freeze({ "Content-Type": "application/json", "X-Requested-With": "PH-Form", Accept: "application/json" });
|
|
4043
5214
|
var PAYTRAIL_REFUSALS = Object.freeze(["paytrail_3ds_challenge", "paytrail_card_refused"]);
|
|
4044
5215
|
// src/processors/eximbay.js
|
|
@@ -4047,7 +5218,7 @@ var EXIMBAY_MERCHANTS = Object.freeze([]);
|
|
|
4047
5218
|
var MAX_ENTRY4 = 16 * 1024;
|
|
4048
5219
|
var REQUIRED4 = Object.freeze(["ver", "mid", "txntype", "ref", "cur", "amt", "buyer", "email", "lang", "returnurl", "statusurl", "fgkey"]);
|
|
4049
5220
|
var CURRENCIES4 = Object.freeze({ USD: 2, KRW: 0, JPY: 0, EUR: 2, GBP: 2, SGD: 2, HKD: 2, CAD: 2, AUD: 2, THB: 2 });
|
|
4050
|
-
var
|
|
5221
|
+
var MAX_PAGE8 = 512 * 1024;
|
|
4051
5222
|
var ATTRS = `(?:[^>"']|"[^"]{0,1024}"|'[^']{0,1024}'){0,512}`;
|
|
4052
5223
|
var startTag = (name) => new RegExp(`<${name}(?=[\\t\\n\\f\\r />])${ATTRS}>`, "gi");
|
|
4053
5224
|
var FORM_START = startTag("form");
|
|
@@ -4100,7 +5271,7 @@ var RESULT_BINDS = Object.freeze(["mid", "txntype", "ref", "cur", "amt"]);
|
|
|
4100
5271
|
var BARION_HOSTS = Object.freeze(["secure.barion.com", "secure.test.barion.com"]);
|
|
4101
5272
|
var BARION_SANDBOX_HOSTS = Object.freeze(["secure.test.barion.com"]);
|
|
4102
5273
|
var BARION_SHOPS = Object.freeze([]);
|
|
4103
|
-
var
|
|
5274
|
+
var MAX_PAGE9 = 512 * 1024;
|
|
4104
5275
|
var CURRENCIES5 = Object.freeze(["HUF", "EUR", "USD", "CZK", "RON", "PLN"]);
|
|
4105
5276
|
var CARD_INPUTS = Object.freeze({ number: "cc-number", expiry: "cc-exp-date", cvc: "CardCVC", holder: "CardHolderName" });
|
|
4106
5277
|
var CHECKBOXES = Object.freeze(["RegisterUser", "AcceptedTerms", "HasEmailConsent"]);
|
|
@@ -4152,7 +5323,7 @@ var SBPS_MERCHANT_PINS = /* @__PURE__ */ Object.freeze([
|
|
|
4152
5323
|
]);
|
|
4153
5324
|
var ERROR_TYPES = /* @__PURE__ */ Object.freeze(["03", "04", "05", "07", "99"]);
|
|
4154
5325
|
var ERROR_FIELDS = /* @__PURE__ */ Object.freeze(["001", "002", "003", "004", "005", "999"]);
|
|
4155
|
-
var SBPS_REFUSAL_CODES = /* @__PURE__ */ Object.freeze(ERROR_TYPES.flatMap((type) => ERROR_FIELDS.map((
|
|
5326
|
+
var SBPS_REFUSAL_CODES = /* @__PURE__ */ Object.freeze(ERROR_TYPES.flatMap((type) => ERROR_FIELDS.map((field2) => `${type}${field2}`)));
|
|
4156
5327
|
// src/recognition.js
|
|
4157
5328
|
var PATTERN_WITHOUT_CARD_FIELDS = Object.freeze({
|
|
4158
5329
|
stripe: "api\\.stripe\\.com/v1/(payment_methods|tokens|setup_intents/seti_\\w+/confirm|payment_intents/pi_\\w+/confirm)"
|
|
@@ -4235,7 +5406,7 @@ var replayPolicy = Object.freeze({ contentTypeFor, HEADER_NEVER_FORWARD });
|
|
|
4235
5406
|
var STRIPE_CHECKOUT_OPERATION = "stripe.device_checkout_confirm.v1";
|
|
4236
5407
|
var STRIPE_CHECKOUT_CONTEXT_HEADER = "x-agentcard-stripe-checkout-context";
|
|
4237
5408
|
var SESSION = /^cs_(?:test|live)_[A-Za-z0-9]{1,200}(?![\s\S])/;
|
|
4238
|
-
var
|
|
5409
|
+
var KEY3 = /^pk_(?:test|live)_[A-Za-z0-9_]{1,256}(?![\s\S])/;
|
|
4239
5410
|
var SYNTHETIC = /^pm_agentcard_checkout_[A-Za-z0-9_-]{16,80}(?![\s\S])/;
|
|
4240
5411
|
var STRIPE_CHECKOUT_VALIDATION_CODES = Object.freeze({
|
|
4241
5412
|
unclassified: "unclassified",
|
|
@@ -4278,7 +5449,7 @@ function validateStripeCheckoutIdentity(value) {
|
|
|
4278
5449
|
reject("mode_binding");
|
|
4279
5450
|
const environment = value.environment ?? "test", livemode = environment === "production";
|
|
4280
5451
|
const mode = livemode ? "live" : "test";
|
|
4281
|
-
if (Object.hasOwn(value, "sessionId") && (typeof value.sessionId !== "string" || !SESSION.test(value.sessionId) || !value.sessionId.startsWith(`cs_${mode}_`)) || Object.hasOwn(value, "publishableKey") && (typeof value.publishableKey !== "string" || !
|
|
5452
|
+
if (Object.hasOwn(value, "sessionId") && (typeof value.sessionId !== "string" || !SESSION.test(value.sessionId) || !value.sessionId.startsWith(`cs_${mode}_`)) || Object.hasOwn(value, "publishableKey") && (typeof value.publishableKey !== "string" || !KEY3.test(value.publishableKey) || !value.publishableKey.startsWith(`pk_${mode}_`)) || Object.hasOwn(value, "livemode") && value.livemode !== livemode)
|
|
4282
5453
|
reject("mode_binding");
|
|
4283
5454
|
return Object.freeze({ environment, livemode });
|
|
4284
5455
|
}
|
|
@@ -4314,16 +5485,16 @@ function isStripeCheckoutHostedMode(value) {
|
|
|
4314
5485
|
return value === "hosted" || value === "hosted_page";
|
|
4315
5486
|
}
|
|
4316
5487
|
function encodeAscii(value) {
|
|
4317
|
-
let result = "", bits = 0,
|
|
5488
|
+
let result = "", bits = 0, count2 = 0;
|
|
4318
5489
|
for (const char of value) {
|
|
4319
5490
|
bits = bits << 8 | char.charCodeAt(0);
|
|
4320
|
-
|
|
4321
|
-
while (
|
|
4322
|
-
|
|
4323
|
-
result += alphabet[bits >>>
|
|
5491
|
+
count2 += 8;
|
|
5492
|
+
while (count2 >= 6) {
|
|
5493
|
+
count2 -= 6;
|
|
5494
|
+
result += alphabet[bits >>> count2 & 63];
|
|
4324
5495
|
}
|
|
4325
5496
|
}
|
|
4326
|
-
return result + (
|
|
5497
|
+
return result + (count2 ? alphabet[bits << 6 - count2 & 63] : "");
|
|
4327
5498
|
}
|
|
4328
5499
|
function context(value) {
|
|
4329
5500
|
if (!object(value) || Object.keys(value).length !== 3 || value.version !== 1 || !["version", "session_id", "synthetic_payment_method_id"].every((key) => Object.hasOwn(value, key)) || !SESSION.test(value.session_id) || !SYNTHETIC.test(value.synthetic_payment_method_id))
|
|
@@ -4343,13 +5514,13 @@ function parseStripeCheckoutContext(request) {
|
|
|
4343
5514
|
if (entries.length !== 1 || typeof entries[0][1] !== "string" || !/^[A-Za-z0-9_-]{1,1024}$/.test(entries[0][1]))
|
|
4344
5515
|
reject("context_invalid");
|
|
4345
5516
|
const encoded = entries[0][1];
|
|
4346
|
-
let text2 = "", bits = 0,
|
|
5517
|
+
let text2 = "", bits = 0, count2 = 0;
|
|
4347
5518
|
for (const char of encoded) {
|
|
4348
5519
|
bits = bits << 6 | alphabet.indexOf(char);
|
|
4349
|
-
|
|
4350
|
-
if (
|
|
4351
|
-
|
|
4352
|
-
text2 += String.fromCharCode(bits >>>
|
|
5520
|
+
count2 += 6;
|
|
5521
|
+
if (count2 >= 8) {
|
|
5522
|
+
count2 -= 8;
|
|
5523
|
+
text2 += String.fromCharCode(bits >>> count2 & 255);
|
|
4353
5524
|
}
|
|
4354
5525
|
}
|
|
4355
5526
|
let value;
|
|
@@ -4482,7 +5653,7 @@ function keyFor(request, values, expected) {
|
|
|
4482
5653
|
headerKey = match[1];
|
|
4483
5654
|
}
|
|
4484
5655
|
const key = values.get("key") || headerKey;
|
|
4485
|
-
if (!
|
|
5656
|
+
if (!KEY3.test(key) || headerKey && headerKey !== key || expected !== void 0 && expected !== key)
|
|
4486
5657
|
reject("publishable_key");
|
|
4487
5658
|
return key;
|
|
4488
5659
|
}
|
|
@@ -4504,13 +5675,13 @@ function attachStripeCheckoutBilling(request, captured, options) {
|
|
|
4504
5675
|
const phase = classifyStripeCheckoutRequest(request, options);
|
|
4505
5676
|
if (phase?.phase !== "final" || !object(captured) || Object.keys(captured).length !== 3 || !["session_id", "synthetic_payment_method_id", "email"].every((key) => Object.hasOwn(captured, key)) || captured.session_id !== phase.session_id || captured.synthetic_payment_method_id !== phase.synthetic_payment_method_id || !billingEmail(captured.email))
|
|
4506
5677
|
reject("billing_binding");
|
|
4507
|
-
const
|
|
4508
|
-
const existing = form(request, finalFields).values.get(
|
|
5678
|
+
const field2 = "payment_method_data[billing_details][email]";
|
|
5679
|
+
const existing = form(request, finalFields).values.get(field2);
|
|
4509
5680
|
if (existing !== void 0 && existing !== captured.email)
|
|
4510
5681
|
reject("billing_conflict");
|
|
4511
5682
|
if (captured.email === null || existing !== void 0)
|
|
4512
5683
|
return { ...request };
|
|
4513
|
-
const body = `${request.body}&${encodeURIComponent(
|
|
5684
|
+
const body = `${request.body}&${encodeURIComponent(field2)}=${encodeURIComponent(captured.email)}`;
|
|
4514
5685
|
const result = { ...request, body };
|
|
4515
5686
|
classifyStripeCheckoutRequest(result, options);
|
|
4516
5687
|
return result;
|