Integración completa con MercadoPago en Go: Checkout Pro (Preferences API), webhooks con validación HMAC-SHA256 (x-signature + x-request-id), Payments API, tarjetas de test Argentina, y buenas prácticas de producción. Cubre el flujo end-to-end desde crear la preference hasta confirmar el pago en el webhook y marcar la orden como pagada. Optimizado para stack Go + HTTP directo (no requiere SDK). Incluye checklist de sandbox con ngrok y pasaje a producción. Triggers: "MercadoPago", "Checkout Pro", "webhook MP", "x-signature", "HMAC MP", "notification_url", "tarjetas de test", "APRO", "sandbox MP", "preference".
Skill para integrar MercadoPago con Checkout Pro en stack Go, con foco en TiendaGo y en los patrones de producción reales para Argentina (ARS, DNI, Rapipago/Pago Fácil, MP Wallet).
POST https://api.mercadopago.com/checkout/preferences con items + external_reference (tu order ID) + back_urls + notification_url. MP responde con init_point (redirigir al usuario ahí).approved / pending / rejected.notification_url con {"type":"payment","data":{"id":"..."}} + headers x-signature, x-request-id.id:<data.id>;request-id:<x-request-id>;ts:<ts>;.GET /v1/payments/{id} con tu access token. Leés y . — solo usalo para saber qué consultar.statusexternal_referenceid200 OK (o 201) en menos de 22 segundos.| Archivo | Cuándo usarlo |
|---|---|
| references/checkout-pro.md | Crear Preferences, back_urls, payment_methods, exclusiones, cuotas, expiration |
| references/webhooks-hmac.md | CRÍTICO — validar la firma del webhook (Go listo para pegar) |
| references/payments-api.md | Tabla completa de status y status_detail — mapeo a estados internos |
| references/test-cards-argentina.md | Números reales de tarjetas de test AR + magic words (APRO/OTHE/CONT/...) |
| references/go-sdk.md | Si migrás de HTTP directo al SDK oficial github.com/mercadopago/sdk-go |
| references/troubleshooting.md | Errores comunes, cc_rejected_*, anti-fraude, retries duplicados |
| Tipo | Formato | Dónde se usa |
|---|---|---|
| Access Token TEST | TEST-XXXXXX-XXXXX-... | Backend en sandbox. Sirve para crear preferences de prueba. |
| Access Token PROD | APP_USR-XXXXXX-... | Backend en producción. |
| Webhook Secret | string random | Solo para HMAC del webhook. Se ve en: Your integrations → app → Webhooks → Configure Notification → Reveal secret. |
Ubicación en el panel: https://www.mercadopago.com.ar/developers/panel/app → tu app → Credentials (Test / Production).
Importante: los TEST credentials son de la app, pero para probar el pago completo necesitás además un test buyer user (comprador de prueba) distinto del seller. Se crean en: app → Test accounts. Creás 1 Seller + 1 Buyer, ambos del mismo país. Al buyer lo usás en incógnito para pagar.
MP_ACCESS_TOKEN=TEST-xxxx... # o APP_USR-xxxx... en prod
MP_WEBHOOK_SECRET=xxxxxxxx # del dashboard, solo para HMAC
MP_BASE_URL=https://abcd1234.ngrok.app # en sandbox, tu ngrok
# En prod: MP_BASE_URL=https://ecobiocosmetica.com.ar
Gotcha de sandbox: MP no envía notificaciones a pagos creados con test credentials a menos que hayas configurado el webhook en el panel (no via
notification_urlde la preference). Si querés testear el HMAC real, configurá la URL en: app → Webhooks → Configure Notifications → Mode: Test.
Base: https://api.mercadopago.com
POST /checkout/preferences # crear preference
GET /checkout/preferences/{id} # leer preference
PUT /checkout/preferences/{id} # actualizar (algunos campos)
GET /v1/payments/{id} # leer pago (usar después del webhook)
GET /v1/payments/search?... # buscar (filtros: external_reference, date, status)
POST /v1/payments/{id}/refunds # reembolso total o parcial
PUT /v1/payments/{id} # cambiar estado (cancel, capture)
Headers en todo:
Authorization: Bearer ACCESS_TOKEN
Content-Type: application/json
{
"payer": {
"name": "Juan",
"surname": "Perez",
"email": "[email protected]",
"phone": { "area_code": "11", "number": "22223333" },
"identification": { "type": "DNI", "number": "12345678" },
"address": {
"zip_code": "1414",
"street_name": "Av. Corrientes",
"street_number": 1234
}
}
}
DNI en test: en Argentina,
DNI 12345678dispara flujos específicos junto con el cardholderAPRO/OTHE. Ver test-cards-argentina.md.
x-signature — si no matchea, HTTP 401 y cortar.data.id puede llegar varias veces (MP reintenta si no respondés 200). Guardar payment_ids procesados; si ya lo procesaste, responder 200 sin hacer nada.GET /v1/payments/{id} con tu access token — nunca confíes en el body del webhook, solo en esta respuesta.return HTTP 200 antes de 22s. Si el procesamiento es pesado, encolar y responder ya.x-request-id, data.id, status leído. Si el HMAC falla en prod pero anda en test → revisar si leés el body raw (no re-serializado) y si el secret está bien.Código Go listo para pegar en references/webhooks-hmac.md.
| MP status | Acción en tu sistema |
|---|---|
approved + status_detail: accredited | marcar orden paid, mandar email, descontar stock |
pending | orden pending_payment — esperar (Rapipago puede tardar 2-3 días) |
in_process | revisión manual de MP — esperar notificación |
rejected | orden payment_failed — mostrar status_detail al usuario |
cancelled | orden cancelled — liberar stock |
refunded / charged_back | marcar orden, devolver stock |
Tabla completa (todos los status_detail) en references/payments-api.md.
MP reintenta si no contestás 200/201 en ≤22s:
retry 1: 0 min (inmediato)
retry 2: 15 min
retry 3: 30 min
retry 4: 6 h
retry 5: 48 h
retry 6-8: 96 h cada una
8 intentos totales. Implementar idempotencia es obligatorio (no opcional) — si tu sistema se cae entre el paso 3 y el 5 del flujo, MP te va a volver a avisar del mismo pago.
https://tudominio.com/webhooks/mp/ipnMP_BASE_URL en env apunta al dominio real (no ngrok)GET /v1/payments/search?external_reference=... para órdenes pending de +1 horaMP mide la calidad de tu integración. Para subirlo:
Ver en: Your integrations → app → Integration quality.
TiendaGo usa HTTP directo (internal/mp/client.go). Pros y contras vs el SDK oficial (github.com/mercadopago/sdk-go):
HTTP directo (actual):
SDK oficial:
Recomendación para TiendaGo: quedarse con HTTP directo. El surface es chico (3 endpoints: POST preferences, GET payments, POST webhooks). El SDK pesa más de lo que ayuda. Si alguna vez se migra, está todo en references/go-sdk.md.