Lane · Documentación

Referencia

Cobros

El objeto central de la API. Todo lo demás existe para crear uno o para entenderlo.

Recorrido de un cobro: pending → authorized → processing → succeeded, o failed / cancelled / refunded. Esta sección documenta authorized.

Crear un cobro

POST/v1/payments

Cobra contra una tarjeta ya guardada. Para cobrar con el comprador presente, usa una sesión de checkout.

Cabeceras

CampoTipoObligatorioDescripción
Idempotency-KeytextonoOpcional, hasta 255 caracteres. Con un valor propio de cada cobro, reintentar no cobra dos veces: la segunda petición recibe la respuesta de la primera. Si el procesador no respondió a tiempo (504, charge_unconfirmed), la misma clave devuelve ese mismo error y no un segundo cobro. Ver Reintentos.

Cuerpo

CampoTipoObligatorioDescripción
amountenterosíEn centavos. Cero solo con intent: "account-status".
currencytextonoPor defecto COP.
instrument_idUUIDcondicionalLa tarjeta guardada en Lane. Obligatorio si no mandas provider_instrument_id; no mandes los dos.
provider_instrument_idtextocondicionalEl identificador de la tarjeta en el procesador, para migraciones.
initiatorcustomer · merchantnoQuién dispara el cobro. Por defecto merchant.
cvvtextocondicional3 o 4 dígitos. Obligatorio con initiator: "customer", prohibido con merchant.
order_typetextonoEl tipo de orden para la red. Ver Cobro recurrente.
intentauthorization · pre-authorization · account-statusnoPor defecto authorization.
captureobjetono{ "mode": "AUTOMATIC" | "MANUAL" | "SCHEDULED" }. Con automática (la de defecto) el cobro aprobado te llega como succeeded de una. Manual lo deja en authorized hasta que lo captures.
installmentsobjetono{ "quantity": 3 }, mínimo 2. Omítelo para un pago sin cuotas.
parent_transaction_dataobjetocondicionalEnlace al primer cobro de la serie. Obligatorio en cobros recurrentes sin el cliente presente.
metadataobjetonoTus datos, de vuelta en el cobro junto con algunos campos que agrega Lane (initiator, order_type…). Las llaves que empiezan por lane_ o blink_ se descartan al guardar. No cuentes con ella en los avisos payment.*: consulta el cobro.

Cobrar una tarjeta guardada

curl -X POST https://api.lane.money/v1/payments \
  -H "Authorization: Bearer sk_test_…" \
  -H "Idempotency-Key: suscripcion-311-ciclo-4" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 8900000,
    "currency": "COP",
    "instrument_id": "c1a9f3e0-…",
    "initiator": "merchant",
    "order_type": "recurring",
    "parent_transaction_data": { "first_payment_id": "9b41d0c7-…" }
  }'

Respuesta 201

{
  "object": "payment",
  "payment": {
    "object": "payment",
    "id": "a02e5b19-…",
    "amount": 8900000,
    "refunded_amount": 0,
    "currency": "COP",
    "status": "succeeded",
    "status_detail": "CAPTURED",
    "payment_method": "card",
    "metadata": { "initiator": "merchant", "order_type": "recurring" },
    "environment": "test",
    "processed_at": "2026-09-06T18:22:41.000Z",
    "created_at": "2026-09-06T18:22:39.000Z"
  },
  "provider": { "name": "processor", "operation": "authorize_payment" }
}

El cobro viene en payment, con la misma forma que GET /v1/payments/{id}. provider solo dice que pasó por el procesador: su respuesta no se repite. Lo que sirve de ella está en los campos del cobro: installment (las cuotas que aplicó el emisor), parent_transaction_data (la serie) y decline (por qué se rechazó).

Si la tarjeta rechaza el cobro. La respuesta es 201 con status: "failed" y un objeto decline: status_detail dice el motivo (INSUFFICIENT_FUNDS, EXPIRED_CARD…) y advice_action, cuando la red lo da, si conviene volver a intentar: RETRY (al menos 10 minutos después, una o dos veces), UPDATE_AND_RETRY (con otra tarjeta), AUTHENTICATE_AND_RETRY (con el cliente presente: vuelve a registrar la tarjeta o cobra por checkout) o DO_NOT_RETRY (nunca con esa tarjeta: la red sanciona los reintentos). null si no lo dio. Algunos rechazos llegan como error (un 402 u otro 4xx, con provider_status) y no como 201: el cobro igual queda creado como failed, y el error trae payment_id y el mismo objeto decline (null si la red no dijo nada). GET /v1/payments/{id} y el aviso payment.failed lo traen igual.

Consultar un cobro

GET/v1/payments/{id}

Devuelve el cobro con su estado actual.

Query

CampoTipoObligatorioDescripción
syncbooleanonotrue consulta al procesador antes de responder. Más lento; para depurar.

Consultar

