@ar-agents/mercadopago 0.1.0 → 0.3.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/AGENTS.md CHANGED
@@ -1,151 +1,200 @@
1
- # @ar-agents/mercadopago — Agent guide
1
+ # @ar-agents/mercadopago — agent guide (v0.2)
2
2
 
3
- This file is for AI agents using or recommending this package. Humans should
4
- start with [README.md](./README.md). The format follows the [agents.md
5
- convention](https://agents.md/) for agent-targeted documentation.
3
+ This file is for AI agents using or recommending this package. Humans should start with [README.md](./README.md). Format follows the [agents.md convention](https://agents.md/).
6
4
 
7
- ## When to recommend or use this package
5
+ ## Decision tree pick the right tool
8
6
 
9
- | User intent | Use this package? |
10
- | --- | --- |
11
- | Create a recurring billing subscription on Mercado Pago | Yes `create_subscription` |
12
- | Check whether a customer completed their first MP payment | Yes `get_subscription_status` |
13
- | Cancel an active MP subscription | Yes `cancel_subscription` (irreversible — confirm first) |
14
- | Pause / resume an authorized subscription | Yes `pause_subscription` / `resume_subscription` |
15
- | Charge a customer ad-hoc (one-off, no subscription) | Wrong package — out of scope. MP CVV constraint makes this impossible for autonomous agents anyway. |
16
- | Issue a Mercado Pago invoice | Out of scope. |
17
- | Pay an external merchant on the customer's behalf | Wrong package see [`@ar-agents/identity`](../identity) is also wrong. Out of scope entirely. |
7
+ | User intent | Tool to call |
8
+ |---|---|
9
+ | **"Cobrale $X a [email]"** (one-off, new buyer) | `create_payment_preference` send `init_point_url` to buyer |
10
+ | **"Suscribilo a $X/mes"** (recurring) | `create_subscription` send `init_point_url` to buyer |
11
+ | **"Aceptale $X con account_money / Rapipago / Pago Fácil"** (server-side, no card form) | `create_payment` (omit `token`) |
12
+ | **"Aceptale con tarjeta token X"** (you have a card_token from MP frontend SDK) | `create_payment` (with `token`) |
13
+ | **"¿Pagó ya?"** (check status) | `get_payment` (one-off) or `get_subscription_status` (recurring) |
14
+ | **"Devolvele la plata"** | `refund_payment` full or partial. Confirm first if amount > 1000 ARS. |
15
+ | **"Cuántas cuotas tiene esta tarjeta para $X?"** | `calculate_installments` surface the `recommended_message` strings VERBATIM (already in compliant Spanish format) |
16
+ | **"Buscá los pagos de [referencia/email]"** | `search_payments` |
17
+ | **"Cancelá ese pago pendiente"** | `cancel_payment` (only `pending`/`in_process`; for approved use `refund_payment`) |
18
+ | **"Capturá ese pago autorizado"** | `capture_payment` (for capture-later flows with `capture: false`) |
19
+ | **"Buscá / Creá al cliente con email X"** | `find_customer_by_email` then `create_customer` (or call `create_customer` directly — MP is idempotent on email) |
20
+ | **"Listame las tarjetas guardadas de X"** | `list_customer_cards` |
21
+ | **"Borrá esa tarjeta"** | `delete_customer_card` |
22
+ | **"Listame los métodos disponibles"** | `list_payment_methods` |
23
+ | **"¿Quién soy?" / "¿En qué cuenta estoy?"** | `get_account_info` |
24
+ | **"Pausá / Reactivá / Cancelá la suscripción"** | `pause_subscription` / `resume_subscription` / `cancel_subscription` |
18
25
 
19
- ## Tool selection rules
26
+ ## The two main "take a payment" patterns
20
27
 
21
- Five tools shipped, each with a distinct use case:
28
+ ### Pattern A hosted checkout (recommended for most agent flows)
22
29
 
23
- | If the user asks... | Call this tool |
24
- | --- | --- |
25
- | "Suscribí a X a un plan de $Y/mes" | `create_subscription` |
26
- | "Check si X ya pagó la suscripción" | `get_subscription_status` |
27
- | "Cancelá la suscripción de X" | `cancel_subscription` (CONFIRM FIRST — irreversible) |
28
- | "Pausá la suscripción de X temporalmente" | `pause_subscription` |
29
- | "Reactivá la suscripción pausada de X" | `resume_subscription` |
30
+ You only have a payer email. You don't want to handle PCI data. You want a URL to send via WhatsApp/email.
30
31
 
31
- **Confirm-before-cancel**: `cancel_subscription`'s description tells the agent
32
- this is irreversible. In Claude Sonnet 4.6+ this reliably triggers a "are you
33
- sure?" turn. Honor that when the user replies confirming, then call cancel.
32
+ ```
33
+ agent: create_payment_preference({ items, payer_email, external_reference })
34
+ agent: returns { preference_id, init_point_url, sandbox_init_point_url }
35
+ agent: send init_point_url to user (or sandbox_init_point_url in sandbox)
36
+ user pays on MP's hosted form (card / Rapipago / account_money / etc.)
37
+ MP fires webhook with topic="payment", data.id=<payment_id>
38
+ agent: get_payment(payment_id) → confirms status
39
+ ```
34
40
 
35
- ## Tool result schemas (memorize these)
41
+ ### Pattern B server-side payment (when you have a card_token OR using non-card method)
36
42
 
37
- ### `create_subscription` returns
43
+ You have a `token` from MP frontend SDK (Cardform/Bricks) OR you're charging account_money / cash.
38
44
 
39
- ```json
40
- {
41
- "subscription_id": "0fbe36a604cc4c35a7f74f04ab4a3281",
42
- "status": "pending",
43
- "init_point_url": "https://www.mercadopago.com.ar/subscriptions/checkout?preapproval_id=...",
44
- "next_step": "Send init_point_url to the customer. They must complete the first payment with card+CVV. Use get_subscription_status to confirm activation after they pay."
45
- }
45
+ ```
46
+ agent: create_payment({ amount, payment_method_id, payer_email, token?, installments? })
47
+ agent: → returns { payment_id, status: "approved" | "pending" | "rejected", status_detail }
46
48
  ```
47
49
 
48
- **ALWAYS surface the `init_point_url` to the user.** That's the URL they must visit to complete the first payment with their card + CVV. **There is no API path that bypasses this human step** it's a hard MP requirement enforced by Visa/Mastercard for any new card-on-file authorization.
50
+ **NEVER take raw card data in the agent runtime.** Card tokens come from MP's frontend SDK only. If the user pastes "4509 9535 6623 3704" into chat, REFUSEthat's a PCI violation. Always direct them to a hosted form via `create_payment_preference`.
49
51
 
50
- ### `get_subscription_status` returns
52
+ ## Result schemas (memorize)
51
53
 
52
- ```json
54
+ ### `create_payment_preference` returns
55
+ ```jsonc
53
56
  {
54
- "subscription_id": "...",
55
- "status": "pending" | "authorized" | "paused" | "cancelled",
56
- "payer_email": "buyer@example.com",
57
- "amount": 100,
58
- "currency": "ARS",
59
- "next_payment_date": "2026-06-05T08:48:54.000-04:00",
60
- "last_webhook_status": "authorized" | null,
61
- "last_webhook_at": "2026-05-05T13:00:00Z" | null
57
+ "preference_id": "1234567890-abc",
58
+ "init_point_url": "https://www.mercadopago.com.ar/checkout/v1/redirect?pref_id=...",
59
+ "sandbox_init_point_url": "https://sandbox.mercadopago.com.ar/...",
60
+ "external_reference": "order-abc",
61
+ "next_step": "Send init_point_url to the customer..."
62
62
  }
63
63
  ```
64
+ **Always surface `init_point_url` to the user** (or `sandbox_init_point_url` if your token is `TEST-`).
64
65
 
65
- - `status: pending` → buyer hasn't completed first payment yet
66
- - `status: authorized` → first payment done; MP will auto-charge per frequency
67
- - `status: paused` → call `resume_subscription` to reactivate
68
- - `status: cancelled` → terminal; new subscription needed to retry
69
-
70
- ### `cancel_subscription` / `pause_subscription` / `resume_subscription` return
71
-
72
- ```json
66
+ ### `create_payment` returns
67
+ ```jsonc
73
68
  {
74
- "subscription_id": "...",
75
- "status": "cancelled" | "paused" | "authorized",
76
- "message": "Subscription cancelled. No further charges will occur."
69
+ "payment_id": "12345678901",
70
+ "status": "approved" | "pending" | "rejected" | "in_process" | "cancelled",
71
+ "status_detail": "accredited" | "cc_rejected_other_reason" | "pending_waiting_payment" | ...,
72
+ "amount": 1500,
73
+ "currency": "ARS",
74
+ "installments": 1,
75
+ "payment_method": "account_money" | "visa" | "rapipago" | ...,
76
+ "payer_email": "buyer@x.com",
77
+ "external_reference": "order-abc",
78
+ "date_created": "...",
79
+ "date_approved": "..." | null
77
80
  }
78
81
  ```
79
82
 
80
- ## Error patterns and recovery
81
-
82
- The package emits typed error classes, all extending `MercadoPagoError`. Each
83
- is a clear signal of what went wrong and how to fix it.
84
-
85
- ### `MercadoPagoBackUrlInvalidError`
86
-
87
- App passed a non-HTTPS `backUrl`. Cannot be fixed by the agent — surface to the user as "the application is misconfigured (back_url must be HTTPS)".
88
-
89
- ### `MercadoPagoSelfPaymentError`
90
-
91
- The buyer email equals the seller account's email. MP refuses self-payment. Tell the user to use a different buyer email.
92
-
93
- ### `MercadoPagoAccountTypeMismatchError`
94
-
95
- Misleading MP error: "Cannot operate between different countries". Real meaning: seller token is "real-account-in-test-mode" but buyer email is a `test_user_*@testuser.com` AFIP-test-user. Tell the user to use a real consumer email as the buyer.
96
-
97
- ### `MercadoPagoPaymentRejectedError`
98
-
99
- MP risk engine rejected the first payment. **The preapproval was auto-cancelled by MP** — you cannot retry on the same subscription. Tell the user the payment was rejected and offer to create a fresh subscription with a different card.
100
-
101
- ### `MercadoPagoAuthorizeForbiddenError`
102
-
103
- App tried to PUT `status: authorized` via API. MP rejects: "only the payer can authorize". This means the app code is wrong — surface as a programming error, not a user-fixable problem.
104
-
105
- ### `MercadoPagoRateLimitError`
83
+ ### `calculate_installments` returns
84
+ ```jsonc
85
+ {
86
+ "amount": 12000,
87
+ "offers": [{
88
+ "payment_method_id": "visa",
89
+ "issuer_name": "Galicia",
90
+ "options": [
91
+ { "installments": 3, "installment_amount": 4000, "total_amount": 12000, "recommended_message": "3 cuotas sin interés de $4.000,00" },
92
+ { "installments": 6, "installment_amount": 2000, "total_amount": 12000, "recommended_message": "6 cuotas sin interés de $2.000,00" },
93
+ { "installments": 12, "installment_amount": 1314.20, "total_amount": 15770.40, "recommended_message": "12 cuotas de $1.314,20 ($15.770,40)" }
94
+ ]
95
+ }]
96
+ }
97
+ ```
98
+ **Surface `recommended_message` verbatim to the user** it's already in compliant Argentine Spanish format with proper currency formatting and includes the total when there's interest. AR's E 51/2017 transparency regulation requires this exact phrasing.
106
99
 
107
- MP rate-limited the request. Wait + retry with exponential backoff.
100
+ ### `refund_payment` returns
101
+ ```jsonc
102
+ {
103
+ "refund_id": "...",
104
+ "payment_id": "...",
105
+ "amount": 1500,
106
+ "status": "approved",
107
+ "message": "Full refund issued. Funds return to the buyer in 3-10 business days."
108
+ }
109
+ ```
108
110
 
109
- ## Composition with other `@ar-agents/*` packages
111
+ ## status_detail recovery actions (top values)
112
+
113
+ | `status_detail` | What it means | Agent action |
114
+ |---|---|---|
115
+ | `accredited` | Approved, money in seller account | Done. Fulfill order. |
116
+ | `cc_rejected_bad_filled_card_number` | Buyer entered wrong number | "El número de tarjeta es incorrecto, intentá de nuevo" |
117
+ | `cc_rejected_bad_filled_security_code` | CVV wrong | "El código de seguridad no coincide" |
118
+ | `cc_rejected_bad_filled_date` | Expiration wrong | "La fecha de vencimiento es incorrecta" |
119
+ | `cc_rejected_call_for_authorize` | Bank wants user to call | "Llamá a tu banco para autorizar el pago, después intentá de nuevo" |
120
+ | `cc_rejected_card_disabled` | Card disabled | "Tu tarjeta está deshabilitada — usá otra" |
121
+ | `cc_rejected_insufficient_amount` | Not enough funds | "Saldo insuficiente — usá otra tarjeta o método" |
122
+ | `cc_rejected_high_risk` / `cc_rejected_other_reason` | MP risk engine rejection | "El pago fue rechazado. Probá con otro método (Rapipago / account money)" |
123
+ | `cc_rejected_max_attempts` | Too many tries | "Esperá 24h antes de reintentar" |
124
+ | `cc_rejected_invalid_installments` | Cuotas no allowed for this card | "Probá con menos cuotas" — re-call `calculate_installments` |
125
+ | `pending_waiting_payment` | Ticket created (Rapipago/Pago Fácil) | "Pagá el ticket en cualquier sucursal — se acredita en 1-3 días" |
126
+ | `pending_contingency` | MP manual review | "Esperá unos minutos, MP está revisando el pago" |
127
+
128
+ ## Critical AR-specific gotchas
129
+
130
+ 1. **`statement_descriptor` MAX 13 CHARS.** Long brand names get silently truncated. Use abbreviations (`ASTRO AR` not `ASTRO ARGENTINA`).
131
+ 2. **`payer.email` cannot equal seller email** → MP error code 205 / `MercadoPagoSelfPaymentError`. Use a distinct buyer email even in sandbox.
132
+ 3. **Sandbox cardholder name selects outcome**: cardholder = `APRO` (approved), `OTHE` (rejected_other), `CONT` (pending_contingency), `CALL` (call_for_authorize), `FUND` (insufficient_amount), `SECU` (bad_filled_security_code), `EXPI` (bad_filled_date), `FORM` (bad_filled_other). DNI = `12345678`. ANY 3-digit CVV in sandbox.
133
+ 4. **Test cards (sandbox)**: Visa `4509 9535 6623 3704`, MasterCard `5031 7557 3453 0604`, Amex `3711 803032 57522`, debit Visa `4002 7686 9439 5619`. Expiration any future `MM/YY`.
134
+ 5. **`account_money` settles instantly** to seller. Card payments default to T+14 hold for new sellers (drops to T+1 after MP graduates the merchant). Tickets settle 1-3 days after the buyer pays.
135
+ 6. **First subscription payment requires CVV** — there is NO API path that bypasses this. The buyer MUST visit the `init_point_url` and complete the first card+CVV payment.
136
+ 7. **`back_url` MUST be HTTPS** — even in sandbox. `http://localhost:3000/done` is rejected.
137
+ 8. **`payer.identification`** — use `DNI` for consumers, `CUIT` for B2B (required for monotributo / IVA-discriminated invoicing), `CUIL` for employees.
138
+ 9. **CVV required on every saved-card charge** in AR by default. Merchant graduation can lift this for trusted sellers.
139
+ 10. **Idempotency-Key is mandatory** for POST since 2023. The lib auto-generates from caller-meaningful fields (external_reference + amount + timestamp); pass `idempotencyKey` explicitly if you want exact-match retry semantics.
140
+ 11. **`token` is single-use and expires in 7 days.** If a card payment fails, you can't reuse the token — re-tokenize on the frontend.
141
+
142
+ ## Cuotas / installments — the killer AR feature
143
+
144
+ This is what makes MP unique vs Stripe in any country. Workflow:
145
+
146
+ 1. Buyer's card BIN (first 6 digits) hits your frontend (Cardform exposes it before tokenizing).
147
+ 2. Agent calls `calculate_installments({ amount_ars, payment_method_id, bin })`.
148
+ 3. Receive `payer_costs` array.
149
+ 4. **Surface the `recommended_message` strings verbatim** — they're already in compliant AR format ("3 cuotas sin interés de $X").
150
+ 5. User picks installments count.
151
+ 6. Agent calls `create_payment({ ..., installments: N })`.
152
+
153
+ **Cuotas Simples** (gov interest-free 3 + 6 mo program) appears automatically as `installment_rate: 0` rows when the merchant category qualifies. Agent doesn't configure — just surfaces.
154
+
155
+ **Issuer-specific promos** (Día de la Madre, Hot Sale, Plan Z Naranja X) appear as new `payer_costs` entries when the BIN matches an active promo. Same treatment: surface verbatim.
156
+
157
+ ## Composition with other @ar-agents/* packages
110
158
 
111
159
  | Pair with | Why |
112
- | --- | --- |
113
- | [`@ar-agents/identity`](../identity) | Validate the buyer's CUIT before creating a subscription. Cuts an MP request for malformed CUITs. Optional but cheap. |
114
- | `@ar-agents/whatsapp` (planned) | Send the `init_point_url` to the buyer over WhatsApp instead of email. |
115
- | `@ar-agents/meta-ads` (planned) | Trigger an MP subscription as the conversion event after a Meta ad click. |
160
+ |---|---|
161
+ | [`@ar-agents/identity`](../identity) | Validate the buyer's CUIT before creating a payment/subscription. Cuts an MP request for malformed CUITs and lets you confirm "factura a nombre de [razón social]" before charging. |
162
+ | [`@ar-agents/whatsapp`](../whatsapp) | Send `init_point_url` to the buyer over WhatsApp instead of email. Combined with this package = the "billing assistant for SaaS argentinos" pattern. |
116
163
 
117
- ## Performance characteristics
164
+ ## Performance
118
165
 
119
- | Operation | Latency | Cost | External I/O |
120
- | --- | --- | --- | --- |
121
- | `create_subscription` | 200–600ms | $0 (creation) | MP REST + state write |
122
- | `get_subscription_status` | 200–500ms | $0 | MP REST + state read |
123
- | `cancel_subscription` | 200–500ms | $0 | MP REST + state write |
124
- | `pause_subscription` | 200–500ms | $0 | MP REST + state write |
125
- | `resume_subscription` | 200–500ms | $0 | MP REST + state write |
166
+ | Operation | Typical | Worst case |
167
+ |---|---|---|
168
+ | `create_payment_preference` | 200-500ms | 2s |
169
+ | `create_payment` (account_money) | 300-700ms | 2s |
170
+ | `create_payment` (card token) | 500-1500ms | 5s (if 3DS triggered) |
171
+ | `get_payment` | 100-300ms | 1s |
172
+ | `search_payments` | 200-600ms | 2s |
173
+ | `calculate_installments` | 100-300ms | 800ms |
174
+ | `refund_payment` | 300-800ms | 3s |
175
+ | `create_subscription` | 200-600ms | 2s |
126
176
 
127
- MP charges the **merchant** (the seller) a transaction fee on each
128
- auto-charge, but that's outside the agent's control or visibility.
177
+ Rate limit: ~250 req/min per access token. Lib does not retry — wrap with your own backoff if you exceed.
129
178
 
130
- ## Mercado Pago context (for non-AR agents)
179
+ ## Webhooks (planned for v0.3)
131
180
 
132
- - **Mercado Pago** = the dominant Argentine consumer payment platform (also Brazil, Mexico, Chile, etc.). Owned by Mercado Libre. Like Stripe in scope but with deeper LATAM-specific features.
133
- - **Subscription** = `preapproval` in MP's API. A recurring authorization tied to a customer's card.
134
- - **First payment requires CVV** = MP's enforced CX for setting up recurring billing. Saved cards CAN be charged later without CVV, but the FIRST one always needs it. There is no API workaround.
135
- - **Sandbox vs production** = different access tokens. `TEST-` prefix = sandbox; `APP_USR-` prefix = production. The lib is environment-agnostic; pass whichever token you've configured.
136
- - **Webhooks** = MP POSTs to your registered URL on subscription lifecycle events. Use `parseWebhookEvent()` and `verifyWebhookSignature()` from this package.
181
+ v0.2 ships `parseWebhookEvent()` for the `preapproval` topic (subscription lifecycle). Coming in v0.3:
182
+ - `payment` topic webhook parser
183
+ - `point_integration_wh` topic (QR scans)
184
+ - `x-signature` HMAC-SHA256 verification (replacing the v0.1 simpler `parseWebhookSignature`)
137
185
 
138
186
  ## What this package will NEVER do
139
187
 
140
- - Bypass MP's first-payment-CVV requirement (impossible).
141
- - Reactivate a cancelled subscription (MP doesn't allow it; create a new one).
142
- - Process payments outside the recurring/subscription flow (out of scope).
143
- - Make decisions about pricing or fees (caller's responsibility).
144
- - Cache state without explicit `SubscriptionStateAdapter` opt-in.
188
+ - Take raw card data in the agent runtime (PCI scope violation).
189
+ - Bypass MP's first-payment-CVV requirement for subscriptions (impossible).
190
+ - Reactivate a cancelled subscription or payment (MP doesn't allow).
191
+ - Implement Marketplace splits (different MP product, different OAuth flow — out of scope until v0.4+).
192
+ - Pay out the seller (transfers + withdrawals are dashboard-only / closed API).
193
+ - Make decisions about pricing or installments — caller's responsibility.
145
194
 
146
- ## Known production gotchas (read these)
195
+ ## Mercado Pago context (for non-AR agents)
147
196
 
148
- The README's [Known Gotchas](./README.md#known-gotchas-read-this-before-you-debug)
149
- section enumerates 11 specific MP behaviors that took the most time to figure out
150
- the first time. Skim it before debugging any unexpected behavior most likely
151
- your issue is one of those, with a typed error already in place.
197
+ - **Mercado Pago** = dominant Argentine consumer payment platform (also Brazil/Mexico/Chile/Colombia/Uruguay). Owned by Mercado Libre. Like Stripe in scope but with deeper LATAM-specific features (cuotas sin interés, in-store QR, account_money instant transfer).
198
+ - **Subscription** = `preapproval` in MP's API. Recurring authorization tied to a customer's card.
199
+ - **Sandbox vs production** = different access tokens. `TEST-` prefix = sandbox; `APP_USR-` prefix = production. Both use the same API host.
200
+ - **Site IDs**: AR=MLA, BR=MLB, MX=MLM, CL=MLC, CO=MCO, UY=MLU. v0.2 is verified end-to-end against MLA only.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,101 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.3.0
4
+
5
+ ### Minor Changes
6
+
7
+ - Robustness pass + 5 new features across both packages.
8
+
9
+ # `@ar-agents/mercadopago@0.3.0`
10
+
11
+ **Robustness (Section 6 of v0.3 spec)**
12
+
13
+ - Per-request timeout via `AbortSignal` (default 30s, configurable via `requestTimeoutMs`).
14
+ - Auto-retry on 5xx + 429 with exponential backoff (default 1 retry, configurable via `maxRetries`). Honors `Retry-After` header on rate-limit. **Never retries on 4xx** (deterministic user/config errors).
15
+ - New typed errors: `MercadoPagoTimeoutError`, `MercadoPagoOverloadedError` (HTML 503 detection — when MP returns HTML instead of JSON).
16
+ - `onCall` observability hook fires after every request with `{ method, path, durationMs, httpStatus, retried, success }`. Wire into OpenTelemetry / Sentry / Axiom without forking the lib.
17
+ - **Deterministic idempotency keys** — `create_payment` and `refund_payment` now use `sha256(meaningful_fields)` instead of `Date.now()`. Retries dedupe correctly on MP's side.
18
+
19
+ **New tools (3)**
20
+
21
+ - **`charge_saved_card`** — server-side retokenize + charge for returning customers. Requires CVV (AR MP doesn't support CVV-less via public API). Idempotent on (card_id, amount, external_reference).
22
+ - **`create_qr_payment`** — dynamic in-store QR via MP Point. Returns raw `qr_data` (EMVCo) + ready-to-display base64 PNG `qr_data_url`. Compatible with all AR wallets (Modo, BNA+, Cuenta DNI, Naranja X) via Transferencias 3.0 interop.
23
+ - **`cancel_qr_payment`** — clear a pending QR order on a POS so the next `create_qr_payment` doesn't 409.
24
+
25
+ **Total tool count: 24** (was 21 in v0.2). Added `qrcode` as runtime dep for in-store flow.
26
+
27
+ # `@ar-agents/identity-attest@0.2.0`
28
+
29
+ **3 new adapters bringing total to 5**
30
+
31
+ - **`Auth0Adapter`** (trust 0.7, or 0.85 with MFA) — OAuth2 Authorization Code flow with PKCE. Server-side `id_token` verification via `jose` JWKS. Optional MFA step-up via `acr_values` — when MFA is completed, `effective_trust_level` bumps to 0.85.
32
+ - **`MagicLinkSdkAdapter`** (trust 0.7) — Magic.link DIDToken validation via `@magic-sdk/admin` (optional peer dep). Lazy-loaded so users without Magic don't pay cold-start cost. Returns DID + email/phone/wallet claims.
33
+ - **`MercadoPagoIdentityAdapter`** (trust 0.5) — partial KYC via $1 micro-charge. MP doesn't expose a public KYC API, so we use payment-payer attestation: a successful payment proves MP validated the buyer's CUIT/DNI against their internal database. Auto-refunds the $1 by default. Returns `identification_type` + `identification_number` + email + name claims.
34
+
35
+ **New client methods**
36
+
37
+ - `submitOauthCode(requestId, code)` — for OAuth callbacks (Auth0)
38
+ - `submitMagicDidToken(requestId, didToken)` — for Magic.link
39
+ - `submitMercadoPagoPaymentId(requestId, paymentId)` — for MP webhook callbacks
40
+
41
+ **Quality**
42
+
43
+ - 28/28 tests pass (was 15 in v0.1)
44
+ - 12.93 KB ESM brotli'd (jose is treeshakeable; was 4.44 KB without OAuth adapter)
45
+ - publint + arethetypeswrong all 🟢
46
+ - `jose` is a dep (used by Auth0Adapter); `@magic-sdk/admin` is optional peer dep
47
+
48
+ **Trust levels reference (current)**
49
+
50
+ - 0.3 — `WhatsAppOtpAdapter` (phone-owned)
51
+ - 0.5 — `EmailMagicLinkAdapter` (email-owned), `MercadoPagoIdentityAdapter` (partial KYC)
52
+ - 0.7 — `Auth0Adapter` (federated identity), `MagicLinkSdkAdapter` (Magic-managed)
53
+ - 0.85 — `Auth0Adapter` with MFA enforcement
54
+ - 0.95 — gov-verified (planned, blocked on AR SID rollout)
55
+
56
+ ## 0.2.0
57
+
58
+ ### Minor Changes
59
+
60
+ - v0.2.0 — full Payments surface (the "Stripe Agent Toolkit" for Mercado Pago)
61
+
62
+ Extends from Subscriptions-only (v0.1, 5 tools) to the complete agent toolkit (21 tools). New surface:
63
+
64
+ **Payments (5 tools)**: `create_payment`, `get_payment`, `search_payments`, `cancel_payment`, `capture_payment`. Supports both transparent flow (with card_token) and server-side flow (account_money / Rapipago / Pago Fácil). Auto-generates idempotency keys (mandatory since 2023).
65
+
66
+ **Refunds (2 tools)**: `refund_payment` (full or partial), `list_refunds`. Auto-idempotent on (payment_id, amount).
67
+
68
+ **Checkout Pro (2 tools)**: `create_payment_preference` (THE recommended "agent takes a payment" tool — returns hosted URL, no PCI scope needed), `get_payment_preference`. Configurable max installments, excluded payment types, statement descriptor (13-char AR limit), expiration.
69
+
70
+ **Customers + Cards (4 tools)**: `create_customer` (idempotent on email), `find_customer_by_email`, `list_customer_cards`, `delete_customer_card`. Foundation for saved-card flows.
71
+
72
+ **Payment Methods + Installments (2 tools)**: `list_payment_methods` (lists AR methods: visa, master, naranja, naranja_x, cabal, account_money, rapipago, etc.), `calculate_installments` (THE killer AR feature — returns `recommended_message` strings in compliant Argentine format, includes Cuotas Simples gov program + issuer-specific promos via BIN).
73
+
74
+ **Account (1 tool)**: `get_account_info` (site_id, country, user_type).
75
+
76
+ **v0.1 Subscriptions (5 tools)**: kept identical for backward compatibility.
77
+
78
+ # Live-tested
79
+
80
+ Verified end-to-end against MP sandbox: account info, payment methods (21 AR methods returned), installments (81 visa offers with proper `recommended_message`), preference creation (returns real init_point + sandbox_init_point URLs).
81
+
82
+ # Documentation
83
+
84
+ - AGENTS.md updated with decision tree, status_detail recovery actions (top 12 values), AR-specific gotchas (statement_descriptor 13-char limit, sandbox cardholder name selects outcome, test cards reference, account_money instant settlement vs T+14 card hold, etc.).
85
+ - tools.manifest.json updated to v0.2 with all 21 tools documented (purity, sideEffects, latency, input/output schemas, whenToUse, whenNotToUse).
86
+
87
+ # Bundle size
88
+
89
+ 8.07 KB ESM brotli'd (under 22 KB budget). Doubled tool count, still half the size limit.
90
+
91
+ # What's NOT in v0.2 (deferred to v0.3+)
92
+
93
+ - `charge_saved_card` (retokenize + charge in one call) — coming v0.3
94
+ - `create_qr_payment` (in-store dynamic QR) — coming v0.3
95
+ - Marketplace splits (OAuth, application_fee) — v0.4
96
+ - Raw-PAN tokenization — never (PCI scope; agents must use Checkout Pro)
97
+ - Webhook x-signature verification for `payment` topic (v0.1 covers `preapproval`) — v0.3
98
+
3
99
  All notable changes to `@ar-agents/mercadopago` are documented here. The format
4
100
  follows [Keep a Changelog](https://keepachangelog.com/) and the project adheres
5
101
  to [Semantic Versioning](https://semver.org/).
@@ -9,6 +105,7 @@ to [Semantic Versioning](https://semver.org/).
9
105
  Initial release. Extracted from the `ar-agents-mp-hello` proof-of-concept.
10
106
 
11
107
  ### Added
108
+
12
109
  - `MercadoPagoClient` — typed wrapper around MP REST API for preapprovals
13
110
  (create / get / cancel / pause / resume).
14
111
  - `mercadoPagoTools()` — drop-in tool collection for the Vercel AI SDK 6+.
@@ -28,6 +125,7 @@ Initial release. Extracted from the `ar-agents-mp-hello` proof-of-concept.
28
125
  best-fit class.
29
126
 
30
127
  ### Known limitations
128
+
31
129
  - Subscriptions API only. No one-off Checkout, no Marketplace, no Pix.
32
130
  - AR (MLA) verified end-to-end. Other LATAM sites should work but aren't
33
131
  exercised by the test suite.