@agent-cards/sdk 0.23.13 → 0.23.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,577 @@
1
+ // @ts-nocheck
2
+ // Generated from @agent-cards/payment-core. Do not edit.
3
+ // artifact-sha256: fa93cde1a237f603279ae56e0c7d9539896784842d9077fb777b8a23bacc9a3d
4
+ // src/ebanx.js
5
+ var EBANX_RESEND_HOSTS = Object.freeze([
6
+ "customer.ebanx.com",
7
+ "customer-frontier.ebanx.com",
8
+ "customer-local-latam.ebanx.com",
9
+ "api-local-latam.ebanx.com",
10
+ "api.ebanx.com",
11
+ "sandbox.ebanx.com",
12
+ "sandbox-local-latam.ebanx.com",
13
+ "api-diamond.ebanxpay.com",
14
+ "api.ebanxpay.com",
15
+ "sandbox.ebanxpay.com"
16
+ ]);
17
+ var EBANX_THREE_DS_CARD_PATHS = Object.freeze([
18
+ "/ws/threedsecureserver-generateToken",
19
+ "/ws/threedsecureserver-authentications",
20
+ "/ws/threedsecureserver-authentication-results"
21
+ ]);
22
+ var EBANX_CONFIRM_PATH = "/ws/checkout-v2/confirm";
23
+ var EBANX_RESEND_REFUSALS = Object.freeze(["three_ds_card", "confirm_card_code", "unreadable"]);
24
+ var THREE_DS = EBANX_THREE_DS_CARD_PATHS.map((path) => path.toLowerCase());
25
+ var CONFIRM = EBANX_CONFIRM_PATH.toLowerCase();
26
+ var CONFIRM_CARD_KEYS = Object.freeze(["card_cvv", "card_number"]);
27
+ var record = (value) => !!value && typeof value === "object" && !Array.isArray(value);
28
+ var own = (value, key) => record(value) && Object.prototype.hasOwnProperty.call(value, key) ? value[key] : void 0;
29
+ function ebanxResendKind(url) {
30
+ let parsed;
31
+ try {
32
+ parsed = new URL(String(url));
33
+ }
34
+ catch {
35
+ return null;
36
+ }
37
+ if (parsed.protocol !== "https:" || parsed.port || parsed.username || parsed.password)
38
+ return null;
39
+ if (!EBANX_RESEND_HOSTS.includes(parsed.hostname.toLowerCase().replace(/\.$/, "")))
40
+ return null;
41
+ const path = resendPath(parsed.pathname);
42
+ if (path === null)
43
+ return "unreadable";
44
+ if (THREE_DS.includes(path))
45
+ return "three_ds";
46
+ return path === CONFIRM ? "confirm" : null;
47
+ }
48
+ var RESEND_PATH_ROUNDS = 4;
49
+ var ASCII_ESCAPE = /%[0-7][0-9A-Fa-f]/;
50
+ function resendPath(pathname) {
51
+ let path = String(pathname);
52
+ for (let round = 0; round < RESEND_PATH_ROUNDS && ASCII_ESCAPE.test(path); round++) {
53
+ path = path.replace(/%([0-7][0-9A-Fa-f])/g, (escape, hex) => String.fromCharCode(parseInt(hex, 16)));
54
+ }
55
+ if (ASCII_ESCAPE.test(path))
56
+ return null;
57
+ const segments = [];
58
+ for (const piece of path.split(/[/\\]/)) {
59
+ const segment = piece.split(";")[0];
60
+ if (segment === "" || segment === ".")
61
+ continue;
62
+ if (segment === "..")
63
+ segments.pop();
64
+ else
65
+ segments.push(segment);
66
+ }
67
+ return ("/" + segments.join("/")).toLowerCase();
68
+ }
69
+ function ebanxResendRefusal(request) {
70
+ if (!record(request) || String(request.method ?? "").toUpperCase() !== "POST")
71
+ return null;
72
+ const kind = ebanxResendKind(request.url);
73
+ if (kind === "unreadable")
74
+ return "unreadable";
75
+ if (kind === "three_ds")
76
+ return "three_ds_card";
77
+ if (kind !== "confirm")
78
+ return null;
79
+ const body = request.body;
80
+ if (typeof body !== "string" || body === "")
81
+ return "unreadable";
82
+ let parsed;
83
+ try {
84
+ parsed = JSON.parse(body);
85
+ }
86
+ catch {
87
+ return "unreadable";
88
+ }
89
+ if (!record(parsed))
90
+ return "unreadable";
91
+ const card = own(own(parsed, "payment"), "card");
92
+ if (!record(card))
93
+ return null;
94
+ return CONFIRM_CARD_KEYS.some((key) => {
95
+ const value = own(card, key);
96
+ return value !== void 0 && value !== null && value !== "";
97
+ }) ? "confirm_card_code" : null;
98
+ }
99
+ var EBANX_FOLLOW_UP_KINDS = Object.freeze(["generate_token", "authentications", "authentication_results", "confirm"]);
100
+ var EBANX_FOLLOW_UP_LIMITS = Object.freeze({ generate_token: 1, authentications: 1, authentication_results: 48, confirm: 1 });
101
+ var EBANX_FOLLOW_UP_MAX = 51;
102
+ var EBANX_FOLLOW_UP_WINDOW_MS = 15 * 60 * 1e3;
103
+ var EBANX_FOLLOW_UP_IDLE_MS = 60 * 1e3;
104
+ var EBANX_FOLLOW_UP_CHALLENGE_MS = 11 * 60 * 1e3;
105
+ var EBANX_FOLLOW_UP_BODY_LIMIT = 32 * 1024;
106
+ var EBANX_FOLLOW_UP_ANSWER_LIMIT = 64 * 1024;
107
+ var EBANX_FOLLOW_UP_REFUSALS = Object.freeze([
108
+ "not_a_follow_up",
109
+ "parent_unreadable",
110
+ "host_mismatch",
111
+ "follow_up_closed",
112
+ "follow_up_in_flight",
113
+ "follow_up_limit",
114
+ "out_of_order",
115
+ "unreadable",
116
+ "shape",
117
+ "card_mismatch",
118
+ "key_mismatch",
119
+ "amount_unapproved",
120
+ "amount_mismatch",
121
+ "token_mismatch",
122
+ "session_mismatch",
123
+ "card_on_file",
124
+ "instalments",
125
+ "unreviewed_field"
126
+ ]);
127
+ var FOLLOW_UP_PATHS = Object.freeze({
128
+ "/ws/threedsecureserver-generateToken": "generate_token",
129
+ "/ws/threedsecureserver-authentications": "authentications",
130
+ "/ws/threedsecureserver-authentication-results": "authentication_results",
131
+ [EBANX_CONFIRM_PATH]: "confirm"
132
+ });
133
+ var TOKEN_HOSTS = Object.freeze([
134
+ "customer.ebanx.com",
135
+ "customer-frontier.ebanx.com",
136
+ "api-local-latam.ebanx.com",
137
+ "api.ebanx.com",
138
+ "sandbox.ebanx.com",
139
+ "sandbox-local-latam.ebanx.com",
140
+ "api-diamond.ebanxpay.com",
141
+ "api.ebanxpay.com",
142
+ "sandbox.ebanxpay.com"
143
+ ]);
144
+ var CONFIRM_HOSTS = Object.freeze({
145
+ "customer.ebanx.com": "customer.ebanx.com",
146
+ "api-local-latam.ebanx.com": "customer-local-latam.ebanx.com",
147
+ "api-diamond.ebanxpay.com": "api-diamond.ebanxpay.com",
148
+ "customer-frontier.ebanx.com": "customer-frontier.ebanx.com"
149
+ });
150
+ var INVOICE_HASH = /^[0-9a-f]{48}$/i;
151
+ var THREE_DS_KINDS = Object.freeze(["generate_token", "authentications", "authentication_results"]);
152
+ var CONFIRM_PAYMENT_FIELDS = Object.freeze([
153
+ "hash",
154
+ "merchant_payment_code",
155
+ "payment_type",
156
+ "payment_type_code",
157
+ "card",
158
+ "instalments",
159
+ "save_card_oneclick",
160
+ "name",
161
+ "email",
162
+ "castle_request_token",
163
+ "captcha_token",
164
+ "device_id",
165
+ "app_metadata",
166
+ "metadata",
167
+ "country",
168
+ "document",
169
+ "document_type",
170
+ "person_type",
171
+ "responsible",
172
+ "zipcode",
173
+ "state",
174
+ "city",
175
+ "address",
176
+ "street_number",
177
+ "street_complement",
178
+ "phone_number"
179
+ ]);
180
+ var CONFIRM_CARD_FIELDS = Object.freeze([
181
+ "token",
182
+ "payment_type_code",
183
+ "card_unique_id",
184
+ "card_cvv",
185
+ "threeds_eci",
186
+ "threeds_cryptogram",
187
+ "threeds_xid",
188
+ "threeds_version",
189
+ "threeds_trxid",
190
+ "threeds_token"
191
+ ]);
192
+ var DIGITS = /^\d{12,19}$/;
193
+ var DECIMAL = /^(\d{1,15})(?:\.(\d{1,3}))?$/;
194
+ var ZERO_DECIMAL = Object.freeze(["bif", "clp", "djf", "gnf", "jpy", "kmf", "krw", "mga", "pyg", "rwf", "vnd", "vuv", "xaf", "xof", "xpf"]);
195
+ var THREE_DECIMAL = Object.freeze(["bhd", "jod", "kwd", "omr", "tnd"]);
196
+ var minorDigits = (currency) => ZERO_DECIMAL.includes(currency) ? 0 : THREE_DECIMAL.includes(currency) ? 3 : 2;
197
+ var text = (value) => typeof value === "string" && value.length > 0 && value.length <= 1024;
198
+ function parseObject(body, limit = EBANX_FOLLOW_UP_BODY_LIMIT) {
199
+ if (typeof body !== "string" || body.length === 0 || body.length > limit)
200
+ return null;
201
+ try {
202
+ const parsed = JSON.parse(body);
203
+ return record(parsed) ? parsed : null;
204
+ }
205
+ catch {
206
+ return null;
207
+ }
208
+ }
209
+ function followUpUrl(url) {
210
+ if (typeof url !== "string" || url.length > 2048)
211
+ return null;
212
+ let parsed;
213
+ try {
214
+ parsed = new URL(url);
215
+ }
216
+ catch {
217
+ return null;
218
+ }
219
+ if (parsed.protocol !== "https:" || parsed.port || parsed.username || parsed.password || parsed.hash || url.includes("#"))
220
+ return null;
221
+ if (!EBANX_RESEND_HOSTS.includes(parsed.hostname) || parsed.href !== url)
222
+ return null;
223
+ const kind = Object.prototype.hasOwnProperty.call(FOLLOW_UP_PATHS, parsed.pathname) ? FOLLOW_UP_PATHS[parsed.pathname] : null;
224
+ if (!kind)
225
+ return null;
226
+ if (kind !== "confirm")
227
+ return parsed.search === "" ? { kind, host: parsed.hostname, hash: null } : null;
228
+ const query = /^\?hash=([0-9A-Fa-f]{48})$/.exec(parsed.search);
229
+ return query ? { kind, host: parsed.hostname, hash: query[1] } : null;
230
+ }
231
+ function ebanxFollowUpKind(url) {
232
+ return followUpUrl(url)?.kind ?? null;
233
+ }
234
+ function readEbanxTokenRequest(template) {
235
+ if (!record(template) || typeof template.url !== "string")
236
+ return null;
237
+ let parsed;
238
+ try {
239
+ parsed = new URL(template.url);
240
+ }
241
+ catch {
242
+ return null;
243
+ }
244
+ if (parsed.protocol !== "https:" || parsed.port || parsed.username || parsed.password || parsed.pathname !== "/ws/token" || !TOKEN_HOSTS.includes(parsed.hostname))
245
+ return null;
246
+ const body = parseObject(template.body);
247
+ const card = own(body, "card");
248
+ const number = own(card, "card_number");
249
+ const due = /^(\d{1,2})\/(\d{4})$/.exec(String(own(card, "card_due_date") ?? ""));
250
+ const key = own(body, "public_integration_key");
251
+ const country = own(body, "country");
252
+ if (!record(card) || typeof number !== "string" || !DIGITS.test(number) || !due || Number(due[1]) < 1 || Number(due[1]) > 12 || !text(key) || !text(country))
253
+ return null;
254
+ const cvv = own(card, "card_cvv");
255
+ const name = own(card, "card_name");
256
+ return Object.freeze({
257
+ host: parsed.hostname,
258
+ number,
259
+ month: Number(due[1]),
260
+ year: Number(due[2]),
261
+ cvv: typeof cvv === "string" || typeof cvv === "number" ? String(cvv) : null,
262
+ name: typeof name === "string" ? name : null,
263
+ publicIntegrationKey: key,
264
+ country: country.toLowerCase()
265
+ });
266
+ }
267
+ function readEbanxTokenAnswer(answer) {
268
+ const body = record(answer) ? parseObject(answer.text, EBANX_FOLLOW_UP_ANSWER_LIMIT) : null;
269
+ if (!body || own(body, "status") !== "SUCCESS" || record(answer) && answer.status !== void 0 && !(answer.status >= 200 && answer.status < 300))
270
+ return null;
271
+ const named = own(body, "token");
272
+ const token = record(named) ? own(named, "token") : named;
273
+ if (!text(token))
274
+ return null;
275
+ const brand = own(body, "payment_type_code");
276
+ const unique = own(body, "card_unique_id");
277
+ return Object.freeze({ token, paymentTypeCode: text(brand) ? brand : null, cardUniqueId: text(unique) ? unique : null });
278
+ }
279
+ var EBANX_PAYING_STATUSES = Object.freeze(["CO", "PE"]);
280
+ var EBANX_ERROR_CODE = /^[A-Z]{2,4}(?:-[A-Z0-9]{1,6}){1,3}$/;
281
+ var ebanxErrorCode = (code) => typeof code === "string" && EBANX_ERROR_CODE.test(code) && !/\d{5}/.test(code) && (code.match(/\d/g) ?? []).length < 12 ? code : null;
282
+ function ebanxAnswerRefusal(status, answerText) {
283
+ if (!Number.isInteger(status))
284
+ return null;
285
+ if (status >= 400 && status < 500)
286
+ return ebanxErrorCode(own(parseObject(answerText, EBANX_FOLLOW_UP_ANSWER_LIMIT), "status_code")) ?? `ebanx_http_${status}`;
287
+ if (!(status >= 200 && status < 300))
288
+ return null;
289
+ const body = parseObject(answerText, EBANX_FOLLOW_UP_ANSWER_LIMIT);
290
+ if (!body)
291
+ return null;
292
+ if (own(body, "status") === "ERROR")
293
+ return ebanxErrorCode(own(body, "status_code")) ?? "ebanx_error";
294
+ const paymentStatus = own(own(body, "payment"), "status");
295
+ if (typeof paymentStatus === "string" && !EBANX_PAYING_STATUSES.includes(paymentStatus)) {
296
+ return /^[A-Z]{2}$/.test(paymentStatus) ? "ebanx_payment_" + paymentStatus.toLowerCase() : "ebanx_payment_refused";
297
+ }
298
+ return null;
299
+ }
300
+ var EBANX_THREE_DS_FAILED = "AUTHENTICATION_FAILED";
301
+ var EBANX_THREE_DS_FAILED_CODE = "ebanx_3ds_failed";
302
+ function ebanxAnswerOutcome(status, answerText, url) {
303
+ const kind = ebanxFollowUpKind(url);
304
+ if (!kind)
305
+ return null;
306
+ if (kind !== "confirm") {
307
+ return ebanxAnswerSession(answerText).status === EBANX_THREE_DS_FAILED ? { outcome: "refused", code: EBANX_THREE_DS_FAILED_CODE } : { outcome: "approved" };
308
+ }
309
+ if (!Number.isInteger(status) || status >= 500)
310
+ return { outcome: "unknown", reason: "server_error" };
311
+ const body = parseObject(answerText, EBANX_FOLLOW_UP_ANSWER_LIMIT);
312
+ const unconfirmed = { outcome: "unknown", reason: "ebanx_confirm_unconfirmed" };
313
+ const answered = own(body, "status");
314
+ if (answered === "ERROR")
315
+ return { outcome: "refused", code: ebanxErrorCode(own(body, "status_code")) ?? "ebanx_error" };
316
+ if (!(status >= 200 && status < 300) || answered !== "SUCCESS")
317
+ return unconfirmed;
318
+ const paymentStatus = own(own(body, "payment"), "status");
319
+ if (typeof paymentStatus !== "string" || paymentStatus === "")
320
+ return unconfirmed;
321
+ if (EBANX_PAYING_STATUSES.includes(paymentStatus))
322
+ return { outcome: "approved" };
323
+ return { outcome: "refused", code: /^[A-Z]{2}$/.test(paymentStatus) ? "ebanx_payment_" + paymentStatus.toLowerCase() : "ebanx_payment_refused" };
324
+ }
325
+ function answerItem(answerText) {
326
+ const body = parseObject(answerText, EBANX_FOLLOW_UP_ANSWER_LIMIT);
327
+ const data = own(body, "data");
328
+ return Array.isArray(data) && record(data[0]) ? data[0] : null;
329
+ }
330
+ function ebanxAnswerSession(answerText) {
331
+ const item = answerItem(answerText);
332
+ const read = (key) => {
333
+ const value = own(item, key);
334
+ return text(value) ? value : null;
335
+ };
336
+ const status = read("status");
337
+ return Object.freeze({ paymentId: read("paymentId"), accessToken: read("accessToken"), status: status ? status.toUpperCase() : null });
338
+ }
339
+ function ebanxFollowUpIdleMs(kind, answerText) {
340
+ if (kind === "confirm")
341
+ return 0;
342
+ if (kind === "authentications" && ebanxAnswerSession(answerText).status === "PENDING_AUTHENTICATION")
343
+ return EBANX_FOLLOW_UP_CHALLENGE_MS;
344
+ return EBANX_FOLLOW_UP_IDLE_MS;
345
+ }
346
+ function namedAmount(amount, currency) {
347
+ const figure = typeof amount === "number" && Number.isFinite(amount) && amount >= 0 ? String(amount) : amount;
348
+ if (typeof figure !== "string" || typeof currency !== "string" || !/^[A-Za-z]{3}$/.test(currency))
349
+ return null;
350
+ const match = DECIMAL.exec(figure);
351
+ if (!match)
352
+ return null;
353
+ const code = currency.toLowerCase();
354
+ const digits = minorDigits(code);
355
+ const fraction = match[2] ?? "";
356
+ if (fraction.length > digits && Number(fraction.slice(digits)) !== 0)
357
+ return null;
358
+ const minor = Number(match[1]) * 10 ** digits + Number((fraction + "000").slice(0, digits) || "0");
359
+ return Number.isSafeInteger(minor) ? { minor, currency: code } : null;
360
+ }
361
+ function approvedAmount(approved) {
362
+ if (!record(approved) || typeof approved.currency !== "string" || !/^[A-Za-z]{3}$/.test(approved.currency))
363
+ return null;
364
+ const minor = typeof approved.amountCents === "bigint" ? Number(approved.amountCents) : approved.amountCents;
365
+ return Number.isSafeInteger(minor) && minor > 0 ? { minor, currency: approved.currency.toLowerCase() } : null;
366
+ }
367
+ function sentFacts(sent) {
368
+ if (!Array.isArray(sent))
369
+ return null;
370
+ const out = [];
371
+ for (const item of sent) {
372
+ if (!record(item) || !EBANX_FOLLOW_UP_KINDS.includes(item.kind) || !["pending", "answered", "failed"].includes(item.state))
373
+ return null;
374
+ const answer = item.state === "answered" && record(item.answer) ? item.answer : null;
375
+ out.push({
376
+ kind: item.kind,
377
+ state: item.state,
378
+ body: parseObject(item.body),
379
+ answerText: answer && typeof answer.text === "string" ? answer.text : null,
380
+ answerStatus: answer && Number.isInteger(answer.status) ? answer.status : null
381
+ });
382
+ }
383
+ return out;
384
+ }
385
+ function threeDsSucceeded(item) {
386
+ return THREE_DS_KINDS.includes(item.kind) && item.state === "answered" && item.answerText !== null && own(answerItem(item.answerText), "status") === "AUTHENTICATION_SUCCESSFUL";
387
+ }
388
+ var refused = (refusal) => Object.freeze({ ok: false, refusal });
389
+ function threeDsCardRefusal(body, parent) {
390
+ const info = own(body, "paymentInformation");
391
+ const card = own(info, "card");
392
+ const number = own(card, "number");
393
+ const month = own(card, "expirationMonth");
394
+ const year = own(card, "expirationYear");
395
+ if (!record(card) || typeof number !== "string" || typeof month !== "string" || typeof year !== "string")
396
+ return "shape";
397
+ if (!/^\d{1,2}$/.test(month) || !/^(?:\d{2}|\d{4})$/.test(year))
398
+ return "shape";
399
+ if (number !== parent.number)
400
+ return "card_mismatch";
401
+ const fullYear = year.length === 2 ? 2e3 + Number(year) : Number(year);
402
+ if (Number(month) !== parent.month || fullYear !== parent.year)
403
+ return "card_mismatch";
404
+ const holder = own(card, "holderName");
405
+ if (holder !== void 0 && holder !== null && typeof holder !== "string")
406
+ return "shape";
407
+ return null;
408
+ }
409
+ function ebanxFollowUpVerdict(input, options = {}) {
410
+ if (!record(input) || !record(input.request))
411
+ return refused("not_a_follow_up");
412
+ const { request } = input;
413
+ if (String(request.method ?? "").toUpperCase() !== "POST")
414
+ return refused("not_a_follow_up");
415
+ const target = followUpUrl(request.url);
416
+ if (!target)
417
+ return refused("not_a_follow_up");
418
+ const parentInput = record(input.parent) ? input.parent : null;
419
+ const parent = parentInput ? readEbanxTokenRequest(parentInput) : null;
420
+ const token = parentInput ? readEbanxTokenAnswer(parentInput.answer) : null;
421
+ if (!parent || !token)
422
+ return refused("parent_unreadable");
423
+ const { kind } = target;
424
+ if (kind === "confirm" ? CONFIRM_HOSTS[parent.host] !== target.host : target.host !== parent.host)
425
+ return refused("host_mismatch");
426
+ const sent = sentFacts(input.sent ?? []);
427
+ if (!sent)
428
+ return refused("parent_unreadable");
429
+ if (sent.some((item) => item.kind === "confirm"))
430
+ return refused("follow_up_closed");
431
+ if (sent.some((item) => item.state === "pending"))
432
+ return refused("follow_up_in_flight");
433
+ const ofKind = sent.filter((item) => item.kind === kind).length;
434
+ if (ofKind >= EBANX_FOLLOW_UP_LIMITS[kind] || sent.length >= EBANX_FOLLOW_UP_MAX)
435
+ return refused("follow_up_limit");
436
+ const generate = sent.find((item) => item.kind === "generate_token") ?? null;
437
+ const authentications = sent.find((item) => item.kind === "authentications") ?? null;
438
+ if (kind === "generate_token" && sent.length > 0)
439
+ return refused("out_of_order");
440
+ if (kind === "authentications" && generate?.state !== "answered")
441
+ return refused("out_of_order");
442
+ if (kind === "authentication_results" && authentications?.state !== "answered")
443
+ return refused("out_of_order");
444
+ if (kind === "confirm" && (generate?.state !== "answered" || authentications?.state !== "answered"))
445
+ return refused("out_of_order");
446
+ const body = parseObject(request.body);
447
+ if (!body)
448
+ return refused("unreadable");
449
+ const openedHash = generate?.body ? own(own(generate.body, "paymentInformation"), "paymentHash") : void 0;
450
+ if (kind === "confirm") {
451
+ const payment = own(body, "payment");
452
+ const card = own(payment, "card");
453
+ if (!record(payment) || !record(card))
454
+ return refused("shape");
455
+ for (const key2 of ["card_number", "card_due_date", "card_name"]) {
456
+ if (own(card, key2) !== void 0)
457
+ return refused("card_mismatch");
458
+ }
459
+ if (Object.keys(body).some((key2) => key2 !== "payment") || Object.keys(payment).some((key2) => !CONFIRM_PAYMENT_FIELDS.includes(key2)) || Object.keys(card).some((key2) => !CONFIRM_CARD_FIELDS.includes(key2)))
460
+ return refused("unreviewed_field");
461
+ const kept = own(payment, "save_card_oneclick");
462
+ if (kept !== void 0 && kept !== false)
463
+ return refused("card_on_file");
464
+ const instalments = own(payment, "instalments");
465
+ if (instalments !== void 0 && instalments !== "1" && instalments !== 1)
466
+ return refused("instalments");
467
+ if (own(payment, "payment_type") !== "creditcard")
468
+ return refused("unreviewed_field");
469
+ const country2 = own(payment, "country");
470
+ if (country2 !== void 0 && (typeof country2 !== "string" || country2.toLowerCase() !== parent.country))
471
+ return refused("key_mismatch");
472
+ const code = own(card, "card_cvv");
473
+ if (typeof code !== "string")
474
+ return refused("shape");
475
+ if (parent.cvv === null || code !== parent.cvv)
476
+ return refused("card_mismatch");
477
+ if (own(card, "token") !== token.token)
478
+ return refused("token_mismatch");
479
+ for (const brand of [own(payment, "payment_type_code"), own(card, "payment_type_code")]) {
480
+ if (brand !== void 0 && brand !== token.paymentTypeCode)
481
+ return refused("token_mismatch");
482
+ }
483
+ const unique = own(card, "card_unique_id");
484
+ if (unique !== void 0 && unique !== token.cardUniqueId)
485
+ return refused("token_mismatch");
486
+ const hash2 = own(payment, "hash");
487
+ if (typeof hash2 !== "string" || !INVOICE_HASH.test(hash2) || hash2 !== target.hash || hash2 !== openedHash)
488
+ return refused("session_mismatch");
489
+ if (!threeDsSucceeded(sent[sent.length - 1]))
490
+ return refused("out_of_order");
491
+ return Object.freeze({ ok: true, kind, slot: ofKind + 1 });
492
+ }
493
+ const cardRefusal = threeDsCardRefusal(body, parent);
494
+ if (cardRefusal)
495
+ return refused(cardRefusal);
496
+ let key = own(body, "publicIntegrationKey");
497
+ if (kind === "authentications") {
498
+ const extra = parseObject(own(body, "additionalData"), 4096);
499
+ key = own(extra, "publicIntegrationKey");
500
+ }
501
+ const country = own(body, "country");
502
+ if (!text(key) || !text(country))
503
+ return refused("shape");
504
+ if (key !== parent.publicIntegrationKey || country.toLowerCase() !== parent.country)
505
+ return refused("key_mismatch");
506
+ if (kind === "authentications") {
507
+ const count = own(own(body, "consumerAuthenticationInformation"), "installmentTotalCount");
508
+ if (count === void 0)
509
+ return refused("shape");
510
+ if (count !== "1" && count !== 1)
511
+ return refused("instalments");
512
+ }
513
+ if (!options.skipAmount) {
514
+ const approved = approvedAmount(input.approved);
515
+ if (!approved)
516
+ return refused("amount_unapproved");
517
+ const details = kind === "generate_token" ? body : own(own(body, "orderInformation"), "amountDetails");
518
+ const named = namedAmount(own(details, "totalAmount"), own(details, "currency"));
519
+ if (!named)
520
+ return refused("shape");
521
+ if (named.minor !== approved.minor || named.currency !== approved.currency)
522
+ return refused("amount_mismatch");
523
+ }
524
+ const hash = own(own(body, "paymentInformation"), "paymentHash");
525
+ if (typeof hash !== "string" || !INVOICE_HASH.test(hash))
526
+ return refused("shape");
527
+ if (kind === "generate_token")
528
+ return Object.freeze({ ok: true, kind, slot: ofKind + 1 });
529
+ if (hash !== openedHash)
530
+ return refused("session_mismatch");
531
+ const session = ebanxAnswerSession(generate.answerText);
532
+ if (!session.paymentId || !session.accessToken)
533
+ return refused("session_mismatch");
534
+ if (own(body, "merchantTrackId") !== session.paymentId || own(body, "token") !== session.accessToken)
535
+ return refused("session_mismatch");
536
+ return Object.freeze({ ok: true, kind, slot: ofKind + 1 });
537
+ }
538
+ var CARD_KEY = /^(?:pan|accountnumber|cardnumber|cardcvv|cvv|cvc|cvv2|cvc2|securitycode)$/;
539
+ function ebanxFollowUpAnswerRefusal(answerText) {
540
+ const body = parseObject(answerText, EBANX_FOLLOW_UP_ANSWER_LIMIT);
541
+ if (!body)
542
+ return "answer_unreadable";
543
+ let visits = 0;
544
+ let found = false;
545
+ let exhausted = false;
546
+ const walk = (value, depth) => {
547
+ if (found || exhausted)
548
+ return;
549
+ if (depth > 16 || ++visits > 6e3) {
550
+ exhausted = true;
551
+ return;
552
+ }
553
+ if (Array.isArray(value)) {
554
+ for (const item of value)
555
+ walk(item, depth + 1);
556
+ return;
557
+ }
558
+ if (!record(value))
559
+ return;
560
+ for (const key of Object.keys(value)) {
561
+ const child = value[key];
562
+ if (CARD_KEY.test(key.toLowerCase().replace(/[-_]/g, "")) && child !== null && child !== "" && child !== false && child !== void 0) {
563
+ found = true;
564
+ return;
565
+ }
566
+ walk(child, depth + 1);
567
+ }
568
+ };
569
+ walk(body, 0);
570
+ if (exhausted)
571
+ return "answer_unreadable";
572
+ return found ? "card_in_answer" : null;
573
+ }
574
+ function isEbanxThreeDsFollowUp(kind) {
575
+ return THREE_DS_KINDS.includes(kind);
576
+ }
577
+ export { EBANX_CONFIRM_PATH, EBANX_FOLLOW_UP_ANSWER_LIMIT, EBANX_FOLLOW_UP_BODY_LIMIT, EBANX_FOLLOW_UP_CHALLENGE_MS, EBANX_FOLLOW_UP_IDLE_MS, EBANX_FOLLOW_UP_KINDS, EBANX_FOLLOW_UP_LIMITS, EBANX_FOLLOW_UP_MAX, EBANX_FOLLOW_UP_REFUSALS, EBANX_FOLLOW_UP_WINDOW_MS, EBANX_PAYING_STATUSES, EBANX_RESEND_HOSTS, EBANX_RESEND_REFUSALS, EBANX_THREE_DS_CARD_PATHS, EBANX_THREE_DS_FAILED, EBANX_THREE_DS_FAILED_CODE, ebanxAnswerOutcome, ebanxAnswerRefusal, ebanxAnswerSession, ebanxFollowUpAnswerRefusal, ebanxFollowUpIdleMs, ebanxFollowUpKind, ebanxFollowUpVerdict, ebanxResendKind, ebanxResendRefusal, isEbanxThreeDsFollowUp, readEbanxTokenAnswer, readEbanxTokenRequest };