Lane · Documentación

Conceptos

Errores

Todos los errores tienen el mismo cuerpo: una frase en error, un code para tu código y un request_id para soporte.

Forma de un error

{
  "error": "Este comercio todavía no puede cobrar con ese medio de pago",
  "code": "payment_method_unavailable",
  "details": "Los que tiene habilitados son: card, pse.",
  "request_id": "b7d1c6f0-…"
}

error describe el problema y está pensado para tu log, no para mostrárselo al comprador. code es lo que conviene leer desde tu código: cuando el error no tiene uno propio, es el nombre del código HTTP (bad_request, not_found, conflict…). details viene solo cuando hay algo más que decir, y request_id identifica la petición si nos escribes por ella.

Códigos

CódigoSignifica¿Reintentar?
400El cuerpo no cumple el contrato: falta un campo, sobra otro o el tipo no corresponde.No, hasta corregirlo
401La llave falta, no existe o venció. Ver Llaves y entornos.No
402El emisor o la red no aprobaron el cobro. En POST /v1/payments, el cobro queda creado con status: "failed": la respuesta trae su payment_id y un objeto decline con status_detail y advice_action (ver Cobros). details, cuando viene, es una frase corta con el motivo.Según decline.advice_action
403La llave es válida pero no puede hacer eso. Para una plataforma: not_a_platform u on_behalf_not_supported (ver Plataformas).No
404La ruta no existe. También cuando el recurso no es de tu organización.No
409La operación choca con el estado de las cosas. Con idempotency_key_in_use, la primera petición con esa clave todavía se está procesando.Solo idempotency_key_in_use: en unos segundos, con la misma clave
422El contrato está bien pero la operación es imposible: monto fuera del tope de un medio instantáneo, por ejemplo. Con idempotency_key_reused, esa clave ya se usó con otra petición. Con payment_method_unavailable, el comercio no tiene habilitado ese medio de pago. Con operation_not_supported_for_method, ese medio no admite la operación (un reembolso de PSE). Con extra_items_not_supported, mandaste extra_items sin ser una plataforma. Con contact_rejected, la red de tarjetas no aceptó el sitio web o el teléfono de un comercio.No
429Con rate_limited: más de 300 peticiones en un minuto con la misma llave. La cabecera Retry-After dice cuántos segundos esperar.Sí, después de Retry-After
500Algo se rompió de nuestro lado.Sí, con la misma Idempotency-Key y espera creciente
502La conexión de Lane con el procesador falló (sus credenciales, no tu llave), y trae provider_status. Cuando el procesador rechaza una operación, el error conserva su código (400, 402, 422…) con provider_status y, si su motivo es una frase corta, details. Si no responde a tiempo, es 504.Sí, con la misma Idempotency-Key
504Con charge_unconfirmed: el procesador no respondió a tiempo y no se sabe si el cobro pasó. La respuesta trae payment_id.No. Consulta ese cobro o espera su webhook
Un recurso ajeno responde 404, no 403. Si pides un cobro que existe pero es de otra organización, la API contesta 404. Es a propósito: un 403 confirmaría que ese identificador existe.

Errores de validación más frecuentes

Llegan como 400, en español. Un campo con el tipo equivocado responde error: "Los datos enviados no son válidos" y la lista de problemas en details, separados por ;. Una combinación que no se puede cobrar responde la frase directamente en error.

MensajeQué corregir
amount debe ser un entero positivo en la unidad mínima de la monedaManda centavos, como entero. Ver Montos.
Falta instrument_id o provider_instrument_idUn cobro contra tarjeta guardada necesita saber qué tarjeta.
cvv es obligatorio cuando initiator es customer…Si el cliente está presente, el CVV es obligatorio.
No envíes cvv cuando initiator es merchant…En un cobro automático no hay quien lo escriba: no lo mandes.
parent_transaction_data es obligatorio para continuar una serie…Un cobro recurrente tiene que apuntar al primero de la serie.
installments.quantity debe ser un entero mayor o igual a 2…Para un pago sin cuotas, omite el objeto installments.
success_url debe ser una URL válidaTiene que ser http o https absoluta.

Reintentos

Una petición que se corta por un timeout te deja sin saber si pasó. Para poder mandarla otra vez sin riesgo, ponle nombre: una cabecera Idempotency-Key con un valor tuyo, único para esa operación. Si llega dos veces con la misma clave, se ejecuta una sola vez y la segunda recibe la respuesta de la primera, con la cabecera Idempotent-Replayed: true.

Un cobro que se puede reintentar

curl -X POST https://api.lane.money/v1/payments \
  -H "Authorization: Bearer sk_test_…" \
  -H "Idempotency-Key: pedido-4821-cobro" \
  -H "Content-Type: application/json" \
  -d '{ "amount": 8900000, "instrument_id": "c1a9f3e0-…" }'
La aceptanQué evita
POST /v1/paymentsCobrar dos veces la misma tarjeta.
POST /v1/payments/{id}/refund y las demás operaciones sobre un cobroDevolver, capturar o anular dos veces.
POST /v1/checkout/sessions y POST /v1/payment_linksCrear dos pantallas de pago para un pedido.
POST /v1/enrollment/sessionsCrear dos pantallas para guardar la misma tarjeta.
POST /v1/platform/signup-linksCrear dos enlaces de registro para un comercio.
  • Una clave por operación, no por pedido. El cobro de un pedido y su devolución llevan claves distintas. Genera la clave antes del primer intento y guárdala: si la generas dentro del reintento, cada intento es una operación nueva.
  • Hasta 255 caracteres, y vale 24 horas. La clave es de la llave secreta que la mandó.
  • El mismo cuerpo. La misma clave con otra petición responde 422 (idempotency_key_reused). El cvv no cuenta para la comparación, y no se guarda.
  • Dos a la vez: corre una. La otra recibe 409 (idempotency_key_in_use); vuelve a intentar en unos segundos.
  • Un error no se guarda. Si la petición falló con un error —una validación, un rechazo que llegó como 4xx—, el reintento se procesa de nuevo. Un rechazo que llegó como 201 con status: "failed" sí es una respuesta: con la misma clave recibes ese mismo cobro fallido. Para volver a intentar, usa otra clave. Y charge_unconfirmed (504) también se guarda: la misma clave lo devuelve sin cobrar de nuevo.
  • `Lane-On-Behalf-Of` cuenta. Una plataforma que cobra a nombre de dos comercios con la misma clave hace dos peticiones distintas: la segunda responde 422 (idempotency_key_reused).
Un cobro sin confirmar no se reintenta. La excepción a esa última regla es el 504 con charge_unconfirmed: el procesador no respondió y el cobro pudo haber pasado. Con la misma clave recibes ese mismo error, nunca un segundo cobro. Consulta el payment_id que trae la respuesta, o espera el webhook, y decide con el estado que veas.

Sin la cabecera, todo funciona como siempre: un POST reintentado es una operación nueva. Por eso conviene mandarla siempre que la operación mueva plata, y guardar además tu identificador en metadata: vuelve en el objeto del cobro tal como lo mandaste (salvo las llaves que empiezan por lane_ o blink_).

Esta página en markdown: /docs/errores.md · Toda la documentación: /docs/llms-full.txt