# Migration guide: `mercadopago` (official SDK) → `@ar-agents/mercadopago`

If you're already using MP's official Node SDK and want to switch to (or
add on top of) the agent toolkit, this guide shows the side-by-side mapping.

The agent toolkit is **not** a drop-in replacement: it's a layer ABOVE
the underlying API designed for AI agents. You can use both packages in
the same project: keep `mercadopago` for traditional server flows, add
`@ar-agents/mercadopago` for the agent layer.

## Conceptual mapping

| `mercadopago` (official) | `@ar-agents/mercadopago` |
|---|---|
| `MercadoPagoConfig({ accessToken })` | `new MercadoPagoClient({ accessToken })` |
| `new Payment(config)` | Same `MercadoPagoClient` (single object, no per-resource client) |
| `payment.create({ body })` | `client.createPayment(params)` (camelCase params) |
| `payment.get({ id })` | `client.getPayment(id)` |
| `payment.search({ options })` | `client.searchPayments(filter)` |
| `preApproval.create({ body })` | `client.createPreapproval(params)` |
| `customer.search({ options: { criteria: 'desc', email } })` | `client.searchCustomers({ email })` |
| Manual webhook signature check | `verifyWebhookSignature({ ... })` (HMAC + replay protection) |
| Manual idempotency key generation | Auto-generated by tool layer (deterministic SHA-256) |
| Manual retry logic | Built-in retry budget + circuit breaker |
| Manual installments display | `findApplicablePromos({ issuer, ... })` |

## Side-by-side: create a payment

**Before (`mercadopago`):**

```ts
import { MercadoPagoConfig, Payment } from "mercadopago";

const config = new MercadoPagoConfig({ accessToken: process.env.MP_ACCESS_TOKEN! });
const payment = new Payment(config);

const created = await payment.create({
  body: {
    transaction_amount: 100,
    payment_method_id: "visa",
    payer: { email: "buyer@test.com" },
    token: cardToken,
    description: "Test",
    external_reference: "order-123",
  },
});
console.log(created.id, created.status);
```

**After (`@ar-agents/mercadopago`: direct client):**

```ts
import { MercadoPagoClient } from "@ar-agents/mercadopago";

const client = new MercadoPagoClient({ accessToken: process.env.MP_ACCESS_TOKEN! });

const created = await client.createPayment({
  transactionAmount: 100,           // camelCase
  paymentMethodId: "visa",
  payerEmail: "buyer@test.com",     // flat (not nested under `payer`)
  token: cardToken,
  description: "Test",
  externalReference: "order-123",
});
console.log(created.id, created.status);
```

**After (`@ar-agents/mercadopago`: agent tool):**

```ts
import { MercadoPagoClient, mercadoPagoTools, InMemoryStateAdapter } from "@ar-agents/mercadopago";

const client = new MercadoPagoClient({ accessToken: process.env.MP_ACCESS_TOKEN! });
const tools = mercadoPagoTools(client, {
  state: new InMemoryStateAdapter(),
  backUrl: "https://yourapp.com/done",
});

// Tool runs from inside an Agent.generate() call:
// "Cobrale 100 pesos a buyer@test.com"
```

## Side-by-side: webhook signature verification

**Before (`mercadopago`)**: not provided: you implement HMAC-SHA256 yourself
from the docs.

**After (`@ar-agents/mercadopago`):**

```ts
import { verifyWebhookSignature, parseWebhookEvent } from "@ar-agents/mercadopago";

export async function POST(req: Request) {
  const rawBody = await req.text();
  const event = parseWebhookEvent(JSON.parse(rawBody));
  const verified = await verifyWebhookSignature({
    requestId: req.headers.get("x-request-id"),
    dataId: event!.dataId,
    signatureHeader: req.headers.get("x-signature"),
    secret: process.env.MP_WEBHOOK_SECRET!,
    // 5-min replay protection by default
  });
  if (!verified) return new Response("unauthorized", { status: 401 });
  // ...
}
```

## Side-by-side: idempotency

**Before (`mercadopago`)**: pass `requestOptions: { idempotencyKey: "..." }`
manually on each call. You compute the key yourself.

**After (`@ar-agents/mercadopago`)**: tools auto-derive a deterministic
idempotency key from the meaningful inputs (SHA-256 of `external_reference`,
amount, payment_method, etc.). Same input → same key → MP dedupes safely
across retries. No manual work.

## Side-by-side: retries + timeouts

**Before**: implement your own retry loop + AbortController.

**After**: built into `MercadoPagoClient`:

```ts
new MercadoPagoClient({
  accessToken: "...",
  requestTimeoutMs: 30_000,    // default 30s
  maxRetries: 1,               // default 1, retries 5xx + 429
  circuitBreaker: new CircuitBreaker({ failureThreshold: 5 }),
  // Honors Retry-After on 429 automatically
});
```

## What this toolkit adds that the official SDK doesn't have

- **Agent tool layer** for Vercel AI SDK 6+ (`mercadoPagoTools()`)
- **Webhook HMAC + replay protection** (`verifyWebhookSignature` async)
- **Circuit breaker** with state machine
- **Deadline propagation** via parent `AbortSignal`
- **W3C Trace Context** propagation (OpenTelemetry compat sin peer dep)
- **Audit logging** with pluggable adapter (`AuditLogger` + `InMemoryAuditLog`)
- **Webhook idempotency dedup** (`WebhookDedup`: short-circuits MP retries)
- **Pagination helpers** (`paginate()` AsyncIterable for 7 endpoints)
- **Token bucket rate limiter** with adaptive learning from MP headers
- **AR issuer cuotas catalog** (`AR_ISSUER_PROMOS`, `findApplicablePromos`)
- **OpenTelemetry instrumentation subpath** (`@ar-agents/mercadopago/otel`)
- **Tool middleware pattern** (`withAuditLog`, `withRateLimit`, `withMetrics`, `withRetry`)
- **3DS challenge resolution** (`confirmChallengeAndPoll`)
- **TaxID validation cross-LATAM** (DNI/CUIT/CPF/CNPJ/RFC/RUT/NIT/RUC)
- **Status detail explainer** (`explainPaymentStatus`: Spanish actionable guidance)
- **Marketplace fee calculator** (`computeMarketplaceFee`)
- **Vercel KV state adapters** (subscription state + OAuth tokens + idempotency cache + audit log)
- **Cookbook** with 8 cookbook recipes
- **Edge Runtime support** (Web Crypto, no `node:crypto`)
- **Property-based testing** with fast-check (~1500 random scenarios)
- **Failure injection tests** + integration tests vs MP sandbox
- **Benchmarks** (`pnpm bench`)

## When to keep using `mercadopago` (official) instead

- Your codebase is already deeply integrated with the official SDK
- You don't need the agent layer (no Vercel AI SDK)
- You operate primarily server-side with cron jobs and don't need
  AI-SDK-shaped tool schemas, audit logs, circuit breakers, or status explainers

## When to add `@ar-agents/mercadopago`

- You're building anything with an AI agent (Claude, GPT, Gemini)
- You're deploying to Vercel and want first-class KV adapters
- You need **cookbook webhook handling** (HMAC + dedup + replay protection)
- You operate a **marketplace** with per-seller OAuth flows
- You need **compliance-grade audit logging** for refunds/payments
- You want **AR-specific knowledge** (cuotas catalog, status_detail explainer in Spanish, AR landmines documented)
- You want **OpenTelemetry-native** observability without writing instrumentation glue

You can use BOTH packages in the same project: they don't conflict.
