Errores
Todas las respuestas de error de /v1 tienen la misma forma:
{
"error": {
"code": "PAYMENT_INVALID_STATE",
"message": "El payment intent no admite esa operación en su estado actual",
"request_id": "3e29bd22-e528-4d10-8f11-f808b88d42dd",
"details": {}
}
}
- Usa
codepara decidir qué hacer: es estable.messagees para personas y puede cambiar. request_ididentifica tu llamada. Inclúyelo al pedir soporte. Toda respuesta, exitosa o no, trae el mismo valor en el headerX-Correlation-Id; si tú envías ese header, se respeta tu valor, así puedes seguir la llamada con tu propio id.detailstrae información adicional cuando aplica (por ejemplo, los campos inválidos oretry_after_seconds).- Nunca se exponen errores internos ni respuestas crudas del proveedor.
Códigos
| Código | HTTP | Qué pasó | Qué hacer |
|---|---|---|---|
AUTH_INVALID_API_KEY | 401 | falta la API key o no es válida | revisa Authorization: Bearer pay_… |
AUTH_KEY_REVOKED | 401 | la API key fue revocada | usa una vigente |
RATE_LIMIT_EXCEEDED | 429 | tu aplicación superó el límite de solicitudes | espera details.retry_after_seconds y reintenta |
VALIDATION_ERROR | 400 | body, parámetros o headers inválidos (incluye Idempotency-Key faltante) | corrige según details |
SANDBOX_SCENARIO_NOT_ALLOWED | 400 | enviaste X-Sandbox-Scenario con una aplicación de producción | quita el header |
IDEMPOTENCY_CONFLICT | 409 | la Idempotency-Key ya se usó con otro body | usa una clave nueva por operación |
PAYMENT_NOT_FOUND | 404 | el intent o payment no existe en tu organización | revisa el id |
PAYMENT_INVALID_STATE | 409 | la operación no aplica al estado actual (o el pago cambió mientras tanto) | reobtén el intent y decide |
PAYMENT_ALREADY_TERMINAL | 409 | el intent ya terminó (FAILED, CANCELLED, EXPIRED, REFUNDED) | crea un intent nuevo si corresponde |
CONNECTOR_NOT_CONFIGURED | 422 | el proveedor pedido no está habilitado para tu comercio | usa auto o pide habilitarlo |
CONNECTOR_UNAVAILABLE | 503 | no hay un proveedor disponible en este momento | reintenta más tarde |
REFUND_AMOUNT_INVALID | 422 | la devolución supera lo autorizado menos lo ya devuelto | ajusta el monto |
MERCHANT_ACCOUNT_NOT_FOUND | 404 | el comercio no existe en tu organización | revisa merchant_account_id |
CONNECTOR_CONFIG_NOT_FOUND | 404 | ese proveedor no está configurado para el comercio | revisa el id |
CONNECTOR_CONFIG_ALREADY_EXISTS | 409 | ese proveedor ya está configurado para el comercio | actualízalo con PATCH |
API_CREDENTIAL_NOT_FOUND | 404 | la API key a revocar no existe en tu aplicación | revisa el id |
WEBHOOK_ENDPOINT_URL_NOT_ALLOWED | 400 | la URL del webhook no cumple las reglas del ambiente | ver Webhooks |
WEBHOOK_ENDPOINT_NOT_FOUND | 404 | el endpoint no existe en tu aplicación | revisa el id |
WEBHOOK_DELIVERY_NOT_FOUND | 404 | la entrega no existe para ese endpoint | revisa el id |
WEBHOOK_DELIVERY_ALREADY_SUCCEEDED | 409 | esa entrega ya fue exitosa | no hace falta reintentarla |
PAYLOAD_TOO_LARGE | 413 | el body es demasiado grande | envía solo los campos del contrato |
INTERNAL_ERROR | 500 | error inesperado | reintenta; si persiste, reporta el request_id |
Reintentos seguros
- Reintentar una operación con la misma
Idempotency-Keynunca crea un segundo cobro. - Ante
5xx,429,503o timeouts, reintenta con backoff exponencial. - Ante otros
4xx, no reintentes sin corregir el request. Ver Idempotencia.
Límite de solicitudes
Cada aplicación tiene un límite de solicitudes por ventana de tiempo (por defecto, 120 por minuto).
Al superarlo recibes 429 RATE_LIMIT_EXCEEDED con details.retry_after_seconds. Si tu volumen
necesita más, pídelo al habilitar tu aplicación.