@yoryoboy/bi-mcp 1.16.0 → 1.17.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.
Files changed (27) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/index.js +34 -1
  3. package/dist/index.js.map +2 -2
  4. package/dist/mcp-use.json +2 -2
  5. package/dist/src/services/mercadolibre/__tests__/mercadolibre-payments.test.js +137 -0
  6. package/dist/src/services/mercadolibre/__tests__/mercadolibre-payments.test.js.map +7 -0
  7. package/dist/src/services/mercadolibre/mercadolibre-api.js +2 -2
  8. package/dist/src/services/mercadolibre/mercadolibre-api.js.map +2 -2
  9. package/dist/src/services/mercadolibre/mercadolibre-billing.js +93 -1
  10. package/dist/src/services/mercadolibre/mercadolibre-billing.js.map +2 -2
  11. package/dist/src/services/mercadolibre/mercadolibre-payments.js +60 -0
  12. package/dist/src/services/mercadolibre/mercadolibre-payments.js.map +7 -0
  13. package/dist/src/tools/mercadolibre/get-billing-provisions-by-order.js +284 -0
  14. package/dist/src/tools/mercadolibre/get-billing-provisions-by-order.js.map +7 -0
  15. package/dist/src/tools/mercadolibre/get-full-storage-charges.js +183 -0
  16. package/dist/src/tools/mercadolibre/get-full-storage-charges.js.map +7 -0
  17. package/dist/src/tools/mercadolibre/get-payment-details.js +322 -0
  18. package/dist/src/tools/mercadolibre/get-payment-details.js.map +7 -0
  19. package/dist/src/tools/mercadolibre/index.js +20 -0
  20. package/dist/src/tools/mercadolibre/index.js.map +2 -2
  21. package/dist/tests/meli/mercadolibre-billing-provisions.test.js +176 -0
  22. package/dist/tests/meli/mercadolibre-billing-provisions.test.js.map +2 -2
  23. package/dist/tests/meli/mercadolibre-payment-details.test.js +356 -0
  24. package/dist/tests/meli/mercadolibre-payment-details.test.js.map +7 -0
  25. package/dist/tests/meli/mercadolibre-payments.test.js +62 -0
  26. package/dist/tests/meli/mercadolibre-payments.test.js.map +7 -0
  27. package/package.json +1 -1