curl "https://api.lane.money/v1/payments/a02e5b19-…" \
  -H "Authorization: Bearer sk_test_…"

Respuesta 200

{
  "object": "payment",
  "id": "a02e5b19-…",
  "amount": 8900000,
  "refunded_amount": 0,
  "currency": "COP",
  "status": "succeeded",
  "status_detail": "CAPTURED",
  "payment_method": "card",
  "customer": { "email": "ana@example.com" },
  "metadata": { "order_id": "4821", "initiator": "merchant", "order_type": "recurring" },
  "provider_payment_id": "…",
  "provider_transaction_id": "…",
  "checkout_session_id": null,
  "environment": "test",
  "cleared_at": "2026-09-07T04:00:00.000Z",
  "processed_at": "2026-09-06T18:22:41.000Z",
  "created_at": "2026-09-06T18:22:39.000Z",
  "updated_at": "2026-09-07T04:00:02.000Z"
}

Según el cobro, trae además installments (lo que pediste) e installment (lo que aplicó el emisor), parent_transaction_data, decline (solo en uno failed), intent y extra_items (los productos que el comprador agregó en la página de pago). cleared_at es la fecha en que la red compensó el cobro, no la del depósito.

Listar cobros

GET/v1/payments

Los cobros del entorno de la llave, del más nuevo al más viejo.

Query

CampoTipoObligatorioDescripción
statustextonoUno o varios separados por coma: succeeded,refunded.
customer_idUUIDnoSolo los de ese cliente.
created_afterfechanoISO 8601. Desde esa fecha en adelante.
limitenteronoPor defecto 25, máximo 100: un valor mayor se toma como 100.
starting_aftercursornoEl next_cursor de la página anterior.

Cada fila es más liviana que el detalle: trae el cliente por customer_id en vez del objeto customer, y no trae refunded_amount ni los campos de cuotas, serie o rechazo. Para esos, consulta el cobro.

Cobros aprobados de esta semana

curl "https://api.lane.money/v1/payments?status=succeeded&created_after=2026-09-01T00:00:00Z&limit=100" \
  -H "Authorization: Bearer sk_test_…"

Respuesta 200

{
  "object": "list",
  "has_more": false,
  "next_cursor": null,
  "data": [
    {
      "object": "payment",
      "id": "a02e5b19-…",
      "amount": 8900000,
      "currency": "COP",
      "status": "succeeded",
      "status_detail": "CAPTURED",
      "payment_method": "card",
      "customer_id": "44f1…",
      "checkout_session_id": null,
      "metadata": { "order_id": "4821" },
      "cleared_at": "2026-09-07T04:00:00.000Z",
      "processed_at": "2026-09-06T18:22:41.000Z",
      "created_at": "2026-09-06T18:22:39.000Z"
    }
  ]
}

Operar sobre un cobro

Las cinco operaciones son POST sin cuerpo obligatorio. Un reembolso o un ajuste parcial admiten { "amount": … } en centavos; sin ese campo, la operación es por el total. Un reembolso admite además reason (requested_by_customer, duplicate, not_delivered, returned, fraud u other) y comment (hasta 300 caracteres): quedan con el cobro y los ve tu equipo en el panel. Todas aceptan la cabecera Idempotency-Key: con una clave propia de cada operación, una devolución enviada dos veces devuelve la plata una sola vez, y dos devoluciones parciales distintas llevan dos claves distintas. Ver Reintentos.

RutaRequiereDeja el cobro en
POST /v1/payments/{id}/captureauthorizedsucceeded
POST /v1/payments/{id}/cancelauthorizedcancelled
POST /v1/payments/{id}/adjustauthorizedauthorized, con otro monto
POST /v1/payments/{id}/refundsucceededrefunded si devuelves el total. Uno parcial lo deja en succeeded y suma refunded_amount; cuando las partes completan el total, pasa a refunded
POST /v1/payments/{id}/cancel-or-refundauthorized o succeededSegún cuál fuera

Reembolso parcial

curl -X POST "https://api.lane.money/v1/payments/a02e5b19-…/refund" \
  -H "Authorization: Bearer sk_test_…" \
  -H "Idempotency-Key: pedido-4821-devolucion-1" \
  -H "Content-Type: application/json" \
  -d '{ "amount": 2000000, "reason": "returned" }'

Respuesta 200

{
  "object": "payment.operation",
  "operation": "refund",
  "payment": {
    "object": "payment",
    "id": "a02e5b19-…",
    "amount": 8900000,
    "refunded_amount": 2000000,
    "status": "succeeded",
    "…": "…"
  },
  "provider": { "name": "processor" }
}

Una devolución parcial te llega como el aviso payment.partially_refunded, con refunded_amount (esta parte) y, cuando el procesador lo dice, remaining_amount (lo que queda del cobro).

Solo la tarjeta se devuelve. Un cobro por PSE, Nequi, Daviplata o Bre-B no admite refund ni cancel. Ver Medios instantáneos.

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