@ar-agents/mercadopago 0.10.0 → 0.12.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 +55 -0
- package/MIGRATION.md +176 -0
- package/cookbook/09-otel-wired.ts +155 -0
- package/cookbook/README.md +1 -0
- package/dist/audit-B9Nhj3PH.d.cts +294 -0
- package/dist/audit-B9Nhj3PH.d.ts +294 -0
- package/dist/index.cjs +588 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +270 -194
- package/dist/index.d.ts +270 -194
- package/dist/index.js +581 -5
- package/dist/index.js.map +1 -1
- package/dist/vercel-kv.cjs +81 -0
- package/dist/vercel-kv.cjs.map +1 -1
- package/dist/vercel-kv.d.cts +38 -2
- package/dist/vercel-kv.d.ts +38 -2
- package/dist/vercel-kv.js +81 -1
- package/dist/vercel-kv.js.map +1 -1
- package/package.json +4 -3
- package/tools.manifest.json +1 -1
- package/dist/state-C6Wzb_XX.d.cts +0 -106
- package/dist/state-C6Wzb_XX.d.ts +0 -106
package/dist/index.js
CHANGED
|
@@ -226,6 +226,23 @@ var DEFAULT_BASE_URL = "https://api.mercadopago.com";
|
|
|
226
226
|
function sleep(ms) {
|
|
227
227
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
228
228
|
}
|
|
229
|
+
function randomUuid() {
|
|
230
|
+
const c = globalThis.crypto;
|
|
231
|
+
if (c?.randomUUID) {
|
|
232
|
+
return c.randomUUID();
|
|
233
|
+
}
|
|
234
|
+
if (c?.getRandomValues) {
|
|
235
|
+
const bytes = new Uint8Array(16);
|
|
236
|
+
c.getRandomValues(bytes);
|
|
237
|
+
bytes[6] = bytes[6] & 15 | 64;
|
|
238
|
+
bytes[8] = bytes[8] & 63 | 128;
|
|
239
|
+
const hex = Array.from(bytes, (b) => b.toString(16).padStart(2, "0")).join("");
|
|
240
|
+
return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
|
|
241
|
+
}
|
|
242
|
+
throw new Error(
|
|
243
|
+
"MercadoPagoClient: no Web Crypto available for idempotency key generation. This shouldn't happen on Node 19+, Edge Runtime, or modern browsers."
|
|
244
|
+
);
|
|
245
|
+
}
|
|
229
246
|
var MercadoPagoClient = class {
|
|
230
247
|
accessToken;
|
|
231
248
|
baseUrl;
|
|
@@ -269,8 +286,10 @@ var MercadoPagoClient = class {
|
|
|
269
286
|
Authorization: `Bearer ${this.accessToken}`,
|
|
270
287
|
"Content-Type": "application/json"
|
|
271
288
|
};
|
|
272
|
-
|
|
273
|
-
|
|
289
|
+
const isMutatingPost = method === "POST";
|
|
290
|
+
const idempotencyKey = options?.idempotencyKey ?? (isMutatingPost ? randomUuid() : void 0);
|
|
291
|
+
if (idempotencyKey) {
|
|
292
|
+
headers["X-Idempotency-Key"] = idempotencyKey;
|
|
274
293
|
}
|
|
275
294
|
const trace = this.traceContext?.();
|
|
276
295
|
if (trace?.traceId && trace?.spanId) {
|
|
@@ -2427,6 +2446,377 @@ function paginateSubscriptionPayments(client, preapprovalId, opts = {}) {
|
|
|
2427
2446
|
);
|
|
2428
2447
|
}
|
|
2429
2448
|
|
|
2449
|
+
// src/tax-id.ts
|
|
2450
|
+
function validateTaxId(input, type) {
|
|
2451
|
+
switch (type) {
|
|
2452
|
+
case "DNI":
|
|
2453
|
+
return validateAR_DNI(input);
|
|
2454
|
+
case "CUIT":
|
|
2455
|
+
case "CUIL":
|
|
2456
|
+
return validateAR_CUIT(input, type);
|
|
2457
|
+
case "CPF":
|
|
2458
|
+
return validateBR_CPF(input);
|
|
2459
|
+
case "CNPJ":
|
|
2460
|
+
return validateBR_CNPJ(input);
|
|
2461
|
+
case "RFC":
|
|
2462
|
+
return validateMX_RFC(input);
|
|
2463
|
+
case "RUT_CL":
|
|
2464
|
+
return validateCL_RUT(input);
|
|
2465
|
+
case "NIT":
|
|
2466
|
+
return validateCO_NIT(input);
|
|
2467
|
+
case "RUT_UY":
|
|
2468
|
+
return validateUY_RUT(input);
|
|
2469
|
+
case "RUC":
|
|
2470
|
+
return validatePE_RUC(input);
|
|
2471
|
+
}
|
|
2472
|
+
}
|
|
2473
|
+
function validateAR_DNI(input) {
|
|
2474
|
+
const normalized = (input ?? "").replace(/\D/g, "");
|
|
2475
|
+
if (normalized.length === 0) {
|
|
2476
|
+
return failure(normalized, "DNI", "AR", "DNI vac\xEDo.");
|
|
2477
|
+
}
|
|
2478
|
+
if (normalized.length < 7 || normalized.length > 8) {
|
|
2479
|
+
return failure(
|
|
2480
|
+
normalized,
|
|
2481
|
+
"DNI",
|
|
2482
|
+
"AR",
|
|
2483
|
+
`Debe tener 7 u 8 d\xEDgitos; recib\xED ${normalized.length}.`
|
|
2484
|
+
);
|
|
2485
|
+
}
|
|
2486
|
+
return {
|
|
2487
|
+
valid: true,
|
|
2488
|
+
normalized,
|
|
2489
|
+
formatted: normalized.replace(/^(\d{1,2})(\d{3})(\d{3})$/, "$1.$2.$3"),
|
|
2490
|
+
type: "DNI",
|
|
2491
|
+
country: "AR",
|
|
2492
|
+
error: null
|
|
2493
|
+
};
|
|
2494
|
+
}
|
|
2495
|
+
var AR_CHECK_WEIGHTS = [5, 4, 3, 2, 7, 6, 5, 4, 3, 2];
|
|
2496
|
+
function validateAR_CUIT(input, type) {
|
|
2497
|
+
const normalized = (input ?? "").replace(/\D/g, "");
|
|
2498
|
+
if (normalized.length !== 11) {
|
|
2499
|
+
return failure(
|
|
2500
|
+
normalized,
|
|
2501
|
+
type,
|
|
2502
|
+
"AR",
|
|
2503
|
+
`Debe tener 11 d\xEDgitos; recib\xED ${normalized.length}.`
|
|
2504
|
+
);
|
|
2505
|
+
}
|
|
2506
|
+
const sum = AR_CHECK_WEIGHTS.reduce(
|
|
2507
|
+
(acc, w, i) => acc + w * Number(normalized[i]),
|
|
2508
|
+
0
|
|
2509
|
+
);
|
|
2510
|
+
const remainder = sum % 11;
|
|
2511
|
+
const expected = remainder === 0 ? 0 : remainder === 1 ? 9 : 11 - remainder;
|
|
2512
|
+
const actual = Number(normalized[10]);
|
|
2513
|
+
if (actual !== expected) {
|
|
2514
|
+
return failure(
|
|
2515
|
+
normalized,
|
|
2516
|
+
type,
|
|
2517
|
+
"AR",
|
|
2518
|
+
`D\xEDgito verificador inv\xE1lido. Esperado: ${expected}, recibido: ${actual}.`
|
|
2519
|
+
);
|
|
2520
|
+
}
|
|
2521
|
+
return {
|
|
2522
|
+
valid: true,
|
|
2523
|
+
normalized,
|
|
2524
|
+
formatted: `${normalized.slice(0, 2)}-${normalized.slice(2, 10)}-${normalized.slice(10)}`,
|
|
2525
|
+
type,
|
|
2526
|
+
country: "AR",
|
|
2527
|
+
error: null
|
|
2528
|
+
};
|
|
2529
|
+
}
|
|
2530
|
+
function validateBR_CPF(input) {
|
|
2531
|
+
const normalized = (input ?? "").replace(/\D/g, "");
|
|
2532
|
+
if (normalized.length !== 11) {
|
|
2533
|
+
return failure(
|
|
2534
|
+
normalized,
|
|
2535
|
+
"CPF",
|
|
2536
|
+
"BR",
|
|
2537
|
+
`Debe tener 11 d\xEDgitos; recib\xED ${normalized.length}.`
|
|
2538
|
+
);
|
|
2539
|
+
}
|
|
2540
|
+
if (/^(\d)\1{10}$/.test(normalized)) {
|
|
2541
|
+
return failure(normalized, "CPF", "BR", "CPF inv\xE1lido (todos los d\xEDgitos iguales).");
|
|
2542
|
+
}
|
|
2543
|
+
const computeDigit = (slice, weights) => {
|
|
2544
|
+
const sum = weights.reduce((acc, w, i) => acc + w * Number(slice[i]), 0);
|
|
2545
|
+
const r = sum * 10 % 11;
|
|
2546
|
+
return r === 10 ? 0 : r;
|
|
2547
|
+
};
|
|
2548
|
+
const d1 = computeDigit(normalized.slice(0, 9), [10, 9, 8, 7, 6, 5, 4, 3, 2]);
|
|
2549
|
+
const d2 = computeDigit(
|
|
2550
|
+
normalized.slice(0, 10),
|
|
2551
|
+
[11, 10, 9, 8, 7, 6, 5, 4, 3, 2]
|
|
2552
|
+
);
|
|
2553
|
+
if (d1 !== Number(normalized[9]) || d2 !== Number(normalized[10])) {
|
|
2554
|
+
return failure(normalized, "CPF", "BR", "D\xEDgitos verificadores inv\xE1lidos.");
|
|
2555
|
+
}
|
|
2556
|
+
return {
|
|
2557
|
+
valid: true,
|
|
2558
|
+
normalized,
|
|
2559
|
+
formatted: normalized.replace(
|
|
2560
|
+
/^(\d{3})(\d{3})(\d{3})(\d{2})$/,
|
|
2561
|
+
"$1.$2.$3-$4"
|
|
2562
|
+
),
|
|
2563
|
+
type: "CPF",
|
|
2564
|
+
country: "BR",
|
|
2565
|
+
error: null
|
|
2566
|
+
};
|
|
2567
|
+
}
|
|
2568
|
+
function validateBR_CNPJ(input) {
|
|
2569
|
+
const normalized = (input ?? "").replace(/\D/g, "");
|
|
2570
|
+
if (normalized.length !== 14) {
|
|
2571
|
+
return failure(
|
|
2572
|
+
normalized,
|
|
2573
|
+
"CNPJ",
|
|
2574
|
+
"BR",
|
|
2575
|
+
`Debe tener 14 d\xEDgitos; recib\xED ${normalized.length}.`
|
|
2576
|
+
);
|
|
2577
|
+
}
|
|
2578
|
+
if (/^(\d)\1{13}$/.test(normalized)) {
|
|
2579
|
+
return failure(normalized, "CNPJ", "BR", "CNPJ inv\xE1lido (todos los d\xEDgitos iguales).");
|
|
2580
|
+
}
|
|
2581
|
+
const computeDigit = (slice, weights) => {
|
|
2582
|
+
const sum = weights.reduce((acc, w, i) => acc + w * Number(slice[i]), 0);
|
|
2583
|
+
const r = sum % 11;
|
|
2584
|
+
return r < 2 ? 0 : 11 - r;
|
|
2585
|
+
};
|
|
2586
|
+
const w1 = [5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2];
|
|
2587
|
+
const w2 = [6, 5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2];
|
|
2588
|
+
const d1 = computeDigit(normalized.slice(0, 12), w1);
|
|
2589
|
+
const d2 = computeDigit(normalized.slice(0, 13), w2);
|
|
2590
|
+
if (d1 !== Number(normalized[12]) || d2 !== Number(normalized[13])) {
|
|
2591
|
+
return failure(normalized, "CNPJ", "BR", "D\xEDgitos verificadores inv\xE1lidos.");
|
|
2592
|
+
}
|
|
2593
|
+
return {
|
|
2594
|
+
valid: true,
|
|
2595
|
+
normalized,
|
|
2596
|
+
formatted: normalized.replace(
|
|
2597
|
+
/^(\d{2})(\d{3})(\d{3})(\d{4})(\d{2})$/,
|
|
2598
|
+
"$1.$2.$3/$4-$5"
|
|
2599
|
+
),
|
|
2600
|
+
type: "CNPJ",
|
|
2601
|
+
country: "BR",
|
|
2602
|
+
error: null
|
|
2603
|
+
};
|
|
2604
|
+
}
|
|
2605
|
+
function validateMX_RFC(input) {
|
|
2606
|
+
const normalized = (input ?? "").trim().toUpperCase().replace(/[\s-]/g, "");
|
|
2607
|
+
const pfPattern = /^[A-ZÑ&]{4}\d{6}[A-Z\d]{3}$/;
|
|
2608
|
+
const pmPattern = /^[A-ZÑ&]{3}\d{6}[A-Z\d]{3}$/;
|
|
2609
|
+
if (!pfPattern.test(normalized) && !pmPattern.test(normalized)) {
|
|
2610
|
+
return failure(
|
|
2611
|
+
normalized,
|
|
2612
|
+
"RFC",
|
|
2613
|
+
"MX",
|
|
2614
|
+
"RFC mal formado. Persona f\xEDsica: 4 letras + YYMMDD + 3 alfanum\xE9ricos. Persona moral: 3 letras + YYMMDD + 3 alfanum\xE9ricos."
|
|
2615
|
+
);
|
|
2616
|
+
}
|
|
2617
|
+
return {
|
|
2618
|
+
valid: true,
|
|
2619
|
+
normalized,
|
|
2620
|
+
formatted: normalized,
|
|
2621
|
+
type: "RFC",
|
|
2622
|
+
country: "MX",
|
|
2623
|
+
error: null
|
|
2624
|
+
};
|
|
2625
|
+
}
|
|
2626
|
+
function validateCL_RUT(input) {
|
|
2627
|
+
const cleaned = (input ?? "").replace(/[^0-9kK]/g, "").toUpperCase();
|
|
2628
|
+
if (cleaned.length < 2) {
|
|
2629
|
+
return failure(cleaned, "RUT_CL", "CL", "RUT vac\xEDo o muy corto.");
|
|
2630
|
+
}
|
|
2631
|
+
const body = cleaned.slice(0, -1);
|
|
2632
|
+
const dv = cleaned.slice(-1);
|
|
2633
|
+
if (!/^\d+$/.test(body)) {
|
|
2634
|
+
return failure(cleaned, "RUT_CL", "CL", "Cuerpo del RUT debe ser num\xE9rico.");
|
|
2635
|
+
}
|
|
2636
|
+
let sum = 0;
|
|
2637
|
+
let multiplier = 2;
|
|
2638
|
+
for (let i = body.length - 1; i >= 0; i--) {
|
|
2639
|
+
sum += Number(body[i]) * multiplier;
|
|
2640
|
+
multiplier = multiplier === 7 ? 2 : multiplier + 1;
|
|
2641
|
+
}
|
|
2642
|
+
const r = 11 - sum % 11;
|
|
2643
|
+
const expected = r === 11 ? "0" : r === 10 ? "K" : String(r);
|
|
2644
|
+
if (dv !== expected) {
|
|
2645
|
+
return failure(
|
|
2646
|
+
cleaned,
|
|
2647
|
+
"RUT_CL",
|
|
2648
|
+
"CL",
|
|
2649
|
+
`D\xEDgito verificador inv\xE1lido. Esperado: ${expected}, recibido: ${dv}.`
|
|
2650
|
+
);
|
|
2651
|
+
}
|
|
2652
|
+
return {
|
|
2653
|
+
valid: true,
|
|
2654
|
+
normalized: cleaned,
|
|
2655
|
+
formatted: `${formatThousands(body)}-${dv}`,
|
|
2656
|
+
type: "RUT_CL",
|
|
2657
|
+
country: "CL",
|
|
2658
|
+
error: null
|
|
2659
|
+
};
|
|
2660
|
+
}
|
|
2661
|
+
var CO_NIT_WEIGHTS = [3, 7, 13, 17, 19, 23, 29, 37, 41, 43, 47, 53, 59, 67, 71];
|
|
2662
|
+
function validateCO_NIT(input) {
|
|
2663
|
+
const cleaned = (input ?? "").replace(/[^0-9-]/g, "");
|
|
2664
|
+
const parts = cleaned.split("-");
|
|
2665
|
+
if (parts.length !== 2 || !/^\d+$/.test(parts[0]) || !/^\d$/.test(parts[1])) {
|
|
2666
|
+
return failure(
|
|
2667
|
+
cleaned,
|
|
2668
|
+
"NIT",
|
|
2669
|
+
"CO",
|
|
2670
|
+
"NIT debe tener formato: d\xEDgitos + '-' + d\xEDgito verificador."
|
|
2671
|
+
);
|
|
2672
|
+
}
|
|
2673
|
+
const body = parts[0];
|
|
2674
|
+
const dv = Number(parts[1]);
|
|
2675
|
+
if (body.length > CO_NIT_WEIGHTS.length) {
|
|
2676
|
+
return failure(cleaned, "NIT", "CO", "NIT excesivamente largo.");
|
|
2677
|
+
}
|
|
2678
|
+
let sum = 0;
|
|
2679
|
+
for (let i = 0; i < body.length; i++) {
|
|
2680
|
+
sum += Number(body[body.length - 1 - i]) * CO_NIT_WEIGHTS[i];
|
|
2681
|
+
}
|
|
2682
|
+
const r = sum % 11;
|
|
2683
|
+
const expected = r > 1 ? 11 - r : r;
|
|
2684
|
+
if (dv !== expected) {
|
|
2685
|
+
return failure(
|
|
2686
|
+
cleaned,
|
|
2687
|
+
"NIT",
|
|
2688
|
+
"CO",
|
|
2689
|
+
`D\xEDgito verificador inv\xE1lido. Esperado: ${expected}, recibido: ${dv}.`
|
|
2690
|
+
);
|
|
2691
|
+
}
|
|
2692
|
+
return {
|
|
2693
|
+
valid: true,
|
|
2694
|
+
normalized: body + parts[1],
|
|
2695
|
+
formatted: cleaned,
|
|
2696
|
+
type: "NIT",
|
|
2697
|
+
country: "CO",
|
|
2698
|
+
error: null
|
|
2699
|
+
};
|
|
2700
|
+
}
|
|
2701
|
+
var UY_RUT_WEIGHTS = [4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2];
|
|
2702
|
+
function validateUY_RUT(input) {
|
|
2703
|
+
const normalized = (input ?? "").replace(/\D/g, "");
|
|
2704
|
+
if (normalized.length !== 12) {
|
|
2705
|
+
return failure(
|
|
2706
|
+
normalized,
|
|
2707
|
+
"RUT_UY",
|
|
2708
|
+
"UY",
|
|
2709
|
+
`Debe tener 12 d\xEDgitos; recib\xED ${normalized.length}.`
|
|
2710
|
+
);
|
|
2711
|
+
}
|
|
2712
|
+
let sum = 0;
|
|
2713
|
+
for (let i = 0; i < 11; i++) {
|
|
2714
|
+
sum += Number(normalized[i]) * UY_RUT_WEIGHTS[i];
|
|
2715
|
+
}
|
|
2716
|
+
const r = sum % 11;
|
|
2717
|
+
const expected = r === 0 ? 0 : 11 - r;
|
|
2718
|
+
if (Number(normalized[11]) !== expected) {
|
|
2719
|
+
return failure(
|
|
2720
|
+
normalized,
|
|
2721
|
+
"RUT_UY",
|
|
2722
|
+
"UY",
|
|
2723
|
+
`D\xEDgito verificador inv\xE1lido. Esperado: ${expected}, recibido: ${normalized[11]}.`
|
|
2724
|
+
);
|
|
2725
|
+
}
|
|
2726
|
+
return {
|
|
2727
|
+
valid: true,
|
|
2728
|
+
normalized,
|
|
2729
|
+
formatted: normalized.replace(
|
|
2730
|
+
/^(\d{2})(\d{6})(\d{3})(\d{1})$/,
|
|
2731
|
+
"$1$2$3$4"
|
|
2732
|
+
),
|
|
2733
|
+
type: "RUT_UY",
|
|
2734
|
+
country: "UY",
|
|
2735
|
+
error: null
|
|
2736
|
+
};
|
|
2737
|
+
}
|
|
2738
|
+
var PE_RUC_WEIGHTS = [5, 4, 3, 2, 7, 6, 5, 4, 3, 2];
|
|
2739
|
+
function validatePE_RUC(input) {
|
|
2740
|
+
const normalized = (input ?? "").replace(/\D/g, "");
|
|
2741
|
+
if (normalized.length !== 11) {
|
|
2742
|
+
return failure(
|
|
2743
|
+
normalized,
|
|
2744
|
+
"RUC",
|
|
2745
|
+
"PE",
|
|
2746
|
+
`Debe tener 11 d\xEDgitos; recib\xED ${normalized.length}.`
|
|
2747
|
+
);
|
|
2748
|
+
}
|
|
2749
|
+
const prefix = normalized.slice(0, 2);
|
|
2750
|
+
if (!["10", "15", "17", "20"].includes(prefix)) {
|
|
2751
|
+
return failure(
|
|
2752
|
+
normalized,
|
|
2753
|
+
"RUC",
|
|
2754
|
+
"PE",
|
|
2755
|
+
`Prefijo ${prefix} no v\xE1lido. Debe ser 10, 15, 17 o 20.`
|
|
2756
|
+
);
|
|
2757
|
+
}
|
|
2758
|
+
let sum = 0;
|
|
2759
|
+
for (let i = 0; i < 10; i++) {
|
|
2760
|
+
sum += Number(normalized[i]) * PE_RUC_WEIGHTS[i];
|
|
2761
|
+
}
|
|
2762
|
+
const r = 11 - sum % 11;
|
|
2763
|
+
const expected = r === 11 ? 0 : r === 10 ? 1 : r;
|
|
2764
|
+
if (Number(normalized[10]) !== expected) {
|
|
2765
|
+
return failure(
|
|
2766
|
+
normalized,
|
|
2767
|
+
"RUC",
|
|
2768
|
+
"PE",
|
|
2769
|
+
`D\xEDgito verificador inv\xE1lido. Esperado: ${expected}, recibido: ${normalized[10]}.`
|
|
2770
|
+
);
|
|
2771
|
+
}
|
|
2772
|
+
return {
|
|
2773
|
+
valid: true,
|
|
2774
|
+
normalized,
|
|
2775
|
+
formatted: normalized,
|
|
2776
|
+
type: "RUC",
|
|
2777
|
+
country: "PE",
|
|
2778
|
+
error: null
|
|
2779
|
+
};
|
|
2780
|
+
}
|
|
2781
|
+
function failure(normalized, type, country, error) {
|
|
2782
|
+
return {
|
|
2783
|
+
valid: false,
|
|
2784
|
+
normalized,
|
|
2785
|
+
formatted: null,
|
|
2786
|
+
type,
|
|
2787
|
+
country,
|
|
2788
|
+
error
|
|
2789
|
+
};
|
|
2790
|
+
}
|
|
2791
|
+
function formatThousands(s) {
|
|
2792
|
+
return s.replace(/\B(?=(\d{3})+(?!\d))/g, ".");
|
|
2793
|
+
}
|
|
2794
|
+
function detectAndValidate(input, country) {
|
|
2795
|
+
const cleaned = input.replace(/\D/g, "");
|
|
2796
|
+
switch (country) {
|
|
2797
|
+
case "AR": {
|
|
2798
|
+
if (cleaned.length === 7 || cleaned.length === 8) return validateTaxId(input, "DNI");
|
|
2799
|
+
if (cleaned.length === 11) return validateTaxId(input, "CUIT");
|
|
2800
|
+
return null;
|
|
2801
|
+
}
|
|
2802
|
+
case "BR": {
|
|
2803
|
+
if (cleaned.length === 11) return validateTaxId(input, "CPF");
|
|
2804
|
+
if (cleaned.length === 14) return validateTaxId(input, "CNPJ");
|
|
2805
|
+
return null;
|
|
2806
|
+
}
|
|
2807
|
+
case "MX":
|
|
2808
|
+
return validateTaxId(input, "RFC");
|
|
2809
|
+
case "CL":
|
|
2810
|
+
return validateTaxId(input, "RUT_CL");
|
|
2811
|
+
case "CO":
|
|
2812
|
+
return validateTaxId(input, "NIT");
|
|
2813
|
+
case "UY":
|
|
2814
|
+
return validateTaxId(input, "RUT_UY");
|
|
2815
|
+
case "PE":
|
|
2816
|
+
return validateTaxId(input, "RUC");
|
|
2817
|
+
}
|
|
2818
|
+
}
|
|
2819
|
+
|
|
2430
2820
|
// src/test-cards.ts
|
|
2431
2821
|
var TEST_CARDS_AR = {
|
|
2432
2822
|
VISA_CREDIT: {
|
|
@@ -2746,7 +3136,9 @@ var DEFAULT_DESCRIPTIONS = {
|
|
|
2746
3136
|
confirm_3ds_challenge: "After the buyer completes a 3DS challenge (redirected back from challengeUrl), call this to poll MP and confirm whether the payment is now resolved. Polls get_payment up to N times with exponential backoff. Returns { payment, threeDs, resolved, attempts }. USE THIS as the FINAL step in the 3DS flow (after analyze_payment_3ds detected a challenge_required). Without confirming, the payment stays in 'pending' indefinitely from the buyer's perspective.",
|
|
2747
3137
|
// ── v0.10 — Auto-paginate variants ──────────────────────────────────────
|
|
2748
3138
|
search_payments_all: "Collect ALL payments matching a filter \u2014 auto-paginates under the hood. Returns an array (NOT paginated) so the agent doesn't have to manage offset/limit loops manually. SAFETY: pass `max_items` to cap; without it, MP traversal is bounded by the toolkit's internal max (10,000 items) to prevent runaway iterations. USE WHEN the agent needs to enumerate everything (e.g., monthly reconciliation 'all approved payments in March'). For agent flows that only need 'first N matches', pass `max_items` directly.",
|
|
2749
|
-
list_settlements_all: "Collect ALL settlements matching a filter \u2014 auto-paginates. Pass `max_items` to cap. Use for monthly bank-conciliation reports."
|
|
3139
|
+
list_settlements_all: "Collect ALL settlements matching a filter \u2014 auto-paginates. Pass `max_items` to cap. Use for monthly bank-conciliation reports.",
|
|
3140
|
+
// ── v0.11 — TaxID validation cross-LATAM (pure) ──────────────────────────
|
|
3141
|
+
validate_tax_id: "PURE HELPER (no network, sub-ms) \u2014 validates a tax ID against the appropriate country algorithm. Supports AR (DNI/CUIT/CUIL with modulo-11), BR (CPF/CNPJ with two-step weighted modulo), MX (RFC structure), CL (RUT with K digit), CO (NIT modulo-11), UY (RUT 12-digit checksum), PE (RUC 11-digit + prefix validation). Returns { valid, normalized, formatted, type, country, error }. USE THIS BEFORE submitting buyer identification to MP \u2014 invalid tax IDs cause 4xx rejections. Surface the Spanish error verbatim."
|
|
2750
3142
|
};
|
|
2751
3143
|
function mercadoPagoTools(client, options) {
|
|
2752
3144
|
const desc = (name) => options.descriptions?.[name] ?? DEFAULT_DESCRIPTIONS[name];
|
|
@@ -2874,7 +3266,45 @@ function mercadoPagoTools(client, options) {
|
|
|
2874
3266
|
type: z.enum(["DNI", "CUIT", "CUIL"]),
|
|
2875
3267
|
number: z.string()
|
|
2876
3268
|
}).optional().describe("Payer identification \u2014 required for some payment types in AR"),
|
|
2877
|
-
statement_descriptor: z.string().max(13).optional().describe("Shows on buyer's card statement (max 13 chars)")
|
|
3269
|
+
statement_descriptor: z.string().max(13).optional().describe("Shows on buyer's card statement (max 13 chars)"),
|
|
3270
|
+
// v0.11 — fraud scoring enrichment fields
|
|
3271
|
+
additional_info: z.object({
|
|
3272
|
+
ip_address: z.string().optional().describe(
|
|
3273
|
+
"Buyer's IP address (from req.headers X-Forwarded-For). STRONGLY RECOMMENDED for card payments \u2014 improves MP fraud scoring confidence and reduces false-positive rejections (3-5x lower per RG 5286/2023)."
|
|
3274
|
+
),
|
|
3275
|
+
referral_url: z.string().url().optional().describe("Page the buyer came from"),
|
|
3276
|
+
payer: z.object({
|
|
3277
|
+
first_name: z.string().optional(),
|
|
3278
|
+
last_name: z.string().optional(),
|
|
3279
|
+
phone: z.object({ area_code: z.string().optional(), number: z.string().optional() }).optional(),
|
|
3280
|
+
address: z.object({
|
|
3281
|
+
zip_code: z.string().optional(),
|
|
3282
|
+
street_name: z.string().optional(),
|
|
3283
|
+
street_number: z.number().optional()
|
|
3284
|
+
}).optional(),
|
|
3285
|
+
registration_date: z.string().optional().describe("ISO 8601 \u2014 when the buyer registered on YOUR platform"),
|
|
3286
|
+
authentication_type: z.string().optional(),
|
|
3287
|
+
is_prime_user: z.boolean().optional(),
|
|
3288
|
+
is_first_purchase_online: z.boolean().optional(),
|
|
3289
|
+
last_purchase: z.string().optional()
|
|
3290
|
+
}).optional(),
|
|
3291
|
+
shipments: z.object({
|
|
3292
|
+
receiver_address: z.object({
|
|
3293
|
+
zip_code: z.string().optional(),
|
|
3294
|
+
street_name: z.string().optional(),
|
|
3295
|
+
street_number: z.number().optional(),
|
|
3296
|
+
floor: z.string().optional(),
|
|
3297
|
+
apartment: z.string().optional(),
|
|
3298
|
+
city_name: z.string().optional(),
|
|
3299
|
+
state_name: z.string().optional(),
|
|
3300
|
+
country_name: z.string().optional()
|
|
3301
|
+
}).optional(),
|
|
3302
|
+
express_shipment: z.boolean().optional(),
|
|
3303
|
+
local_pickup: z.boolean().optional()
|
|
3304
|
+
}).optional()
|
|
3305
|
+
}).optional().describe(
|
|
3306
|
+
"Fraud scoring enrichment. Pass IP address + payer profile + shipping address for materially better approval rates on card payments."
|
|
3307
|
+
)
|
|
2878
3308
|
}),
|
|
2879
3309
|
execute: async (input) => {
|
|
2880
3310
|
const payment = await client.createPayment({
|
|
@@ -2887,6 +3317,7 @@ function mercadoPagoTools(client, options) {
|
|
|
2887
3317
|
...input.external_reference !== void 0 ? { externalReference: input.external_reference } : {},
|
|
2888
3318
|
...input.identification !== void 0 ? { identification: input.identification } : {},
|
|
2889
3319
|
...input.statement_descriptor !== void 0 ? { statementDescriptor: input.statement_descriptor } : {},
|
|
3320
|
+
...input.additional_info !== void 0 ? { additionalInfo: input.additional_info } : {},
|
|
2890
3321
|
...options.notificationUrl !== void 0 ? { notificationUrl: options.notificationUrl } : {},
|
|
2891
3322
|
// Deterministic idempotency key — safe to retry, same inputs always
|
|
2892
3323
|
// produce the same key (MP dedupes on its side).
|
|
@@ -4640,6 +5071,34 @@ function mercadoPagoTools(client, options) {
|
|
|
4640
5071
|
const all = await collect(paginateSettlements(client, filterClean, opts));
|
|
4641
5072
|
return { ok: true, count: all.length, settlements: all };
|
|
4642
5073
|
}
|
|
5074
|
+
}),
|
|
5075
|
+
// ─────────────────────────────────────────────────────────────────────
|
|
5076
|
+
// v0.11 — TaxID validation cross-LATAM (pure)
|
|
5077
|
+
// ─────────────────────────────────────────────────────────────────────
|
|
5078
|
+
validate_tax_id: tool({
|
|
5079
|
+
description: desc("validate_tax_id"),
|
|
5080
|
+
inputSchema: z.object({
|
|
5081
|
+
tax_id: z.string().min(1).describe(
|
|
5082
|
+
"The tax ID to validate. Accepts any format with or without separators (20-41758101-5, 20.41758101.5, 20417581015 all work for AR CUIT)."
|
|
5083
|
+
),
|
|
5084
|
+
type: z.enum([
|
|
5085
|
+
"DNI",
|
|
5086
|
+
"CUIT",
|
|
5087
|
+
"CUIL",
|
|
5088
|
+
"CPF",
|
|
5089
|
+
"CNPJ",
|
|
5090
|
+
"RFC",
|
|
5091
|
+
"RUT_CL",
|
|
5092
|
+
"NIT",
|
|
5093
|
+
"RUT_UY",
|
|
5094
|
+
"RUC"
|
|
5095
|
+
]).describe(
|
|
5096
|
+
"TaxID type. AR: DNI/CUIT/CUIL. BR: CPF (persona f\xEDsica) / CNPJ (persona jur\xEDdica). MX: RFC. CL: RUT_CL. CO: NIT. UY: RUT_UY. PE: RUC."
|
|
5097
|
+
)
|
|
5098
|
+
}),
|
|
5099
|
+
execute: async ({ tax_id, type }) => {
|
|
5100
|
+
return validateTaxId(tax_id, type);
|
|
5101
|
+
}
|
|
4643
5102
|
})
|
|
4644
5103
|
};
|
|
4645
5104
|
}
|
|
@@ -5150,6 +5609,123 @@ function sleep2(ms) {
|
|
|
5150
5609
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
5151
5610
|
}
|
|
5152
5611
|
|
|
5153
|
-
|
|
5612
|
+
// src/middleware.ts
|
|
5613
|
+
function compose(...middlewares) {
|
|
5614
|
+
return (tool2) => {
|
|
5615
|
+
return middlewares.reduceRight((wrapped, mw) => mw(wrapped), tool2);
|
|
5616
|
+
};
|
|
5617
|
+
}
|
|
5618
|
+
function withAuditLog(logger, operation, actor) {
|
|
5619
|
+
return (tool2) => {
|
|
5620
|
+
const original = tool2.execute;
|
|
5621
|
+
if (!original) return tool2;
|
|
5622
|
+
return {
|
|
5623
|
+
...tool2,
|
|
5624
|
+
execute: (async (input, opts) => {
|
|
5625
|
+
return logger.record({
|
|
5626
|
+
operation,
|
|
5627
|
+
input,
|
|
5628
|
+
...actor !== void 0 ? { actor } : {},
|
|
5629
|
+
fn: () => original(input, opts)
|
|
5630
|
+
});
|
|
5631
|
+
})
|
|
5632
|
+
};
|
|
5633
|
+
};
|
|
5634
|
+
}
|
|
5635
|
+
function withRateLimit(limiter) {
|
|
5636
|
+
return (tool2) => {
|
|
5637
|
+
const original = tool2.execute;
|
|
5638
|
+
if (!original) return tool2;
|
|
5639
|
+
return {
|
|
5640
|
+
...tool2,
|
|
5641
|
+
execute: (async (input, opts) => {
|
|
5642
|
+
await limiter.acquire();
|
|
5643
|
+
return original(input, opts);
|
|
5644
|
+
})
|
|
5645
|
+
};
|
|
5646
|
+
};
|
|
5647
|
+
}
|
|
5648
|
+
function withMetrics(toolName, hook) {
|
|
5649
|
+
return (tool2) => {
|
|
5650
|
+
const original = tool2.execute;
|
|
5651
|
+
if (!original) return tool2;
|
|
5652
|
+
return {
|
|
5653
|
+
...tool2,
|
|
5654
|
+
execute: (async (input, opts) => {
|
|
5655
|
+
const t0 = Date.now();
|
|
5656
|
+
try {
|
|
5657
|
+
const result = await original(input, opts);
|
|
5658
|
+
hook.onMetric({
|
|
5659
|
+
toolName,
|
|
5660
|
+
durationMs: Date.now() - t0,
|
|
5661
|
+
success: true
|
|
5662
|
+
});
|
|
5663
|
+
return result;
|
|
5664
|
+
} catch (err) {
|
|
5665
|
+
hook.onMetric({
|
|
5666
|
+
toolName,
|
|
5667
|
+
durationMs: Date.now() - t0,
|
|
5668
|
+
success: false,
|
|
5669
|
+
errorCode: extractErrorCode2(err)
|
|
5670
|
+
});
|
|
5671
|
+
throw err;
|
|
5672
|
+
}
|
|
5673
|
+
})
|
|
5674
|
+
};
|
|
5675
|
+
};
|
|
5676
|
+
}
|
|
5677
|
+
var defaultShouldRetry = (err) => {
|
|
5678
|
+
if (err && typeof err === "object" && "status" in err) {
|
|
5679
|
+
const status = err.status;
|
|
5680
|
+
if (typeof status === "number" && status >= 400 && status < 500) {
|
|
5681
|
+
return false;
|
|
5682
|
+
}
|
|
5683
|
+
}
|
|
5684
|
+
return true;
|
|
5685
|
+
};
|
|
5686
|
+
function withRetry(opts = {}) {
|
|
5687
|
+
const maxAttempts = opts.maxAttempts ?? 3;
|
|
5688
|
+
const baseBackoff = opts.baseBackoffMs ?? 250;
|
|
5689
|
+
const shouldRetry = opts.shouldRetry ?? defaultShouldRetry;
|
|
5690
|
+
return (tool2) => {
|
|
5691
|
+
const original = tool2.execute;
|
|
5692
|
+
if (!original) return tool2;
|
|
5693
|
+
return {
|
|
5694
|
+
...tool2,
|
|
5695
|
+
execute: (async (input, opts2) => {
|
|
5696
|
+
let attempt = 0;
|
|
5697
|
+
while (true) {
|
|
5698
|
+
try {
|
|
5699
|
+
return await original(input, opts2);
|
|
5700
|
+
} catch (err) {
|
|
5701
|
+
attempt++;
|
|
5702
|
+
if (attempt >= maxAttempts || !shouldRetry(err, attempt)) {
|
|
5703
|
+
throw err;
|
|
5704
|
+
}
|
|
5705
|
+
const delayMs = baseBackoff * Math.pow(2, attempt - 1);
|
|
5706
|
+
opts.onRetry?.({ attempt, error: err, delayMs });
|
|
5707
|
+
await new Promise((r) => setTimeout(r, delayMs));
|
|
5708
|
+
}
|
|
5709
|
+
}
|
|
5710
|
+
})
|
|
5711
|
+
};
|
|
5712
|
+
};
|
|
5713
|
+
}
|
|
5714
|
+
function applyToAllTools(tools, middleware) {
|
|
5715
|
+
const out = {};
|
|
5716
|
+
for (const [name, tool2] of Object.entries(tools)) {
|
|
5717
|
+
out[name] = middleware(tool2);
|
|
5718
|
+
}
|
|
5719
|
+
return out;
|
|
5720
|
+
}
|
|
5721
|
+
function extractErrorCode2(err) {
|
|
5722
|
+
if (err && typeof err === "object") {
|
|
5723
|
+
const e = err;
|
|
5724
|
+
return e.code ?? e.name ?? "unknown_error";
|
|
5725
|
+
}
|
|
5726
|
+
return "unknown_error";
|
|
5727
|
+
}
|
|
5728
|
+
|
|
5729
|
+
export { AHORA_PROGRAM_PROMOS, AR_ISSUER_PROMOS, AuditLogger, CircuitBreaker, CircuitOpenError, InMemoryAuditLog, InMemoryIdempotencyCache, InMemoryOAuthTokenStore, InMemoryStateAdapter, MercadoPagoAccountTypeMismatchError, MercadoPagoAuthError, MercadoPagoAuthorizeForbiddenError, MercadoPagoBackUrlInvalidError, MercadoPagoClient, MercadoPagoError, MercadoPagoOverloadedError, MercadoPagoPaymentRejectedError, MercadoPagoRateLimitError, MercadoPagoSelfPaymentError, MercadoPagoTimeoutError, RateLimitTimeoutError, TEST_CARDS_AR, TEST_PAYERS_AR, TokenBucketRateLimiter, WebhookDedup, analyze3DS, applyToAllTools, buildAuthorizeUrl, buildTestCardScenario, classifyError, collect, compose, computeMarketplaceFee, confirmChallengeAndPoll, detectAndValidate, exchangeCodeForToken, expirationTimeMs, explainPaymentStatus, findApplicablePromos, isExpiringSoon, mercadoPagoTools, paginate, paginateAccountMovements, paginateMerchantOrders, paginatePayments, paginateSettlements, paginateSubscriptionPayments, paginateSubscriptionPlans, paginateSubscriptions, parseWebhookEvent, refreshAccessToken, validateTaxId, verifyWebhookSignature, withAuditLog, withMetrics, withRateLimit, withRetry };
|
|
5154
5730
|
//# sourceMappingURL=index.js.map
|
|
5155
5731
|
//# sourceMappingURL=index.js.map
|