@@ -0,0 +1,322 @@
1
+ import { error, object } from "mcp-use/server";
2
+ import { z } from "zod";
3
+ import { formatMercadoLibreError } from "../../services/mercadolibre/mercadolibre-api.js";
4
+ import {
5
+ getMercadoLibrePaymentDetails,
6
+ getMercadoLibrePaymentDetailsBatch
7
+ } from "../../services/mercadolibre/mercadolibre-payments.js";
8
+ import { stripNulls } from "../../utils/strip-payload.js";
9
+ import {
10
+ asArray,
11
+ asRecord,
12
+ compactDateTime,
13
+ currencyBucket,
14
+ normalizeScalarString,
15
+ normalizeString,
16
+ roundMoney,
17
+ toNumber
18
+ } from "./helpers.js";
19
+ import { resolveMercadoLibreProfileOrSelection } from "./profile-resolution.js";
20
+ import { mercadolibreProfileIdSchemaField } from "./write-helpers.js";
21
+ const MAX_PAYMENT_IDS = 250;
22
+ const paymentIdSchemaField = z.string().trim().min(1).describe("MercadoLibre payment id to inspect.");
23
+ const meliGetPaymentDetailsSchema = z.object({
24
+ profileId: mercadolibreProfileIdSchemaField,
25
+ paymentId: paymentIdSchemaField.optional().describe("Single MercadoLibre payment id to inspect."),
26
+ paymentIds: z.array(paymentIdSchemaField).min(1).max(MAX_PAYMENT_IDS).describe("One or more MercadoLibre payment ids to inspect in parallel (up to 250, processed in chunks of 50).").optional()
27
+ }).superRefine((value, ctx) => {
28
+ const hasPaymentId = Boolean(value.paymentId);
29
+ const hasPaymentIds = Boolean(value.paymentIds?.length);
30
+ if (hasPaymentId === hasPaymentIds) {
31
+ ctx.addIssue({
32
+ code: z.ZodIssueCode.custom,
33
+ message: "Provide exactly one of paymentId or paymentIds.",
34
+ path: ["paymentId"]
35
+ });
36
+ ctx.addIssue({
37
+ code: z.ZodIssueCode.custom,
38
+ message: "Provide exactly one of paymentId or paymentIds.",
39
+ path: ["paymentIds"]
40
+ });
41
+ }
42
+ });
43
+ const paymentsSchema = [
44
+ "payment_id",
45
+ "status",
46
+ "status_detail",
47
+ "currency_id",
48
+ "transaction_amount",
49
+ "total_paid_amount",
50
+ "net_received_amount",
51
+ "overpaid_amount",
52
+ "payment_method_id",
53
+ "payment_type_id",
54
+ "installments",
55
+ "date_created",
56
+ "date_last_updated",
57
+ "description",
58
+ "order_id",
59
+ "payer_id",
60
+ "payer_email",
61
+ "payer_type",
62
+ "payer_first_name",
63
+ "payer_last_name",
64
+ "fee_count",
65
+ "fee_total",
66
+ "external_reference"
67
+ ];
68
+ const paymentFeeDetailsSchema = ["payment_id", "fee_type", "fee_amount"];
69
+ function createCurrencyTotals() {
70
+ return {
71
+ count: 0,
72
+ transaction_amount: 0,
73
+ total_paid_amount: 0,
74
+ net_received_amount: 0,
75
+ overpaid_amount: 0,
76
+ fee_total: 0
77
+ };
78
+ }
79
+ function incrementCounter(store, key) {
80
+ const normalizedKey = key.trim() || "UNKNOWN";
81
+ store[normalizedKey] = (store[normalizedKey] ?? 0) + 1;
82
+ }
83
+ function projectPayment(payment) {
84
+ const paymentId = normalizeScalarString(payment.id) || "";
85
+ const transactionDetails = asRecord(payment.transaction_details);
86
+ const payer = asRecord(payment.payer);
87
+ const order = asRecord(payment.order);
88
+ const feeDetails = asArray(payment.fee_details);
89
+ const currencyId = normalizeString(payment.currency_id, "UNKNOWN") || "UNKNOWN";
90
+ const status = normalizeString(payment.status, "UNKNOWN") || "UNKNOWN";
91
+ const paymentMethodId = normalizeScalarString(payment.payment_method_id) || normalizeScalarString(asRecord(payment.payment_method).id) || "UNKNOWN";
92
+ const paymentTypeId = normalizeString(payment.payment_type_id) || "UNKNOWN";
93
+ const transactionAmount = toNumber(payment.transaction_amount);
94
+ const totalPaidAmount = toNumber(transactionDetails.total_paid_amount ?? payment.total_paid_amount);
95
+ const netReceivedAmount = toNumber(transactionDetails.net_received_amount);
96
+ const overpaidAmount = toNumber(transactionDetails.overpaid_amount);
97
+ const feeTotal = roundMoney(feeDetails.reduce((accumulator, fee) => accumulator + toNumber(fee.amount), 0));
98
+ const dateCreated = compactDateTime(payment.date_created);
99
+ const dateLastUpdated = compactDateTime(payment.date_last_updated ?? payment.last_updated);
100
+ const description = normalizeString(payment.description);
101
+ const orderId = normalizeScalarString(order.id) || null;
102
+ const payerId = normalizeScalarString(payer.id) || null;
103
+ const payerEmail = normalizeString(payer.email);
104
+ const payerType = normalizeString(payer.type);
105
+ const payerFirstName = normalizeString(payer.first_name);
106
+ const payerLastName = normalizeString(payer.last_name);
107
+ const externalReference = normalizeString(transactionDetails.external_reference);
108
+ return {
109
+ row: [
110
+ paymentId || null,
111
+ normalizeString(payment.status) || null,
112
+ normalizeString(payment.status_detail) || null,
113
+ currencyId,
114
+ transactionAmount,
115
+ totalPaidAmount,
116
+ netReceivedAmount,
117
+ overpaidAmount,
118
+ paymentMethodId,
119
+ paymentTypeId,
120
+ toNumber(payment.installments),
121
+ dateCreated,
122
+ dateLastUpdated,
123
+ description || null,
124
+ orderId,
125
+ payerId,
126
+ payerEmail || null,
127
+ payerType || null,
128
+ payerFirstName || null,
129
+ payerLastName || null,
130
+ feeDetails.length,
131
+ feeTotal,
132
+ externalReference || null
133
+ ],
134
+ feeRows: feeDetails.map((fee) => [
135
+ paymentId || null,
136
+ normalizeString(fee.type) || null,
137
+ toNumber(fee.amount)
138
+ ]),
139
+ paymentId,
140
+ currencyId,
141
+ status,
142
+ paymentMethodId,
143
+ paymentTypeId,
144
+ hasOrder: Boolean(orderId),
145
+ hasPayer: Boolean(payerId || payerEmail),
146
+ feeTotal
147
+ };
148
+ }
149
+ function buildBreakdownEntries(store) {
150
+ const total = Object.values(store).reduce((accumulator, value) => accumulator + value, 0);
151
+ return Object.entries(store).map(([key, count]) => ({
152
+ key,
153
+ count,
154
+ rate: total > 0 ? roundMoney(count / total) : 0
155
+ })).sort((left, right) => right.count - left.count || left.key.localeCompare(right.key));
156
+ }
157
+ function buildCurrencyBreakdowns(store) {
158
+ return Object.entries(store).map(([currencyId, totals]) => ({
159
+ currency_id: currencyId,
160
+ count: totals.count,
161
+ transaction_amount: roundMoney(totals.transaction_amount),
162
+ total_paid_amount: roundMoney(totals.total_paid_amount),
163
+ net_received_amount: roundMoney(totals.net_received_amount),
164
+ overpaid_amount: roundMoney(totals.overpaid_amount),
165
+ fee_total: roundMoney(totals.fee_total)
166
+ })).sort((left, right) => right.count - left.count || left.currency_id.localeCompare(right.currency_id));
167
+ }
168
+ function buildAlerts(params) {
169
+ const alerts = [];
170
+ if (params.failedCount > 0) {
171
+ alerts.push(`${params.failedCount} payment${params.failedCount === 1 ? "" : "s"} failed to fetch.`);
172
+ }
173
+ if (params.successfulCount === 0 && params.failedCount > 0) {
174
+ alerts.push("No payments were successfully retrieved.");
175
+ }
176
+ if (params.paymentsWithoutOrderCount > 0) {
177
+ alerts.push(
178
+ `${params.paymentsWithoutOrderCount} payment${params.paymentsWithoutOrderCount === 1 ? "" : "s"} do not include an order reference.`
179
+ );
180
+ }
181
+ if (params.paymentsWithoutPayerCount > 0) {
182
+ alerts.push(
183
+ `${params.paymentsWithoutPayerCount} payment${params.paymentsWithoutPayerCount === 1 ? "" : "s"} are missing payer data.`
184
+ );
185
+ }
186
+ if (params.currenciesObserved.length > 1) {
187
+ alerts.push(`Multiple currencies detected: ${params.currenciesObserved.join(", ")}.`);
188
+ }
189
+ return alerts;
190
+ }
191
+ function buildPaymentPayload(params) {
192
+ const currencyTotals = {};
193
+ const statusCounts = {};
194
+ const paymentMethodCounts = {};
195
+ const paymentTypeCounts = {};
196
+ const payments = [];
197
+ const feeDetailRows = [];
198
+ let paymentsWithOrderCount = 0;
199
+ let paymentsWithoutOrderCount = 0;
200
+ let paymentsWithoutPayerCount = 0;
201
+ for (const projection of params.successful) {
202
+ payments.push(projection.row);
203
+ feeDetailRows.push(...projection.feeRows);
204
+ const currencyBucketTotals = currencyBucket(currencyTotals, projection.currencyId, createCurrencyTotals);
205
+ currencyBucketTotals.count += 1;
206
+ currencyBucketTotals.transaction_amount += projection.row[4] ? Number(projection.row[4]) : 0;
207
+ currencyBucketTotals.total_paid_amount += projection.row[5] ? Number(projection.row[5]) : 0;
208
+ currencyBucketTotals.net_received_amount += projection.row[6] ? Number(projection.row[6]) : 0;
209
+ currencyBucketTotals.overpaid_amount += projection.row[7] ? Number(projection.row[7]) : 0;
210
+ currencyBucketTotals.fee_total += projection.feeTotal;
211
+ incrementCounter(statusCounts, projection.status);
212
+ incrementCounter(paymentMethodCounts, projection.paymentMethodId);
213
+ incrementCounter(paymentTypeCounts, projection.paymentTypeId);
214
+ if (projection.hasOrder) {
215
+ paymentsWithOrderCount += 1;
216
+ } else {
217
+ paymentsWithoutOrderCount += 1;
218
+ }
219
+ if (!projection.hasPayer) {
220
+ paymentsWithoutPayerCount += 1;
221
+ }
222
+ }
223
+ const currenciesObserved = Object.keys(currencyTotals).sort((left, right) => left.localeCompare(right));
224
+ const summary = {
225
+ requested_count: params.requestedPaymentIds.length,
226
+ successful_count: params.successful.length,
227
+ failed_count: params.failed.length,
228
+ payments_with_order_count: paymentsWithOrderCount,
229
+ payments_without_order_count: paymentsWithoutOrderCount,
230
+ payments_without_payer_count: paymentsWithoutPayerCount,
231
+ currency_totals: Object.fromEntries(
232
+ Object.entries(currencyTotals).map(([currencyId, totals]) => [currencyId, stripNulls({
233
+ count: totals.count,
234
+ transaction_amount: roundMoney(totals.transaction_amount),
235
+ total_paid_amount: roundMoney(totals.total_paid_amount),
236
+ net_received_amount: roundMoney(totals.net_received_amount),
237
+ overpaid_amount: roundMoney(totals.overpaid_amount),
238
+ fee_total: roundMoney(totals.fee_total)
239
+ })])
240
+ ),
241
+ status_counts: statusCounts,
242
+ payment_method_counts: paymentMethodCounts,
243
+ payment_type_counts: paymentTypeCounts
244
+ };
245
+ const breakdowns = stripNulls({
246
+ by_currency: buildCurrencyBreakdowns(currencyTotals),
247
+ by_status: buildBreakdownEntries(statusCounts),
248
+ by_payment_method: buildBreakdownEntries(paymentMethodCounts),
249
+ by_payment_type: buildBreakdownEntries(paymentTypeCounts)
250
+ });
251
+ const alerts = buildAlerts({
252
+ successfulCount: params.successful.length,
253
+ failedCount: params.failed.length,
254
+ paymentsWithoutOrderCount,
255
+ paymentsWithoutPayerCount,
256
+ currenciesObserved
257
+ });
258
+ const payload = stripNulls({
259
+ metadata: {
260
+ profile_id: params.profileId,
261
+ endpoint: "/v1/payments/{payment_id}",
262
+ mode: params.requestedPaymentIds.length === 1 ? "single" : "batch",
263
+ requested_count: params.requestedPaymentIds.length,
264
+ successful_count: params.successful.length,
265
+ failed_count: params.failed.length,
266
+ coverage_complete: params.failed.length === 0,
267
+ requested_payment_ids: params.requestedPaymentIds,
268
+ successful_payment_ids: params.successful.map((entry) => entry.paymentId),
269
+ failed_payment_ids: params.failed.map((entry) => entry.paymentId)
270
+ },
271
+ summary,
272
+ breakdowns,
273
+ alerts,
274
+ failures: params.failed
275
+ });
276
+ return {
277
+ ...payload,
278
+ payments_schema: paymentsSchema,
279
+ payments,
280
+ payment_fee_details_schema: paymentFeeDetailsSchema,
281
+ payment_fee_details: feeDetailRows
282
+ };
283
+ }
284
+ async function meliGetPaymentDetailsHandler(params) {
285
+ try {
286
+ const profileResolution = await resolveMercadoLibreProfileOrSelection(params.profileId);
287
+ if (!profileResolution.ok) {
288
+ return profileResolution.response;
289
+ }
290
+ const profileId = profileResolution.value.profileId;
291
+ if (params.paymentId) {
292
+ const payment = await getMercadoLibrePaymentDetails(profileId, params.paymentId);
293
+ const projected = projectPayment(payment);
294
+ return object(
295
+ buildPaymentPayload({
296
+ profileId,
297
+ requestedPaymentIds: [params.paymentId],
298
+ successful: [projected],
299
+ failed: []
300
+ })
301
+ );
302
+ }
303
+ const batch = await getMercadoLibrePaymentDetailsBatch(profileId, params.paymentIds ?? []);
304
+ return object(
305
+ buildPaymentPayload({
306
+ profileId,
307
+ requestedPaymentIds: params.paymentIds ?? [],
308
+ successful: batch.successful.map((entry) => projectPayment(entry.payment)),
309
+ failed: batch.failed
310
+ })
311
+ );
312
+ } catch (err) {
313
+ return error(formatMercadoLibreError(err, "Failed to fetch MercadoLibre payment details"));
314
+ }
315
+ }
316
+ export {
317
+ meliGetPaymentDetailsHandler,
318
+ meliGetPaymentDetailsSchema,
319
+ paymentFeeDetailsSchema,
320
+ paymentsSchema
321
+ };
322
+ //# sourceMappingURL=get-payment-details.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/tools/mercadolibre/get-payment-details.ts"],
4
+ "sourcesContent": ["import { error, object } from \"mcp-use/server\";\nimport { z } from \"zod\";\n\nimport { formatMercadoLibreError } from \"../../services/mercadolibre/mercadolibre-api.js\";\nimport {\n getMercadoLibrePaymentDetails,\n getMercadoLibrePaymentDetailsBatch,\n} from \"../../services/mercadolibre/mercadolibre-payments.js\";\nimport { stripNulls } from \"../../utils/strip-payload.js\";\nimport {\n asArray,\n asRecord,\n compactDateTime,\n currencyBucket,\n normalizeScalarString,\n normalizeString,\n roundMoney,\n toNumber,\n} from \"./helpers.js\";\nimport { resolveMercadoLibreProfileOrSelection } from \"./profile-resolution.js\";\nimport { mercadolibreProfileIdSchemaField } from \"./write-helpers.js\";\n\nconst MAX_PAYMENT_IDS = 250;\n\nconst paymentIdSchemaField = z\n .string()\n .trim()\n .min(1)\n .describe(\"MercadoLibre payment id to inspect.\");\n\nexport const meliGetPaymentDetailsSchema = z\n .object({\n profileId: mercadolibreProfileIdSchemaField,\n paymentId: paymentIdSchemaField.optional().describe(\"Single MercadoLibre payment id to inspect.\"),\n paymentIds: z\n .array(paymentIdSchemaField)\n .min(1)\n .max(MAX_PAYMENT_IDS)\n .describe(\"One or more MercadoLibre payment ids to inspect in parallel (up to 250, processed in chunks of 50).\")\n .optional(),\n })\n .superRefine((value, ctx) => {\n const hasPaymentId = Boolean(value.paymentId);\n const hasPaymentIds = Boolean(value.paymentIds?.length);\n\n if (hasPaymentId === hasPaymentIds) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: \"Provide exactly one of paymentId or paymentIds.\",\n path: [\"paymentId\"],\n });\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: \"Provide exactly one of paymentId or paymentIds.\",\n path: [\"paymentIds\"],\n });\n }\n });\n\nexport const paymentsSchema = [\n \"payment_id\",\n \"status\",\n \"status_detail\",\n \"currency_id\",\n \"transaction_amount\",\n \"total_paid_amount\",\n \"net_received_amount\",\n \"overpaid_amount\",\n \"payment_method_id\",\n \"payment_type_id\",\n \"installments\",\n \"date_created\",\n \"date_last_updated\",\n \"description\",\n \"order_id\",\n \"payer_id\",\n \"payer_email\",\n \"payer_type\",\n \"payer_first_name\",\n \"payer_last_name\",\n \"fee_count\",\n \"fee_total\",\n \"external_reference\",\n] as const;\n\nexport const paymentFeeDetailsSchema = [\"payment_id\", \"fee_type\", \"fee_amount\"] as const;\n\ntype PaymentRow = (string | number | null)[];\ntype FeeRow = (string | number | null)[];\n\ntype PaymentProjection = {\n row: PaymentRow;\n feeRows: FeeRow[];\n paymentId: string;\n currencyId: string;\n status: string;\n paymentMethodId: string;\n paymentTypeId: string;\n hasOrder: boolean;\n hasPayer: boolean;\n feeTotal: number;\n};\n\ntype CurrencyTotals = {\n count: number;\n transaction_amount: number;\n total_paid_amount: number;\n net_received_amount: number;\n overpaid_amount: number;\n fee_total: number;\n};\n\nfunction createCurrencyTotals(): CurrencyTotals {\n return {\n count: 0,\n transaction_amount: 0,\n total_paid_amount: 0,\n net_received_amount: 0,\n overpaid_amount: 0,\n fee_total: 0,\n };\n}\n\nfunction incrementCounter(store: Record<string, number>, key: string): void {\n const normalizedKey = key.trim() || \"UNKNOWN\";\n store[normalizedKey] = (store[normalizedKey] ?? 0) + 1;\n}\n\nfunction projectPayment(payment: Record<string, unknown>): PaymentProjection {\n const paymentId = normalizeScalarString(payment.id) || \"\";\n const transactionDetails = asRecord(payment.transaction_details);\n const payer = asRecord(payment.payer);\n const order = asRecord(payment.order);\n const feeDetails = asArray<Record<string, unknown>>(payment.fee_details);\n const currencyId = normalizeString(payment.currency_id, \"UNKNOWN\") || \"UNKNOWN\";\n const status = normalizeString(payment.status, \"UNKNOWN\") || \"UNKNOWN\";\n const paymentMethodId =\n normalizeScalarString(payment.payment_method_id) || normalizeScalarString(asRecord(payment.payment_method).id) || \"UNKNOWN\";\n const paymentTypeId = normalizeString(payment.payment_type_id) || \"UNKNOWN\";\n const transactionAmount = toNumber(payment.transaction_amount);\n const totalPaidAmount = toNumber(transactionDetails.total_paid_amount ?? payment.total_paid_amount);\n const netReceivedAmount = toNumber(transactionDetails.net_received_amount);\n const overpaidAmount = toNumber(transactionDetails.overpaid_amount);\n const feeTotal = roundMoney(feeDetails.reduce((accumulator, fee) => accumulator + toNumber(fee.amount), 0));\n const dateCreated = compactDateTime(payment.date_created);\n const dateLastUpdated = compactDateTime(payment.date_last_updated ?? payment.last_updated);\n const description = normalizeString(payment.description);\n const orderId = normalizeScalarString(order.id) || null;\n const payerId = normalizeScalarString(payer.id) || null;\n const payerEmail = normalizeString(payer.email);\n const payerType = normalizeString(payer.type);\n const payerFirstName = normalizeString(payer.first_name);\n const payerLastName = normalizeString(payer.last_name);\n const externalReference = normalizeString(transactionDetails.external_reference);\n\n return {\n row: [\n paymentId || null,\n normalizeString(payment.status) || null,\n normalizeString(payment.status_detail) || null,\n currencyId,\n transactionAmount,\n totalPaidAmount,\n netReceivedAmount,\n overpaidAmount,\n paymentMethodId,\n paymentTypeId,\n toNumber(payment.installments),\n dateCreated,\n dateLastUpdated,\n description || null,\n orderId,\n payerId,\n payerEmail || null,\n payerType || null,\n payerFirstName || null,\n payerLastName || null,\n feeDetails.length,\n feeTotal,\n externalReference || null,\n ],\n feeRows: feeDetails.map((fee) => [\n paymentId || null,\n normalizeString(fee.type) || null,\n toNumber(fee.amount),\n ]),\n paymentId,\n currencyId,\n status,\n paymentMethodId,\n paymentTypeId,\n hasOrder: Boolean(orderId),\n hasPayer: Boolean(payerId || payerEmail),\n feeTotal,\n };\n}\n\nfunction buildBreakdownEntries(store: Record<string, number>) {\n const total = Object.values(store).reduce((accumulator, value) => accumulator + value, 0);\n\n return Object.entries(store)\n .map(([key, count]) => ({\n key,\n count,\n rate: total > 0 ? roundMoney(count / total) : 0,\n }))\n .sort((left, right) => right.count - left.count || left.key.localeCompare(right.key));\n}\n\nfunction buildCurrencyBreakdowns(store: Record<string, CurrencyTotals>) {\n return Object.entries(store)\n .map(([currencyId, totals]) => ({\n currency_id: currencyId,\n count: totals.count,\n transaction_amount: roundMoney(totals.transaction_amount),\n total_paid_amount: roundMoney(totals.total_paid_amount),\n net_received_amount: roundMoney(totals.net_received_amount),\n overpaid_amount: roundMoney(totals.overpaid_amount),\n fee_total: roundMoney(totals.fee_total),\n }))\n .sort((left, right) => right.count - left.count || left.currency_id.localeCompare(right.currency_id));\n}\n\nfunction buildAlerts(params: {\n successfulCount: number;\n failedCount: number;\n paymentsWithoutOrderCount: number;\n paymentsWithoutPayerCount: number;\n currenciesObserved: string[];\n}): string[] {\n const alerts: string[] = [];\n\n if (params.failedCount > 0) {\n alerts.push(`${params.failedCount} payment${params.failedCount === 1 ? \"\" : \"s\"} failed to fetch.`);\n }\n\n if (params.successfulCount === 0 && params.failedCount > 0) {\n alerts.push(\"No payments were successfully retrieved.\");\n }\n\n if (params.paymentsWithoutOrderCount > 0) {\n alerts.push(\n `${params.paymentsWithoutOrderCount} payment${params.paymentsWithoutOrderCount === 1 ? \"\" : \"s\"} do not include an order reference.`\n );\n }\n\n if (params.paymentsWithoutPayerCount > 0) {\n alerts.push(\n `${params.paymentsWithoutPayerCount} payment${params.paymentsWithoutPayerCount === 1 ? \"\" : \"s\"} are missing payer data.`\n );\n }\n\n if (params.currenciesObserved.length > 1) {\n alerts.push(`Multiple currencies detected: ${params.currenciesObserved.join(\", \")}.`);\n }\n\n return alerts;\n}\n\nfunction buildPaymentPayload(params: {\n profileId: string;\n requestedPaymentIds: string[];\n successful: PaymentProjection[];\n failed: Array<{\n paymentId: string;\n message: string;\n statusCode?: number;\n attempts: number;\n retryable: boolean;\n }>;\n}) {\n const currencyTotals: Record<string, CurrencyTotals> = {};\n const statusCounts: Record<string, number> = {};\n const paymentMethodCounts: Record<string, number> = {};\n const paymentTypeCounts: Record<string, number> = {};\n const payments: PaymentRow[] = [];\n const feeDetailRows: FeeRow[] = [];\n let paymentsWithOrderCount = 0;\n let paymentsWithoutOrderCount = 0;\n let paymentsWithoutPayerCount = 0;\n\n for (const projection of params.successful) {\n payments.push(projection.row);\n feeDetailRows.push(...projection.feeRows);\n\n const currencyBucketTotals = currencyBucket(currencyTotals, projection.currencyId, createCurrencyTotals);\n currencyBucketTotals.count += 1;\n currencyBucketTotals.transaction_amount += projection.row[4] ? Number(projection.row[4]) : 0;\n currencyBucketTotals.total_paid_amount += projection.row[5] ? Number(projection.row[5]) : 0;\n currencyBucketTotals.net_received_amount += projection.row[6] ? Number(projection.row[6]) : 0;\n currencyBucketTotals.overpaid_amount += projection.row[7] ? Number(projection.row[7]) : 0;\n currencyBucketTotals.fee_total += projection.feeTotal;\n\n incrementCounter(statusCounts, projection.status);\n incrementCounter(paymentMethodCounts, projection.paymentMethodId);\n incrementCounter(paymentTypeCounts, projection.paymentTypeId);\n\n if (projection.hasOrder) {\n paymentsWithOrderCount += 1;\n } else {\n paymentsWithoutOrderCount += 1;\n }\n\n if (!projection.hasPayer) {\n paymentsWithoutPayerCount += 1;\n }\n }\n\n const currenciesObserved = Object.keys(currencyTotals).sort((left, right) => left.localeCompare(right));\n const summary = {\n requested_count: params.requestedPaymentIds.length,\n successful_count: params.successful.length,\n failed_count: params.failed.length,\n payments_with_order_count: paymentsWithOrderCount,\n payments_without_order_count: paymentsWithoutOrderCount,\n payments_without_payer_count: paymentsWithoutPayerCount,\n currency_totals: Object.fromEntries(\n Object.entries(currencyTotals).map(([currencyId, totals]) => [currencyId, stripNulls({\n count: totals.count,\n transaction_amount: roundMoney(totals.transaction_amount),\n total_paid_amount: roundMoney(totals.total_paid_amount),\n net_received_amount: roundMoney(totals.net_received_amount),\n overpaid_amount: roundMoney(totals.overpaid_amount),\n fee_total: roundMoney(totals.fee_total),\n })])\n ),\n status_counts: statusCounts,\n payment_method_counts: paymentMethodCounts,\n payment_type_counts: paymentTypeCounts,\n };\n\n const breakdowns = stripNulls({\n by_currency: buildCurrencyBreakdowns(currencyTotals),\n by_status: buildBreakdownEntries(statusCounts),\n by_payment_method: buildBreakdownEntries(paymentMethodCounts),\n by_payment_type: buildBreakdownEntries(paymentTypeCounts),\n });\n\n const alerts = buildAlerts({\n successfulCount: params.successful.length,\n failedCount: params.failed.length,\n paymentsWithoutOrderCount,\n paymentsWithoutPayerCount,\n currenciesObserved,\n });\n\n const payload = stripNulls({\n metadata: {\n profile_id: params.profileId,\n endpoint: \"/v1/payments/{payment_id}\",\n mode: params.requestedPaymentIds.length === 1 ? \"single\" : \"batch\",\n requested_count: params.requestedPaymentIds.length,\n successful_count: params.successful.length,\n failed_count: params.failed.length,\n coverage_complete: params.failed.length === 0,\n requested_payment_ids: params.requestedPaymentIds,\n successful_payment_ids: params.successful.map((entry) => entry.paymentId),\n failed_payment_ids: params.failed.map((entry) => entry.paymentId),\n },\n summary,\n breakdowns,\n alerts,\n failures: params.failed,\n });\n\n // Attach compact positional blocks after stripping nullish metadata so row length stays aligned.\n return {\n ...payload,\n payments_schema: paymentsSchema,\n payments,\n payment_fee_details_schema: paymentFeeDetailsSchema,\n payment_fee_details: feeDetailRows,\n };\n}\n\nexport async function meliGetPaymentDetailsHandler(\n params: z.infer<typeof meliGetPaymentDetailsSchema>\n) {\n try {\n const profileResolution = await resolveMercadoLibreProfileOrSelection(params.profileId);\n if (!profileResolution.ok) {\n return profileResolution.response;\n }\n\n const profileId = profileResolution.value.profileId;\n\n if (params.paymentId) {\n const payment = await getMercadoLibrePaymentDetails(profileId, params.paymentId);\n const projected = projectPayment(payment);\n\n return object(\n buildPaymentPayload({\n profileId,\n requestedPaymentIds: [params.paymentId],\n successful: [projected],\n failed: [],\n })\n );\n }\n\n const batch = await getMercadoLibrePaymentDetailsBatch(profileId, params.paymentIds ?? []);\n\n return object(\n buildPaymentPayload({\n profileId,\n requestedPaymentIds: params.paymentIds ?? [],\n successful: batch.successful.map((entry) => projectPayment(entry.payment)),\n failed: batch.failed,\n })\n );\n } catch (err) {\n return error(formatMercadoLibreError(err, \"Failed to fetch MercadoLibre payment details\"));\n }\n}\n"],
5
+ "mappings": "AAAA,SAAS,OAAO,cAAc;AAC9B,SAAS,SAAS;AAElB,SAAS,+BAA+B;AACxC;AAAA,EACE;AAAA,EACA;AAAA,OACK;AACP,SAAS,kBAAkB;AAC3B;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,6CAA6C;AACtD,SAAS,wCAAwC;AAEjD,MAAM,kBAAkB;AAExB,MAAM,uBAAuB,EAC1B,OAAO,EACP,KAAK,EACL,IAAI,CAAC,EACL,SAAS,qCAAqC;AAE1C,MAAM,8BAA8B,EACxC,OAAO;AAAA,EACN,WAAW;AAAA,EACX,WAAW,qBAAqB,SAAS,EAAE,SAAS,4CAA4C;AAAA,EAChG,YAAY,EACT,MAAM,oBAAoB,EAC1B,IAAI,CAAC,EACL,IAAI,eAAe,EACnB,SAAS,qGAAqG,EAC9G,SAAS;AACd,CAAC,EACA,YAAY,CAAC,OAAO,QAAQ;AAC3B,QAAM,eAAe,QAAQ,MAAM,SAAS;AAC5C,QAAM,gBAAgB,QAAQ,MAAM,YAAY,MAAM;AAEtD,MAAI,iBAAiB,eAAe;AAClC,QAAI,SAAS;AAAA,MACX,MAAM,EAAE,aAAa;AAAA,MACrB,SAAS;AAAA,MACT,MAAM,CAAC,WAAW;AAAA,IACpB,CAAC;AACD,QAAI,SAAS;AAAA,MACX,MAAM,EAAE,aAAa;AAAA,MACrB,SAAS;AAAA,MACT,MAAM,CAAC,YAAY;AAAA,IACrB,CAAC;AAAA,EACH;AACF,CAAC;AAEI,MAAM,iBAAiB;AAAA,EAC5B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEO,MAAM,0BAA0B,CAAC,cAAc,YAAY,YAAY;AA2B9E,SAAS,uBAAuC;AAC9C,SAAO;AAAA,IACL,OAAO;AAAA,IACP,oBAAoB;AAAA,IACpB,mBAAmB;AAAA,IACnB,qBAAqB;AAAA,IACrB,iBAAiB;AAAA,IACjB,WAAW;AAAA,EACb;AACF;AAEA,SAAS,iBAAiB,OAA+B,KAAmB;AAC1E,QAAM,gBAAgB,IAAI,KAAK,KAAK;AACpC,QAAM,aAAa,KAAK,MAAM,aAAa,KAAK,KAAK;AACvD;AAEA,SAAS,eAAe,SAAqD;AAC3E,QAAM,YAAY,sBAAsB,QAAQ,EAAE,KAAK;AACvD,QAAM,qBAAqB,SAAS,QAAQ,mBAAmB;AAC/D,QAAM,QAAQ,SAAS,QAAQ,KAAK;AACpC,QAAM,QAAQ,SAAS,QAAQ,KAAK;AACpC,QAAM,aAAa,QAAiC,QAAQ,WAAW;AACvE,QAAM,aAAa,gBAAgB,QAAQ,aAAa,SAAS,KAAK;AACtE,QAAM,SAAS,gBAAgB,QAAQ,QAAQ,SAAS,KAAK;AAC7D,QAAM,kBACJ,sBAAsB,QAAQ,iBAAiB,KAAK,sBAAsB,SAAS,QAAQ,cAAc,EAAE,EAAE,KAAK;AACpH,QAAM,gBAAgB,gBAAgB,QAAQ,eAAe,KAAK;AAClE,QAAM,oBAAoB,SAAS,QAAQ,kBAAkB;AAC7D,QAAM,kBAAkB,SAAS,mBAAmB,qBAAqB,QAAQ,iBAAiB;AAClG,QAAM,oBAAoB,SAAS,mBAAmB,mBAAmB;AACzE,QAAM,iBAAiB,SAAS,mBAAmB,eAAe;AAClE,QAAM,WAAW,WAAW,WAAW,OAAO,CAAC,aAAa,QAAQ,cAAc,SAAS,IAAI,MAAM,GAAG,CAAC,CAAC;AAC1G,QAAM,cAAc,gBAAgB,QAAQ,YAAY;AACxD,QAAM,kBAAkB,gBAAgB,QAAQ,qBAAqB,QAAQ,YAAY;AACzF,QAAM,cAAc,gBAAgB,QAAQ,WAAW;AACvD,QAAM,UAAU,sBAAsB,MAAM,EAAE,KAAK;AACnD,QAAM,UAAU,sBAAsB,MAAM,EAAE,KAAK;AACnD,QAAM,aAAa,gBAAgB,MAAM,KAAK;AAC9C,QAAM,YAAY,gBAAgB,MAAM,IAAI;AAC5C,QAAM,iBAAiB,gBAAgB,MAAM,UAAU;AACvD,QAAM,gBAAgB,gBAAgB,MAAM,SAAS;AACrD,QAAM,oBAAoB,gBAAgB,mBAAmB,kBAAkB;AAE/E,SAAO;AAAA,IACL,KAAK;AAAA,MACH,aAAa;AAAA,MACb,gBAAgB,QAAQ,MAAM,KAAK;AAAA,MACnC,gBAAgB,QAAQ,aAAa,KAAK;AAAA,MAC1C;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,SAAS,QAAQ,YAAY;AAAA,MAC7B;AAAA,MACA;AAAA,MACA,eAAe;AAAA,MACf;AAAA,MACA;AAAA,MACA,cAAc;AAAA,MACd,aAAa;AAAA,MACb,kBAAkB;AAAA,MAClB,iBAAiB;AAAA,MACjB,WAAW;AAAA,MACX;AAAA,MACA,qBAAqB;AAAA,IACvB;AAAA,IACA,SAAS,WAAW,IAAI,CAAC,QAAQ;AAAA,MAC/B,aAAa;AAAA,MACb,gBAAgB,IAAI,IAAI,KAAK;AAAA,MAC7B,SAAS,IAAI,MAAM;AAAA,IACrB,CAAC;AAAA,IACD;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,UAAU,QAAQ,OAAO;AAAA,IACzB,UAAU,QAAQ,WAAW,UAAU;AAAA,IACvC;AAAA,EACF;AACF;AAEA,SAAS,sBAAsB,OAA+B;AAC5D,QAAM,QAAQ,OAAO,OAAO,KAAK,EAAE,OAAO,CAAC,aAAa,UAAU,cAAc,OAAO,CAAC;AAExF,SAAO,OAAO,QAAQ,KAAK,EACxB,IAAI,CAAC,CAAC,KAAK,KAAK,OAAO;AAAA,IACtB;AAAA,IACA;AAAA,IACA,MAAM,QAAQ,IAAI,WAAW,QAAQ,KAAK,IAAI;AAAA,EAChD,EAAE,EACD,KAAK,CAAC,MAAM,UAAU,MAAM,QAAQ,KAAK,SAAS,KAAK,IAAI,cAAc,MAAM,GAAG,CAAC;AACxF;AAEA,SAAS,wBAAwB,OAAuC;AACtE,SAAO,OAAO,QAAQ,KAAK,EACxB,IAAI,CAAC,CAAC,YAAY,MAAM,OAAO;AAAA,IAC9B,aAAa;AAAA,IACb,OAAO,OAAO;AAAA,IACd,oBAAoB,WAAW,OAAO,kBAAkB;AAAA,IACxD,mBAAmB,WAAW,OAAO,iBAAiB;AAAA,IACtD,qBAAqB,WAAW,OAAO,mBAAmB;AAAA,IAC1D,iBAAiB,WAAW,OAAO,eAAe;AAAA,IAClD,WAAW,WAAW,OAAO,SAAS;AAAA,EACxC,EAAE,EACD,KAAK,CAAC,MAAM,UAAU,MAAM,QAAQ,KAAK,SAAS,KAAK,YAAY,cAAc,MAAM,WAAW,CAAC;AACxG;AAEA,SAAS,YAAY,QAMR;AACX,QAAM,SAAmB,CAAC;AAE1B,MAAI,OAAO,cAAc,GAAG;AAC1B,WAAO,KAAK,GAAG,OAAO,WAAW,WAAW,OAAO,gBAAgB,IAAI,KAAK,GAAG,mBAAmB;AAAA,EACpG;AAEA,MAAI,OAAO,oBAAoB,KAAK,OAAO,cAAc,GAAG;AAC1D,WAAO,KAAK,0CAA0C;AAAA,EACxD;AAEA,MAAI,OAAO,4BAA4B,GAAG;AACxC,WAAO;AAAA,MACL,GAAG,OAAO,yBAAyB,WAAW,OAAO,8BAA8B,IAAI,KAAK,GAAG;AAAA,IACjG;AAAA,EACF;AAEA,MAAI,OAAO,4BAA4B,GAAG;AACxC,WAAO;AAAA,MACL,GAAG,OAAO,yBAAyB,WAAW,OAAO,8BAA8B,IAAI,KAAK,GAAG;AAAA,IACjG;AAAA,EACF;AAEA,MAAI,OAAO,mBAAmB,SAAS,GAAG;AACxC,WAAO,KAAK,iCAAiC,OAAO,mBAAmB,KAAK,IAAI,CAAC,GAAG;AAAA,EACtF;AAEA,SAAO;AACT;AAEA,SAAS,oBAAoB,QAW1B;AACD,QAAM,iBAAiD,CAAC;AACxD,QAAM,eAAuC,CAAC;AAC9C,QAAM,sBAA8C,CAAC;AACrD,QAAM,oBAA4C,CAAC;AACnD,QAAM,WAAyB,CAAC;AAChC,QAAM,gBAA0B,CAAC;AACjC,MAAI,yBAAyB;AAC7B,MAAI,4BAA4B;AAChC,MAAI,4BAA4B;AAEhC,aAAW,cAAc,OAAO,YAAY;AAC1C,aAAS,KAAK,WAAW,GAAG;AAC5B,kBAAc,KAAK,GAAG,WAAW,OAAO;AAExC,UAAM,uBAAuB,eAAe,gBAAgB,WAAW,YAAY,oBAAoB;AACvG,yBAAqB,SAAS;AAC9B,yBAAqB,sBAAsB,WAAW,IAAI,CAAC,IAAI,OAAO,WAAW,IAAI,CAAC,CAAC,IAAI;AAC3F,yBAAqB,qBAAqB,WAAW,IAAI,CAAC,IAAI,OAAO,WAAW,IAAI,CAAC,CAAC,IAAI;AAC1F,yBAAqB,uBAAuB,WAAW,IAAI,CAAC,IAAI,OAAO,WAAW,IAAI,CAAC,CAAC,IAAI;AAC5F,yBAAqB,mBAAmB,WAAW,IAAI,CAAC,IAAI,OAAO,WAAW,IAAI,CAAC,CAAC,IAAI;AACxF,yBAAqB,aAAa,WAAW;AAE7C,qBAAiB,cAAc,WAAW,MAAM;AAChD,qBAAiB,qBAAqB,WAAW,eAAe;AAChE,qBAAiB,mBAAmB,WAAW,aAAa;AAE5D,QAAI,WAAW,UAAU;AACvB,gCAA0B;AAAA,IAC5B,OAAO;AACL,mCAA6B;AAAA,IAC/B;AAEA,QAAI,CAAC,WAAW,UAAU;AACxB,mCAA6B;AAAA,IAC/B;AAAA,EACF;AAEA,QAAM,qBAAqB,OAAO,KAAK,cAAc,EAAE,KAAK,CAAC,MAAM,UAAU,KAAK,cAAc,KAAK,CAAC;AACtG,QAAM,UAAU;AAAA,IACd,iBAAiB,OAAO,oBAAoB;AAAA,IAC5C,kBAAkB,OAAO,WAAW;AAAA,IACpC,cAAc,OAAO,OAAO;AAAA,IAC5B,2BAA2B;AAAA,IAC3B,8BAA8B;AAAA,IAC9B,8BAA8B;AAAA,IAC9B,iBAAiB,OAAO;AAAA,MACtB,OAAO,QAAQ,cAAc,EAAE,IAAI,CAAC,CAAC,YAAY,MAAM,MAAM,CAAC,YAAY,WAAW;AAAA,QACnF,OAAO,OAAO;AAAA,QACd,oBAAoB,WAAW,OAAO,kBAAkB;AAAA,QACxD,mBAAmB,WAAW,OAAO,iBAAiB;AAAA,QACtD,qBAAqB,WAAW,OAAO,mBAAmB;AAAA,QAC1D,iBAAiB,WAAW,OAAO,eAAe;AAAA,QAClD,WAAW,WAAW,OAAO,SAAS;AAAA,MACxC,CAAC,CAAC,CAAC;AAAA,IACL;AAAA,IACA,eAAe;AAAA,IACf,uBAAuB;AAAA,IACvB,qBAAqB;AAAA,EACvB;AAEA,QAAM,aAAa,WAAW;AAAA,IAC5B,aAAa,wBAAwB,cAAc;AAAA,IACnD,WAAW,sBAAsB,YAAY;AAAA,IAC7C,mBAAmB,sBAAsB,mBAAmB;AAAA,IAC5D,iBAAiB,sBAAsB,iBAAiB;AAAA,EAC1D,CAAC;AAED,QAAM,SAAS,YAAY;AAAA,IACzB,iBAAiB,OAAO,WAAW;AAAA,IACnC,aAAa,OAAO,OAAO;AAAA,IAC3B;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AAED,QAAM,UAAU,WAAW;AAAA,IACzB,UAAU;AAAA,MACR,YAAY,OAAO;AAAA,MACnB,UAAU;AAAA,MACV,MAAM,OAAO,oBAAoB,WAAW,IAAI,WAAW;AAAA,MAC3D,iBAAiB,OAAO,oBAAoB;AAAA,MAC5C,kBAAkB,OAAO,WAAW;AAAA,MACpC,cAAc,OAAO,OAAO;AAAA,MAC5B,mBAAmB,OAAO,OAAO,WAAW;AAAA,MAC5C,uBAAuB,OAAO;AAAA,MAC9B,wBAAwB,OAAO,WAAW,IAAI,CAAC,UAAU,MAAM,SAAS;AAAA,MACxE,oBAAoB,OAAO,OAAO,IAAI,CAAC,UAAU,MAAM,SAAS;AAAA,IAClE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,UAAU,OAAO;AAAA,EACnB,CAAC;AAGD,SAAO;AAAA,IACL,GAAG;AAAA,IACH,iBAAiB;AAAA,IACjB;AAAA,IACA,4BAA4B;AAAA,IAC5B,qBAAqB;AAAA,EACvB;AACF;AAEA,eAAsB,6BACpB,QACA;AACA,MAAI;AACF,UAAM,oBAAoB,MAAM,sCAAsC,OAAO,SAAS;AACtF,QAAI,CAAC,kBAAkB,IAAI;AACzB,aAAO,kBAAkB;AAAA,IAC3B;AAEA,UAAM,YAAY,kBAAkB,MAAM;AAE1C,QAAI,OAAO,WAAW;AACpB,YAAM,UAAU,MAAM,8BAA8B,WAAW,OAAO,SAAS;AAC/E,YAAM,YAAY,eAAe,OAAO;AAExC,aAAO;AAAA,QACL,oBAAoB;AAAA,UAClB;AAAA,UACA,qBAAqB,CAAC,OAAO,SAAS;AAAA,UACtC,YAAY,CAAC,SAAS;AAAA,UACtB,QAAQ,CAAC;AAAA,QACX,CAAC;AAAA,MACH;AAAA,IACF;AAEA,UAAM,QAAQ,MAAM,mCAAmC,WAAW,OAAO,cAAc,CAAC,CAAC;AAEzF,WAAO;AAAA,MACL,oBAAoB;AAAA,QAClB;AAAA,QACA,qBAAqB,OAAO,cAAc,CAAC;AAAA,QAC3C,YAAY,MAAM,WAAW,IAAI,CAAC,UAAU,eAAe,MAAM,OAAO,CAAC;AAAA,QACzE,QAAQ,MAAM;AAAA,MAChB,CAAC;AAAA,IACH;AAAA,EACF,SAAS,KAAK;AACZ,WAAO,MAAM,wBAAwB,KAAK,8CAA8C,CAAC;AAAA,EAC3F;AACF;",
6
+ "names": []
7
+ }
@@ -2,6 +2,7 @@ export * from "./get-account-context.js";
2
2
  export * from "./validate-connection.js";
