Preguntas frecuentes y solución de problemas
El comprador volvió a mi return_url, pero el pago sigue en REQUIRES_ACTION o PROCESSING
Es normal: el retorno del navegador puede llegar antes que la confirmación del proveedor (sobre todo
en Mercado Pago). Muestra "estamos procesando tu pago" y espera el webhook payment.authorized o
payment.failed, o consulta GET /v1/payment-intents/{id} cada pocos segundos durante un rato.
Recibí el mismo webhook dos veces
Es esperado: los webhooks se entregan al menos una vez. Guarda el id del evento (X-Pay-Event-Id)
y, si ya lo procesaste, responde 2xx sin repetir efectos.
Mi endpoint no recibe webhooks
- Revisa las entregas:
GET /v1/admin/webhook-endpoints/{id}/deliveriesmuestra el código HTTP y un extracto de lo que respondió tu servidor. - Tu endpoint debe responder
2xxen menos de 5 segundos. - En producción la URL debe ser
https, puerto 443 y dominio público. - Si una entrega quedó agotada, vuelve a programarla con
POST /v1/admin/webhook-endpoints/{id}/deliveries/{deliveryId}/retry.
La firma del webhook no coincide
- Calcula el HMAC sobre el body crudo, no sobre un JSON reserializado.
- Firma
X-Pay-Timestamp + "." + body, con elsecretdel endpoint correcto (cada endpoint tiene el suyo). - Compara contra el valor después de
v1=. - Revisa la hora de tu servidor: más de 5 minutos de diferencia invalida el aviso.
Recibo 409 IDEMPOTENCY_CONFLICT
Estás reusando una Idempotency-Key con un body distinto. Genera una clave por operación y reúsala
solo para reintentar exactamente la misma operación.
Recibo 422 CONNECTOR_NOT_CONFIGURED
Pediste un proveedor que tu comercio no tiene habilitado. Usa provider: "auto" o habilita ese
proveedor en el comercio (Proveedores y routing).
Recibo 503 CONNECTOR_UNAVAILABLE
Ningún proveedor del comercio está disponible en este momento. Reintenta en unos segundos con la
misma Idempotency-Key. Si tienes más de un proveedor habilitado, auto usa el siguiente disponible.
Recibo 429 RATE_LIMIT_EXCEEDED
Tu aplicación superó su límite de solicitudes. Espera details.retry_after_seconds antes de
reintentar y evita consultar en bucle: prefiere los webhooks.
¿Puedo cambiar de proveedor para un pago ya iniciado?
Sí, pidiendo un checkout nuevo sobre el mismo intent con otro provider, mientras el intent esté en
CREATED o REQUIRES_ACTION (antes de que el proveedor empiece a procesar el pago). El checkout
anterior deja de ser válido.
¿Cómo devuelvo un pago?
Con POST /v1/payments/{paymentId}/refunds, usando el payment.id del intent autorizado. Ver
Devoluciones.
¿Qué necesito para salir a producción?
Una aplicación PRODUCTION con sus API keys, tus webhook endpoints de producción y el comercio con
sus proveedores en modo PRODUCTION. Ver Sandbox.