3
3
  export * from "./get-orders-summary.js";
4
4
  export * from "./get-order-details.js";
5
+ export * from "./get-payment-details.js";
5
6
  export * from "./get-sales-by-item.js";
6
7
  export * from "./get-sales-trend.js";
7
8
  export * from "./get-shipping-summary.js";
@@ -24,4 +25,23 @@ export * from "./answer-question.js";
24
25
  export * from "./profile-resolution.js";
25
26
  export * from "./get-site-categories-and-listing-types.js";
26
27
  export * from "./get-billing-provisions-summary.js";
28
+ import {
29
+ meliGetBillingProvisionsByOrderHandler,
30
+ meliGetBillingProvisionsByOrderSchema,
31
+ ordersSchema,
32
+ paymentInfoSchema,
33
+ detailsSchema,
34
+ detailsSalesSchema,
35
+ detailsItemsSchema
36
+ } from "./get-billing-provisions-by-order.js";
37
+ export * from "./get-full-storage-charges.js";
38
+ export {
39
+ detailsItemsSchema as billingProvisionsByOrderDetailsItemsSchema,
40
+ detailsSalesSchema as billingProvisionsByOrderDetailsSalesSchema,
41
+ detailsSchema as billingProvisionsByOrderDetailsSchema,
42
+ meliGetBillingProvisionsByOrderHandler,
43
+ meliGetBillingProvisionsByOrderSchema,
44
+ ordersSchema,
45
+ paymentInfoSchema
46
+ };
27
47
  //# sourceMappingURL=index.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/tools/mercadolibre/index.ts"],
4
- "sourcesContent": ["export * from \"./get-account-context.js\";\nexport * from \"./validate-connection.js\";\nexport * from \"./get-orders-summary.js\";\nexport * from \"./get-order-details.js\";\nexport * from \"./get-sales-by-item.js\";\nexport * from \"./get-sales-trend.js\";\nexport * from \"./get-shipping-summary.js\";\nexport * from \"./get-item-visits.js\";\nexport * from \"./get-store-performance.js\";\nexport * from \"./search-items.js\";\nexport * from \"./get-item-details.js\";\nexport * from \"./get-listing-quality.js\";\nexport * from \"./predict-category.js\";\nexport * from \"./get-category-requirements.js\";\nexport * from \"./estimate-listing-fee.js\";\nexport * from \"./estimate-product-profitability.js\";\nexport * from \"./create-item.js\";\nexport * from \"./update-item-basic-fields.js\";\nexport * from \"./update-item-description.js\";\nexport * from \"./update-item-pictures.js\";\nexport * from \"./pause-or-reactivate-item.js\";\nexport * from \"./search-questions.js\";\nexport * from \"./answer-question.js\";\nexport * from \"./profile-resolution.js\";\nexport * from \"./get-site-categories-and-listing-types.js\";\nexport * from \"./get-billing-provisions-summary.js\";\n"],
5
- "mappings": "AAAA,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;",
4
+ "sourcesContent": ["export * from \"./get-account-context.js\";\nexport * from \"./validate-connection.js\";\nexport * from \"./get-orders-summary.js\";\nexport * from \"./get-order-details.js\";\nexport * from \"./get-payment-details.js\";\nexport * from \"./get-sales-by-item.js\";\nexport * from \"./get-sales-trend.js\";\nexport * from \"./get-shipping-summary.js\";\nexport * from \"./get-item-visits.js\";\nexport * from \"./get-store-performance.js\";\nexport * from \"./search-items.js\";\nexport * from \"./get-item-details.js\";\nexport * from \"./get-listing-quality.js\";\nexport * from \"./predict-category.js\";\nexport * from \"./get-category-requirements.js\";\nexport * from \"./estimate-listing-fee.js\";\nexport * from \"./estimate-product-profitability.js\";\nexport * from \"./create-item.js\";\nexport * from \"./update-item-basic-fields.js\";\nexport * from \"./update-item-description.js\";\nexport * from \"./update-item-pictures.js\";\nexport * from \"./pause-or-reactivate-item.js\";\nexport * from \"./search-questions.js\";\nexport * from \"./answer-question.js\";\nexport * from \"./profile-resolution.js\";\nexport * from \"./get-site-categories-and-listing-types.js\";\nexport * from \"./get-billing-provisions-summary.js\";\nexport {\n meliGetBillingProvisionsByOrderHandler,\n meliGetBillingProvisionsByOrderSchema,\n ordersSchema,\n paymentInfoSchema,\n detailsSchema as billingProvisionsByOrderDetailsSchema,\n detailsSalesSchema as billingProvisionsByOrderDetailsSalesSchema,\n detailsItemsSchema as billingProvisionsByOrderDetailsItemsSchema,\n} from \"./get-billing-provisions-by-order.js\";\nexport * from \"./get-full-storage-charges.js\";\n"],
5
+ "mappings": "AAAA,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACiB;AAAA,EACK;AAAA,EACA;AAAA,OACjB;AACP,cAAc;",
6
6
  "names": []
7
7
  }
@@ -30,8 +30,18 @@ vi.mock("../../src/tools/mercadolibre/profile-resolution.js", () => ({
30
30
  import {
31
31
  getMercadoLibreBillingProvisionPage,
32
32
  getMercadoLibreBillingProvisions,
33
+ getMercadoLibreBillingProvisionsByOrder,
33
34
  scopeToGroupPath
34
35
  } from "../../src/services/mercadolibre/mercadolibre-billing.js";
36
+ import {
37
+ meliGetBillingProvisionsByOrderHandler,
38
+ meliGetBillingProvisionsByOrderSchema,
39
+ ordersSchema,
40
+ paymentInfoSchema,
41
+ detailsSchema as byOrderDetailsSchema,
42
+ detailsSalesSchema as byOrderDetailsSalesSchema,
43
+ detailsItemsSchema as byOrderDetailsItemsSchema
44
+ } from "../../src/tools/mercadolibre/get-billing-provisions-by-order.js";
35
45
  import {
36
46
  meliGetBillingProvisionsSummaryHandler,
37
47
  meliGetBillingProvisionsSummarySchema,
@@ -145,6 +155,7 @@ describe("getMercadoLibreBillingProvisionPage", () => {
145
155
  expect(p.marketplace_type).toBe("classic");
146
156
  expect(p.order_ids).toBe("O1");
147
157
  expect(p.item_ids).toBe("I1");
158
+ expect(p.site_id).toBeUndefined();
148
159
  });
149
160
  it("reads flat total/limit from real MELI envelope (no paging nesting)", async () => {
150
161
  axiosGetMock.mockResolvedValue({
@@ -235,6 +246,171 @@ describe("getMercadoLibreBillingProvisions", () => {
235
246
  expect(result.coverage_complete).toBe(true);
236
247
  });
237
248
  });
249
+ describe("meliGetBillingProvisionsByOrderHandler", () => {
250
+ beforeEach(() => {
251
+ vi.clearAllMocks();
252
+ vi.mocked(resolveProfileMock).mockResolvedValue({
253
+ ok: true,
254
+ value: { profileId: "meli-profile-1" }
255
+ });
256
+ });
257
+ it("requires profileId and at least one orderId", () => {
258
+ expect(
259
+ () => meliGetBillingProvisionsByOrderSchema.parse({ orderIds: ["O1"] })
260
+ ).toThrow();
261
+ expect(
262
+ () => meliGetBillingProvisionsByOrderSchema.parse({ profileId: "profile-1", orderIds: ["O1"] })
263
+ ).not.toThrow();
264
+ });
265
+ function officialOrderRow(overrides = {}) {
266
+ const paymentInfo = overrides.payment_info ?? {};
267
+ const details = overrides.details;
268
+ return {
269
+ order_id: overrides.order_id ?? `ORD-${Math.random().toString(36).slice(2, 8)}`,
270
+ sale_fee: overrides.sale_fee ?? 12.34,
271
+ document_id: overrides.document_id ?? "DOC-1",
272
+ currency_id: overrides.currency_id ?? "ARS",
273
+ marketplace: overrides.marketplace ?? "MELI",
274
+ payment_info: {
275
+ payment_id: paymentInfo.payment_id ?? "PAY-1",
276
+ payment_type: paymentInfo.payment_type ?? "credit_card",
277
+ payment_method_id: paymentInfo.payment_method_id ?? "visa",
278
+ installments: paymentInfo.installments ?? 1,
279
+ transaction_amount: paymentInfo.transaction_amount ?? 100,
280
+ total_paid_amount: paymentInfo.total_paid_amount ?? 100,
281
+ shipping_cost: paymentInfo.shipping_cost ?? 0,
282
+ coupon_amount: paymentInfo.coupon_amount ?? 0,
283
+ status: paymentInfo.status ?? "approved",
284
+ status_detail: paymentInfo.status_detail ?? "accredited",
285
+ ...paymentInfo
286
+ },
287
+ details: details ?? [
288
+ {
289
+ detail_id: "detail-1",
290
+ detail_type: "sale",
291
+ detail_sub_type: "sale",
292
+ transaction_detail: "Cargo por vender",
293
+ detail_amount: 12.34,
294
+ currency_id: "ARS",
295
+ concept_type: "sale",
296
+ operation_id: "OP-1",
297
+ shipping_id: "SHIP-1",
298
+ pack_id: "PACK-1",
299
+ inventory_id: "INV-1",
300
+ sales_info: [
301
+ {
302
+ order_id: overrides.order_id ?? "ORD-1",
303
+ operation_id: "OP-1",
304
+ sale_date_time: "2026-06-01T10:00:00Z",
305
+ payer_nickname: "buyer-1",
306
+ transaction_amount: 100
307
+ }
308
+ ],
309
+ items_info: [
310
+ {
311
+ item_id: "ITEM-1",
312
+ item_title: "Producto 1",
313
+ item_amount: 1,
314
+ item_price: 100,
315
+ item_kit_id: null,
316
+ store_id: "STORE-1",
317
+ order_id: overrides.order_id ?? "ORD-1"
318
+ }
319
+ ]
320
+ }
321
+ ],
322
+ ...overrides
323
+ };
324
+ }
325
+ it("uses the official order details endpoint without site_id and chunks at 60 IDs", async () => {
326
+ axiosGetMock.mockResolvedValueOnce({ data: { results: [officialOrderRow({ order_id: "O1" })], total: 1, limit: 60 } }).mockResolvedValueOnce({ data: { results: [officialOrderRow({ order_id: "O61" })], total: 1, limit: 1 } });
327
+ const orderIds = Array.from({ length: 61 }, (_, index) => `O${index + 1}`);
328
+ const result = await getMercadoLibreBillingProvisionsByOrder("profile-1", {
329
+ orderIds
330
+ });
331
+ expect(axiosGetMock).toHaveBeenCalledTimes(2);
332
+ expect(axiosGetMock.mock.calls[0][0]).toBe("/billing/integration/group/ML/order/details");
333
+ expect(axiosGetMock.mock.calls[0][1]).toEqual({ params: { order_ids: orderIds.slice(0, 60).join(",") } });
334
+ expect(axiosGetMock.mock.calls[1][1]).toEqual({ params: { order_ids: ["O61"].join(",") } });
335
+ expect(result.chunks_total).toBe(2);
336
+ expect(result.chunks_succeeded).toBe(2);
337
+ expect(result.chunks_failed).toBe(0);
338
+ expect(result.order_ids_found).toEqual(["O1", "O61"]);
339
+ expect(result.order_ids_not_found).toEqual(orderIds.filter((id) => !["O1", "O61"].includes(id)));
340
+ });
341
+ it("deduplicates found order ids from the official per-order payload", async () => {
342
+ axiosGetMock.mockResolvedValue({
343
+ data: {
344
+ results: [
345
+ officialOrderRow({
346
+ order_id: "O1",
347
+ details: [
348
+ {
349
+ detail_id: "detail-1",
350
+ sales_info: [
351
+ { order_id: "O1", operation_id: "OP-1", sale_date_time: "2026-06-01T10:00:00Z", payer_nickname: "buyer-1", transaction_amount: 100 }
352
+ ],
353
+ items_info: [
354
+ { item_id: "ITEM-1", item_title: "Producto 1", item_amount: 1, item_price: 100, order_id: "O1" }
355
+ ]
356
+ }
357
+ ]
358
+ })
359
+ ],
360
+ total: 1,
361
+ limit: 60
362
+ }
363
+ });
364
+ const result = await getMercadoLibreBillingProvisionsByOrder("profile-1", {
365
+ orderIds: ["O1", "O2"]
366
+ });
367
+ expect(result.results).toHaveLength(1);
368
+ expect(result.order_ids_found).toEqual(["O1"]);
369
+ expect(result.order_ids_not_found).toEqual(["O2"]);
370
+ expect(result.coverage_complete).toBe(true);
371
+ });
372
+ it("returns the compact order, payment and detail blocks from the official payload", async () => {
373
+ axiosGetMock.mockResolvedValue({
374
+ data: {
375
+ results: [officialOrderRow({ order_id: "O1", sale_fee: null })],
376
+ total: 1,
377
+ limit: 60
378
+ }
379
+ });
380
+ const result = await meliGetBillingProvisionsByOrderHandler({
381
+ profileId: "profile-1",
382
+ orderIds: ["O1"]
383
+ });
384
+ expect(result).toHaveProperty("kind", "object");
385
+ const payload = result.payload;
386
+ expect(payload.profile_id).toBe("meli-profile-1");
387
+ expect(payload.endpoint).toBe("/billing/integration/group/ML/order/details");
388
+ expect(payload.orders_schema).toEqual(ordersSchema);
389
+ expect(payload.payment_info_schema).toEqual(paymentInfoSchema);
390
+ expect(payload.details_schema).toEqual(byOrderDetailsSchema);
391
+ expect(payload.details_sales_schema).toEqual(byOrderDetailsSalesSchema);
392
+ expect(payload.details_items_schema).toEqual(byOrderDetailsItemsSchema);
393
+ const orders = payload.orders;
394
+ const paymentInfo = payload.payment_info;
395
+ const details = payload.details;
396
+ const detailsSales = payload.details_sales;
397
+ const detailsItems = payload.details_items;
398
+ expect(orders).toHaveLength(1);
399
+ expect(orders[0][0]).toBe("O1");
400
+ expect(orders[0][1]).toBeNull();
401
+ expect(paymentInfo).toHaveLength(1);
402
+ expect(paymentInfo[0][0]).toBe("O1");
403
+ expect(details).toHaveLength(1);
404
+ expect(details[0][0]).toBe("O1");
405
+ expect(detailsSales).toHaveLength(1);
406
+ expect(detailsItems).toHaveLength(1);
407
+ const metadata = payload.metadata;
408
+ expect(metadata.order_ids_requested).toEqual(["O1"]);
409
+ expect(metadata.order_ids_found).toEqual(["O1"]);
410
+ expect(metadata.order_ids_not_found).toEqual([]);
411
+ expect(metadata.coverage_complete).toBe(true);
412
+ });
413
+ });
238
414
  describe("meliGetBillingProvisionsSummaryHandler", () => {
239
415
  beforeEach(() => {
240
416
  vi.clearAllMocks();