Transacciones
Crea, lista, captura y anula transacciones de pago a través del motor de orquestación de Tokeflow, con enrutamiento inteligente, cronologías de conmutación por error y creación idempotente.
Una transacción es un único intento de mover dinero para un pedido a través del motor de orquestación de Tokeflow. Describes la intención —importe, moneda, método de pago, país y el origen de la tarjeta— y Tokeflow enruta el cargo entre los proveedores de pago que hayas conectado, aplicando tus reglas de enrutamiento y escalando a un proveedor de conmutación por error cuando uno rechaza o produce un error.
Tokeflow orquesta el cargo; no procesa ni liquida fondos. La autorización, la captura y la liquidación las realizan los proveedores de pago conectados. Tokeflow normaliza su comportamiento detrás de un único objeto de transacción coherente para que tu integración siga siendo la misma sin importar qué proveedor gestione el pago.
Cada transacción registra una cronología de intentos de enrutamiento: qué conector se probó, en qué orden y cómo respondió cada uno. Esa cronología es tu registro de auditoría y tu herramienta de depuración. Consulta La cronología.
Cómo fluye una transacción
Una sola llamada a la API puede distribuirse a varios proveedores entre bastidores. Las formas de la solicitud y la respuesta son estables independientemente de qué proveedor autorice finalmente el cargo.
El objeto de transacción
| Field | Type | Description |
|---|---|---|
id | string | ID de la transacción, con el prefijo tx_. |
organization_id | string | Organization propietaria, con el prefijo org_. |
merchant_id | string | Merchant propietario, con el prefijo mrc_. |
order_id | string | null | Pedido al que pertenece este cargo, con el prefijo ord_. Tokeflow crea automáticamente un pedido para los cargos directos por API. |
subscription_id | string | null | Suscripción creada a partir de este cargo cuando la oferta subyacente es recurrente, con el prefijo sub_. Null en caso contrario. |
external_order_id | string | null | Tu propia referencia de pedido, devuelta como eco para la conciliación. |
customer_id | string | null | Cliente al que se atribuye el cargo, con el prefijo cust_. |
payment_instrument_id | string | null | Instrumento guardado utilizado, con el prefijo pi_. Null para cargos con tarjeta puntuales o asíncronos. |
amount_authorized | integer | Importe autorizado, en unidades menores. |
amount_captured | integer | Importe capturado, en unidades menores. |
currency | string | Código de moneda ISO 4217. |
payment_method | string | Uno de credit_card, debit_card, pix, boleto, wallet. |
charge_type | string | payment o setup_verification. |
country | string | Código de país ISO 3166-1 alpha-2. |
status | string | Estado actual de la transacción. Consulta Ciclo de vida del estado. |
applied_routing_rule_id | string | null | El nodo de la regla de enrutamiento que produjo el intento exitoso. |
mode | string | null | live o test — si el pago se ejecutó con credenciales de proveedor en vivo o de prueba, tomado del conector del intento final. Null cuando no se hizo ningún intento (el cargo se rechazó antes del enrutamiento). |
timeline | array | Lista ordenada de intentos de enrutamiento. Consulta La cronología. |
payment_instructions | object | null | Instrucciones de cara al cliente para métodos asíncronos (PIX, boleto). Null para cargos con tarjeta síncronos. |
metadata | object | null | Pares clave-valor arbitrarios que adjuntaste en la creación. |
created_at | string | Marca de tiempo de creación (ISO 8601 UTC). |
updated_at | string | Marca de tiempo de la última actualización (ISO 8601 UTC). |
La cronología
La timeline es el registro ordenado de cada intento de proveedor que Tokeflow realizó para esta transacción. Es la forma en que la cascada y la conmutación por error se vuelven observables.
| Field | Type | Description |
|---|---|---|
attempt_number | integer | Número de secuencia del intento, empezando en 1. |
is_fallback | boolean | true si este intento se ejecutó únicamente porque un intento anterior falló. |
connector_id | string | El conector utilizado para este intento. |
provider_slug | string | Slug neutral del proveedor detrás del conector. |
status | string | pending, success, failed o error. |
started_at | string | Cuándo comenzó el intento (ISO 8601 UTC). |
finished_at | string | null | Cuándo se resolvió el intento (ISO 8601 UTC), o null si aún está pendiente. |
error_category | string | null | Clase de error de alto nivel cuando el intento no tuvo éxito. |
error_code | string | null | Código de error normalizado cuando el intento no tuvo éxito. |
decline_reason | string | null | Por qué falló el intento, en palabras propias de Tokeflow — el mismo valor sea cual sea el proveedor que respondió. Consulta Motivos de rechazo. Null cuando no se conoce ningún motivo. |
Para una vista más rica, por intento —incluyendo el estado de 3DS, mensajes de error normalizados y comisiones de gateway—, llama a GET /transactions/:id/attempts.
Ciclo de vida del estado
El enum completo de status:
pending, pre_authorized, authorized, failed, canceled, voided, charged_back, refund_pending, capture_pending, refunded, partially_refunded, expired.
Un cargo fallido no es un error HTTP. Cuando un proveedor rechaza, Tokeflow igualmente devuelve 201 Created con status: "failed" y una cronología que explica el motivo. Ramifica siempre en función del campo status; nunca asumas que una respuesta 2xx significa que el dinero fue autorizado.
Cuando el proveedor no da respuesta
Un cargo con tarjeta también puede volver como pending. Eso ocurre cuando se pidió al proveedor que moviera dinero pero no dio un veredicto — un tiempo de espera agotado, una respuesta ilegible o un error de servidor de su lado. El cargo puede haberse realizado o no, así que Tokeflow no lo trata como un rechazo: no hace cascada a un conector de respaldo (eso podría cobrar dos veces al cliente) y no inicia el dunning en una renovación. La transacción permanece en pending mientras Tokeflow establece el resultado con el proveedor, y luego pasa a su estado final, que te llega mediante los webhooks de transacción habituales. Una sesión de checkout pagada con un cargo así se liquida en el mismo momento.
No reintentes un cargo con tarjeta en pending con una nueva clave de idempotencia. Espera el estado final, o léelo con GET /transactions/:id.
Motivos de rechazo
Cada intento fallido lleva un decline_reason: el nombre que Tokeflow da al motivo por el que falló. Los códigos de rechazo propios de cada proveedor se asignan a este único vocabulario, así que insufficient_funds significa lo mismo sea cual sea el conector que respondió. error_category y error_code siguen siendo los campos que gobiernan los reintentos; decline_reason es el que conviene mostrar a tu equipo de soporte, agrupar en reportes o convertir en un mensaje para el cliente.
| Grupo | Motivos |
|---|---|
| Emisor | do_not_honor, generic_decline, call_issuer, try_again_later, issuer_unavailable, invalid_transaction, transaction_not_permitted, do_not_retry |
| Fondos y límites | insufficient_funds, limit_exceeded, max_attempts |
| Datos de la tarjeta | invalid_card_number, invalid_cvv, invalid_expiry, incorrect_pin, invalid_amount, invalid_installments |
| Estado de la tarjeta | card_expired, lost_or_stolen, pickup_card, card_restricted, card_inactive, account_closed, account_updated, authorization_revoked, card_not_supported, currency_not_supported, test_card_used |
| Fraude y riesgo | fraud_suspected, risk_blocked, blocklisted |
| Autenticación | authentication_required, authentication_failed |
| Solicitud | duplicate_transaction, invalid_request, invalid_token |
| Proveedor | processing_error, provider_unavailable, timeout, rate_limited, invalid_credentials |
| Sin asignar | other — el proveedor dio un motivo que todavía no tiene nombre en Tokeflow. |
La lista solo crece: un motivo nunca se renombra ni se elimina, y se añaden motivos nuevos con el tiempo. Guarda el valor como string y trata uno desconocido como other.
El motivo también decide cómo enruta Tokeflow el rechazo, igual para todos los proveedores:
- En un cargo iniciado por el cliente, los rechazos temporales del emisor y de fondos (
do_not_honor,generic_decline,try_again_later,issuer_unavailable,insufficient_funds) se reintentan una vez en el mismo conector y luego hacen cascada a tus conectores de respaldo. Cualquier otro motivo de rechazo detiene el cargo sin cascada — datos de la tarjeta, estado de la tarjeta, fraude y riesgo, y respuestas del emisor comocall_issuerotransaction_not_permittedque otro intento en este momento no cambiaría. El cliente tiene que corregir la tarjeta, contactar a su banco o usar otra. - En una renovación de suscripción, no se reintenta nada dentro de la solicitud. Un motivo que indica que la tarjeta no podrá volver a cobrarse nunca (
lost_or_stolen,pickup_card,card_restricted,account_closed,account_updated,authorization_revoked,card_not_supported,currency_not_supported,test_card_used,do_not_retry,fraud_suspected,blocklisted) cancela la suscripción. Cualquier otro rechazo — incluidas tarjetas caducadas, datos de tarjeta incorrectos yrisk_blocked— la envía a dunning, para que el cliente todavía pueda actualizar la tarjeta.
Tipo de cargo
| Value | Meaning |
|---|---|
payment | Un cargo real por bienes o servicios. Usa amount. |
setup_verification | Una verificación de importe cero o nominal utilizada para validar y almacenar una tarjeta para cargos posteriores, sin cobrar al cliente. |
Orígenes de tarjeta
Cada cargo con tarjeta necesita un origen de tarjeta. Elige la combinación que se ajuste a tu escenario:
| Escenario | Campo a enviar | Notas |
|---|---|---|
| Tarjeta nueva | card_ciphertext_id | La referencia de tarjeta cifrada de un solo uso (tok_…) devuelta por el Bridge SDK. Añade save_payment_instrument: true para guardar también la tarjeta para más adelante. |
| Tarjeta guardada, el cliente reescribe el CVV | payment_instrument_id + card_ciphertext_id | Un instrumento almacenado, con el prefijo pi_, más un ciphertext nuevo de la misma tarjeta. |
| Tarjeta guardada, un clic | payment_instrument_id + credential_on_file: true | Cobra la credencial del proveedor conservada en el registro. Sin datos de tarjeta, sin CVV. Consulta Cobros con credencial almacenada. |
| Checkout | checkout_session_id | Cobra una sesión de checkout completada, con el prefijo cks_. |
| Checkout, tarjeta guardada | checkout_session_id + payment_instrument_id + credential_on_file: true | Paga la sesión con la tarjeta guardada del cliente, sin volver a introducir la tarjeta. Requiere el opt-in saved_card_checkout_enabled del merchant. Consulta Checkout con tarjeta guardada. |
payment_instrument_id por sí solo se rechaza con 400. Una tarjeta guardada se cobra con credential_on_file: true o con un card_ciphertext_id nuevo — uno de los dos debe indicar cómo se presenta la tarjeta.
Nunca envíes datos de tarjeta sin cifrar a este endpoint. Los campos seguros de Tokeflow se ejecutan dentro de iframes aislados de origen cruzado; los datos de la tarjeta se cifran en el navegador y nunca tocan tus servidores. El navegador recibe una referencia de tarjeta cifrada de un solo uso (tok_…), que pasas como card_ciphertext_id. Para los métodos PIX, boleto y wallet, no se requiere ningún origen de tarjeta.
¿Necesitas un tok_… para probar este endpoint? Usa el probador alojado del Bridge SDK en card.tokeflow.com: ejecútalo contra tu merchant con una clave pública, luego copia la referencia de tarjeta cifrada devuelta y envíala aquí como card_ciphertext_id. Consulta Prueba el Bridge SDK sin código.
Cobros con credencial almacenada (one-click)
Dos banderas booleanas convierten un cargo normal en las dos mitades de un flujo en un clic — el patrón detrás de los upsells y downsells posteriores a la compra. La guía paso a paso es Upsells y downsells en un clic; esta sección es la referencia de campos.
save_payment_instrument
Guarda la tarjeta detrás de card_ciphertext_id como un instrumento de pago del customer_id antes de ejecutar el cargo, y luego cobra el ciphertext enviado. Cuando el proveedor aprueba, su credencial reutilizable para la tarjeta se conserva en ese conector, de modo que los cargos credential_on_file posteriores puedan usarla. La respuesta lleva el nuevo payment_instrument_id.
| Regla | Detalle |
|---|---|
| Requiere | card_ciphertext_id emitido con purpose=instrument_enrollment — desde el Bridge SDK con purpose: 'instrument_enrollment' (independiente) o saveCard: true (dentro de una sesión de checkout). customer_id. Un método de pago con tarjeta. |
| Se rechaza con | checkout_session_id (ahí gobierna el save_card de la sesión), payment_instrument_id, credential_on_file. |
Ciphertext one_time | 400 validation_error — el token no puede guardarse. No se cobra nada. |
| Tarjeta existente | Si el cliente ya tiene esta tarjeta en archivo, se reutiliza el instrumento existente. |
credential_on_file
Cobra el payment_instrument_id guardado con la credencial del proveedor conservada en el registro — sin datos de tarjeta, sin CVV. Pensado para cargos con el cliente presente y no programados, como un upsell en un clic; los cargos programados pertenecen a las suscripciones.
| Regla | Detalle |
|---|---|
| Requiere | payment_instrument_id (debe pertenecer al cliente y estar active) y un método de pago con tarjeta. Sin una sesión de checkout, también customer_id. |
| Se rechaza con | card_ciphertext_id, save_payment_instrument, capture: false. |
Con checkout_session_id | Paga la sesión con la tarjeta guardada: la sesión aporta el importe, la moneda, el cliente y las cuotas. Requiere el opt-in saved_card_checkout_enabled del merchant. Consulta Checkout con tarjeta guardada. |
| Requisito previo | El instrumento conserva una credencial obtenida en un cargo con el titular presente o una verificación de tarjeta exitosa en un conector cuyo proveedor admita cargos con credencial almacenada. De lo contrario, 400 validation_error. |
| Enrutamiento | Fijado al conector activo que conserva la credencial utilizable más reciente del instrumento. Las reglas de enrutamiento y la cascada no se aplican; si ese conector no puede aceptar el cargo (moneda, cuotas), la solicitud se rechaza con 422. |
| Captura | Siempre autorización + captura. |
| Pedido | Creado con recurrence: "unscheduled". |
| Metadatos | stored_credential_usage: "customer_initiated" se fusiona en metadata. |
| Autenticación | Un cargo con credencial almacenada no puede ejecutar un desafío 3-D Secure. Un emisor que lo exija rechaza con error_code: "AUTHENTICATION_REQUIRED" — vuelve a un ciphertext nuevo. |
Checkout con tarjeta guardada
Un cliente que regresa puede pagar una sesión de checkout con una tarjeta que guardó antes, sin volver a escribirla. Tu servidor cobra la sesión con el instrumento guardado:
{
"checkout_session_id": "cks_a1b2c3d4e5",
"payment_instrument_id": "pi_123",
"credential_on_file": true,
"payment_method": "credit_card",
"charge_type": "payment",
"country": "BR"
}| Regla | Detalle |
|---|---|
| Opt-in | El merchant debe tener saved_card_checkout_enabled activado. Está desactivado por defecto. Activarlo declara que tú autenticas al cliente antes de identificarlo en la sesión — en una sesión, Tokeflow nunca ve al titular de la tarjeta, así que tu servidor responde por él. |
| Qué cubre el opt-in | Cualquier uso de un payment_instrument_id guardado en una sesión de checkout sin un card_ciphertext_id nuevo: el cargo credential_on_file y una prueba de importe cero iniciada solo con la tarjeta guardada. Un cargo con un ciphertext nuevo (tarjeta reescrita) no necesita opt-in. |
| Importe y cliente | Se toman de la sesión; cualquier amount, currency o customer_id que envíes no se usa. |
| Conector | Fijado al conector que conserva la credencial almacenada de la tarjeta, como en cualquier cargo credential_on_file. En una oferta recurrente, la suscripción se inicia en ese conector. |
| Opt-in desactivado | 400 — recopila la tarjeta de nuevo y cobra la sesión con un card_ciphertext_id nuevo. Si el mensaje dice que la función está desactivada por una configuración de Tokeflow, cambiar saved_card_checkout_enabled no la levantará; contacta al equipo de Tokeflow. |
Para decidir si ofrecer "pagar con esta tarjeta guardada", lee el contexto de checkout en el navegador: savedCardCheckoutEnabled y el indicador reusable de cada instrumento guardado te dicen qué tarjetas pueden cobrarse en esta sesión. Son indicaciones; el cargo en sí sigue siendo la referencia definitiva y aún puede rechazarse.
Endpoints
POST/api/v1/transactions
Auth: clave de Organization (con merchant_id) o clave de Merchant. Scope: transactions:write.
Crea y envía una transacción de pago. Tokeflow evalúa tus reglas de enrutamiento, intenta el cargo (escalando a un proveedor de conmutación por error en caso de fallo) y crea automáticamente un pedido para el cargo.
Campos de la solicitud
| Field | Type | Required | Description |
|---|---|---|---|
payment_method | string | Sí | Uno de credit_card, debit_card, pix, boleto, wallet. |
charge_type | string | Sí | payment o setup_verification. |
country | string | Sí | Código de país ISO 3166-1 alpha-2. Se usa para el enrutamiento y la selección del adquirente. |
amount | integer | Condicional | Importe en unidades menores (p. ej. R$150,00 = 15000). Usa 0 para setup_verification. Obligatorio a menos que se proporcione checkout_session_id. |
currency | string | Condicional | Código de moneda ISO 4217. Obligatorio a menos que se proporcione checkout_session_id. |
merchant_id | string | Condicional | Merchant de destino. Obligatorio con una clave de Organization; se infiere a partir de una clave de Merchant. |
card_ciphertext_id | string | Condicional | La referencia de tarjeta cifrada de un solo uso (tok_…) devuelta por el Bridge SDK cuando tokenizas una tarjeta nueva. Obligatorio para una tarjeta nueva y para una tarjeta guardada cobrada con CVV reescrito. |
payment_instrument_id | string | Condicional | Instrumento guardado que se va a cobrar (pi_…). Envíalo con un card_ciphertext_id nuevo o con credential_on_file: true — nunca solo. |
credential_on_file | boolean | No | true cobra el payment_instrument_id con la credencial del proveedor conservada en el registro — sin datos de tarjeta, sin CVV. Solo cargos con el cliente presente y no programados. Requiere customer_id salvo que se envíe un checkout_session_id; con una sesión necesita el opt-in saved_card_checkout_enabled del merchant. No se combina con card_ciphertext_id, save_payment_instrument ni capture: false. Predeterminado false. Consulta Cobros con credencial almacenada. |
save_payment_instrument | boolean | No | true guarda la tarjeta detrás de card_ciphertext_id para el customer_id antes de cobrar, de modo que los cargos credential_on_file posteriores puedan reutilizarla. El ciphertext debe haberse emitido con purpose=instrument_enrollment. No se usa con checkout_session_id. Predeterminado false. |
checkout_session_id | string | Condicional | Sesión de checkout completada que se va a cobrar. Cuando se proporciona, amount y currency se derivan de la sesión y se ignoran los valores enviados. |
wallet_type | string | Condicional | Obligatorio cuando payment_method es wallet. |
customer_id | string | Condicional | Cliente al que atribuir el cargo. Obligatorio con save_payment_instrument, y con credential_on_file fuera de una sesión de checkout; recomendado en los demás casos para la resolución de credenciales guardadas. |
payer_ip | string | No | La dirección IP del pagador (IPv4 o IPv6) — desde donde compra el cliente, nunca la de tu servidor. Algunos proveedores la exigen en cargos con tarjeta. Cuando se omite y el cargo pertenece a una sesión de checkout, Tokeflow usa la IP con la que el pagador abrió la sesión del Bridge SDK. |
external_order_id | string | No | Tu referencia de pedido, almacenada para la conciliación. |
capture | boolean | No | true (predeterminado) = autorización + captura en un solo paso. false = solo preautorizar; capturar después. |
risk_score | integer | No | Puntuación de fraude previa a la autorización, de 0 a 100. Se almacena en la transacción. |
installments | object | No | Detalles del plan de cuotas, donde esté disponible. |
payer_token_id | string | No | Token de pagador (ptk_…) de pix.tokenize() o boleto.tokenize() del Bridge SDK. Aporta el pagador de un cargo PIX o boleto, de modo que tu servidor nunca maneja el CPF/CNPJ ni la dirección. De un solo uso, vinculado a su método de pago y a su sesión de checkout. Consulta Pagadores de PIX y boleto. |
boleto | object | No | Opciones de boleto, que solo se leen cuando payment_method es boleto. expires_in_days: días hasta el vencimiento del boleto, 1–30, predeterminado 3. Una fecha de vencimiento que cae en fin de semana pasa al siguiente día hábil. |
idempotency_key | string | No | Evita cargos duplicados. También puede enviarse como el encabezado Idempotency-Key. |
metadata | object | No | Pares clave-valor arbitrarios almacenados en la transacción. |
Envía siempre una clave de idempotencia en la creación. Pasa un valor único por intento de cargo como el encabezado Idempotency-Key (o idempotency_key en el cuerpo). Si un fallo de red te obliga a reintentar, reproducir la misma clave devuelve la transacción original (HTTP 200) en lugar de cobrar al cliente dos veces. Consulta Idempotencia y límites de tasa.
Códigos de respuesta
| Code | When |
|---|---|
201 Created | Primer envío de esta transacción. Inspecciona status para ver el resultado. |
200 OK | Reproducción idempotente: la misma Idempotency-Key se vio antes; se devuelve la transacción original. |
400 Bad Request | Parámetros inválidos o campos obligatorios faltantes. |
401 Unauthorized | Clave de API faltante o inválida. |
403 Forbidden | Autenticado pero sin el scope requerido. |
Solicitud de ejemplo
curl -X POST https://api.tokeflow.com/api/v1/transactions \
-H "Authorization: Bearer sk_live_mer_…" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: order_12345_attempt_1" \
-d '{
"payment_method": "credit_card",
"charge_type": "payment",
"country": "BR",
"amount": 15000,
"currency": "BRL",
"customer_id": "cust_123",
"external_order_id": "order_888",
"card_ciphertext_id": "tok_8f3c2a1b9d4e",
"capture": true,
"metadata": { "campaign": "black_friday" }
}'Respuesta de ejemplo — 201 Created
{
"success": true,
"data": {
"id": "tx_777",
"organization_id": "org_123",
"merchant_id": "mrc_123",
"order_id": "ord_001",
"subscription_id": null,
"external_order_id": "order_888",
"customer_id": "cust_123",
"payment_instrument_id": null,
"amount_authorized": 15000,
"amount_captured": 15000,
"currency": "BRL",
"payment_method": "credit_card",
"charge_type": "payment",
"country": "BR",
"status": "authorized",
"applied_routing_rule_id": "node_2",
"mode": "live",
"timeline": [
{
"attempt_number": 1,
"is_fallback": false,
"connector_id": "conn_a1b2c3",
"provider_slug": "acquirer_a",
"status": "failed",
"started_at": "2026-01-15T12:30:00.000Z",
"finished_at": "2026-01-15T12:30:02.000Z",
"error_category": "SOFT_DECLINE",
"error_code": "INSUFFICIENT_FUNDS",
"decline_reason": "insufficient_funds"
},
{
"attempt_number": 2,
"is_fallback": true,
"connector_id": "conn_d4e5f6",
"provider_slug": "acquirer_b",
"status": "success",
"started_at": "2026-01-15T12:30:02.000Z",
"finished_at": "2026-01-15T12:30:04.000Z",
"error_category": null,
"error_code": null,
"decline_reason": null
}
],
"payment_instructions": null,
"metadata": { "campaign": "black_friday" },
"created_at": "2026-01-15T12:30:00.000Z",
"updated_at": "2026-01-15T12:30:04.000Z"
},
"request_id": "req_8f3c",
"timestamp": "2026-01-15T12:30:04.000Z"
}El ejemplo anterior muestra una cascada: el conector primario rechazó y la conmutación por error de Tokeflow autorizó el cargo, todo en una sola llamada a la API.
Un rechazo del proveedor devuelve 201 con status: "failed" y una cronología explicativa, no un error HTTP. Ramifica en función de status. Consulta La cronología para conocer los campos que explican un fallo.
Métodos asíncronos (PIX y boleto)
Para PIX y boleto, la respuesta lleva payment_instructions en lugar de una autorización inmediata. La transacción permanece en pending hasta que el cliente paga; el estado final llega a través de un webhook. Devuelve payment_instructions al navegador para que el cliente pueda pagar.
| Campo | Método | Descripción |
|---|---|---|
type | ambos | pix o boleto. |
qr_code_text | PIX | El código para copiar y pegar ("copia e cola"). |
qr_code_url | PIX | Imagen del código QR alojada por el proveedor. |
digitable_line | Boleto | La linha digitável — los 47 dígitos que el pagador escribe en la app de su banco. |
barcode | Boleto | El contenido del código de barras de 44 dígitos. |
boleto_url | Boleto | Boleto alojado por el proveedor (PDF o página de instrucciones). |
due_date | Boleto | Fecha de vencimiento en hora de Brasilia, YYYY-MM-DD, tras cualquier traslado por fin de semana. |
expires_at | ambos | Cuándo ya no se puede realizar el pago (ISO 8601). |
{
"success": true,
"data": {
"id": "tx_778",
"status": "pending",
"payment_method": "pix",
"amount_authorized": 0,
"amount_captured": 0,
"currency": "BRL",
"payment_instructions": {
"type": "pix",
"qr_code_text": "00020126580014BR.GOV.BCB.PIX…",
"qr_code_url": "https://example.com/qrcode/image.png",
"expires_at": "2026-01-15T13:00:00.000Z"
},
"timeline": [
{
"attempt_number": 1,
"is_fallback": false,
"connector_id": "conn_a1b2c3",
"provider_slug": "acquirer_a",
"status": "pending",
"started_at": "2026-01-15T12:30:00.000Z",
"finished_at": null,
"error_category": null,
"error_code": null,
"decline_reason": null
}
],
"created_at": "2026-01-15T12:30:00.000Z",
"updated_at": "2026-01-15T12:30:00.000Z"
},
"request_id": "req_9a2d",
"timestamp": "2026-01-15T12:30:00.000Z"
}Un cargo con boleto devuelve el boleto en su lugar:
"payment_instructions": {
"type": "boleto",
"digitable_line": "23793381286000782713695000063305975520000370000",
"barcode": "23799755200003700003381260007827139500006330",
"boleto_url": "https://example.com/boleto/tx_779.pdf",
"due_date": "2026-10-29",
"expires_at": "2026-10-30T02:59:59.000Z"
}Pagadores de PIX y boleto
PIX y boleto necesitan los datos del pagador — nombre, correo electrónico y CPF/CNPJ, además de una dirección de facturación completa para un boleto. La forma recomendada de recogerlos es un token de pagador: el Bridge SDK registra al pagador desde el navegador y devuelve un ptk_…, y tu servidor lo cobra con payer_token_id:
{
"payment_method": "boleto",
"charge_type": "payment",
"country": "BR",
"amount": 10000,
"currency": "BRL",
"external_order_id": "order_123",
"payer_token_id": "ptk_abc123",
"boleto": { "expires_in_days": 3 }
}| Regla | Detalle |
|---|---|
| Un solo uso | Un token lo consume el cargo que lo usa — incluso uno fallido — y caduca 30 minutos después de su creación. Envía una Idempotency-Key para que una solicitud reintentada reproduzca el cargo en lugar de necesitar un token nuevo. |
| Vinculado | El token solo es válido para el payment_method para el que se recogió y, cuando se recogió dentro de una sesión de checkout, solo con ese checkout_session_id. |
| Rechazado | Un token desconocido, ya usado, caducado, recogido para el otro método o para otra sesión se rechaza con 400 y code INVALID_PAYER_TOKEN. No se cobra nada. |
| Cliente | El correo electrónico del token por sí solo nunca vincula el cargo a un cliente existente, ya que cualquiera puede escribir cualquier correo en un navegador. Para atribuir el cargo, envía customer_id, o envía el mismo correo desde tu servidor. |
| Precedencia | Los datos del pagador del token prevalecen sobre los datos del pagador que envíe tu servidor. |
Sin un token de pagador, el pagador sale del cliente que indiques con customer_id y de sus datos almacenados. Un boleto cuyo pagador carece de un campo obligatorio se rechaza antes de llegar a un proveedor.
GET/api/v1/transactions
Auth: clave de Organization (con merchant_id) o clave de Merchant. Scope: transactions:read.
Devuelve una lista paginada de transacciones, las más recientes primero.
Parámetros de consulta
| Field | Type | Required | Description |
|---|---|---|---|
status | string | No | Filtrar por estado. Repetible o separado por comas para varios (p. ej. status=refunded,partially_refunded). |
merchant_id | string | Condicional | Obligatorio con una clave de Organization; se infiere a partir de una clave de Merchant. |
customer_reference | string | No | Filtrar por referencia del cliente. |
order_id | string | No | Filtrar por pedido. |
payment_method | string | No | Filtrar por método de pago. |
currency | string | No | Filtrar por código de moneda ISO 4217. |
date_from | string | No | Creado en o después de esta marca de tiempo (ISO 8601). |
date_to | string | No | Creado en o antes de esta marca de tiempo (ISO 8601). |
page | integer | No | Número de página (predeterminado 1, mín. 1). |
limit | integer | No | Elementos por página (predeterminado 20, máx. 100). |
Solicitud de ejemplo
curl -G https://api.tokeflow.com/api/v1/transactions \
-H "Authorization: Bearer sk_live_mer_…" \
--data-urlencode "status=authorized,refunded" \
--data-urlencode "currency=BRL" \
--data-urlencode "date_from=2026-01-01T00:00:00Z" \
--data-urlencode "page=1" \
--data-urlencode "limit=20"Respuesta de ejemplo — 200 OK
{
"success": true,
"data": [
{
"id": "tx_777",
"organization_id": "org_123",
"merchant_id": "mrc_123",
"order_id": "ord_001",
"external_order_id": "order_888",
"customer_id": "cust_123",
"amount_authorized": 15000,
"amount_captured": 15000,
"currency": "BRL",
"payment_method": "credit_card",
"charge_type": "payment",
"country": "BR",
"status": "authorized",
"applied_routing_rule_id": "node_2",
"mode": "live",
"timeline": [
{
"attempt_number": 1,
"is_fallback": false,
"connector_id": "conn_a1b2c3",
"provider_slug": "acquirer_a",
"status": "success",
"started_at": "2026-01-15T12:30:00.000Z",
"finished_at": "2026-01-15T12:30:02.000Z",
"error_category": null,
"error_code": null,
"decline_reason": null
}
],
"payment_instructions": null,
"metadata": {},
"created_at": "2026-01-15T12:30:00.000Z",
"updated_at": "2026-01-15T12:30:02.000Z"
}
],
"meta": {
"pagination": {
"page": 1,
"limit": 20,
"total": 42,
"total_pages": 3,
"has_next": true,
"has_prev": false
}
},
"request_id": "req_3b7e",
"timestamp": "2026-01-15T12:30:05.000Z"
}GET/api/v1/transactions/:id
Auth: clave de Organization (cualquier transacción de la organización) o clave de Merchant (sus propias transacciones). Scope: transactions:read.
Recupera una única transacción, incluida su cronología de enrutamiento completa. Devuelve el objeto de transacción.
Solicitud de ejemplo
curl https://api.tokeflow.com/api/v1/transactions/tx_777 \
-H "Authorization: Bearer sk_live_mer_…"Respuesta de ejemplo — 200 OK
{
"success": true,
"data": {
"id": "tx_777",
"merchant_id": "mrc_123",
"amount_authorized": 15000,
"amount_captured": 15000,
"currency": "BRL",
"payment_method": "credit_card",
"charge_type": "payment",
"country": "BR",
"status": "authorized",
"applied_routing_rule_id": "node_2",
"mode": "live",
"timeline": [
{
"attempt_number": 1,
"is_fallback": false,
"connector_id": "conn_a1b2c3",
"provider_slug": "acquirer_a",
"status": "success",
"started_at": "2026-01-15T12:30:00.000Z",
"finished_at": "2026-01-15T12:30:02.000Z",
"error_category": null,
"error_code": null,
"decline_reason": null
}
],
"payment_instructions": null,
"metadata": {},
"created_at": "2026-01-15T12:30:00.000Z",
"updated_at": "2026-01-15T12:30:02.000Z"
},
"request_id": "req_5c1a",
"timestamp": "2026-01-15T12:30:06.000Z"
}Se devuelve un 404 (not_found_error) si la transacción no existe o no pertenece al merchant autenticado.
GET/api/v1/transactions/:id/attempts
Auth: clave de Organization (cualquier transacción de la organización) o clave de Merchant (sus propias transacciones). Scope: transactions:read.
Devuelve cada intento individual de proveedor para una transacción, con más detalle que la timeline en línea, incluyendo el estado de 3DS, mensajes de error normalizados y comisiones de gateway. Úsalo para depurar rechazos y analizar el comportamiento del enrutamiento.
Campos del intento
| Field | Type | Description |
|---|---|---|
id | string | ID del intento. |
payment_transaction_id | string | Transacción principal, con el prefijo tx_. |
merchant_connector_id | string | Conector utilizado para este intento. |
provider_slug | string | Slug neutral del proveedor. |
attempt_number | integer | Número de secuencia, empezando en 1. |
is_fallback | boolean | Si el intento se ejecutó como conmutación por error. |
status | string | pending, success, failed o error. |
three_ds_status | string | null | Resultado de la autenticación 3DS, cuando corresponda. |
error_category | string | null | Clase de error de alto nivel, en caso de fallo. |
error_code | string | null | Código de error normalizado, en caso de fallo. |
decline_reason | string | null | El motivo del fallo según Tokeflow, el mismo valor sea cual sea el proveedor que respondió. Consulta Motivos de rechazo. |
error_message | string | null | Error legible por humanos, en caso de fallo. |
psp_transaction_id | string | null | Referencia de transacción del lado del proveedor. |
gateway_fee | integer | null | Comisión de procesamiento tal como la informa el proveedor, en unidades menores. Null cuando el proveedor no informó ninguna; algunos proveedores la informan solo más tarde, y se completa cuando llega. |
started_at | string | Cuándo comenzó el intento (ISO 8601 UTC). |
finished_at | string | null | Cuándo se resolvió el intento (ISO 8601 UTC). |
Solicitud de ejemplo
curl https://api.tokeflow.com/api/v1/transactions/tx_777/attempts \
-H "Authorization: Bearer sk_live_mer_…"Respuesta de ejemplo — 200 OK
{
"success": true,
"data": [
{
"id": "att_1",
"payment_transaction_id": "tx_777",
"merchant_connector_id": "conn_a1b2c3",
"provider_slug": "acquirer_a",
"attempt_number": 1,
"is_fallback": false,
"status": "failed",
"three_ds_status": null,
"error_category": "SOFT_DECLINE",
"error_code": "INSUFFICIENT_FUNDS",
"decline_reason": "insufficient_funds",
"error_message": "Issuer declined: insufficient funds",
"psp_transaction_id": "psp_tx_123",
"gateway_fee": null,
"started_at": "2026-01-15T12:30:00.000Z",
"finished_at": "2026-01-15T12:30:02.000Z"
},
{
"id": "att_2",
"payment_transaction_id": "tx_777",
"merchant_connector_id": "conn_d4e5f6",
"provider_slug": "acquirer_b",
"attempt_number": 2,
"is_fallback": true,
"status": "success",
"three_ds_status": "authenticated",
"error_category": null,
"error_code": null,
"decline_reason": null,
"error_message": null,
"psp_transaction_id": "psp_tx_456",
"gateway_fee": 45,
"started_at": "2026-01-15T12:30:02.000Z",
"finished_at": "2026-01-15T12:30:04.000Z"
}
],
"request_id": "req_7d2f",
"timestamp": "2026-01-15T12:30:07.000Z"
}POST/api/v1/transactions/:id/capture
Auth: clave de Organization (cualquier transacción de la organización) o clave de Merchant (sus propias transacciones). Scope: transactions:write.
Captura una transacción que fue preautorizada con capture: false. La transacción debe estar en el estado capture_pending; tras una captura exitosa pasa a authorized.
Campos de la solicitud
| Field | Type | Required | Description |
|---|---|---|---|
amount | integer | No | Importe a capturar, en unidades menores. Omítelo para capturar el importe autorizado completo. Para una captura parcial, debe ser ≤ amount_authorized. |
La mayoría de los proveedores permiten solo una captura por autorización. En una captura parcial, el remanente no capturado se libera automáticamente.
La captura y la anulación sobre la misma autorización nunca ganan ambas. Si una anulación (tuya, o una que informe el proveedor) liquida la transacción mientras una captura está en curso, o una captura por un importe distinto llega primero, la llamada que pierde responde 409 (conflict_error) — puede que el proveedor ya haya actuado, así que vuelve a leer la transacción con GET /transactions/:id en lugar de reintentar. Una captura que encuentra la misma captura ya registrada devuelve esa transacción con 200.
Solicitud de ejemplo — captura completa
curl -X POST https://api.tokeflow.com/api/v1/transactions/tx_777/capture \
-H "Authorization: Bearer sk_live_mer_…" \
-H "Content-Type: application/json" \
-d '{}'Solicitud de ejemplo — captura parcial
curl -X POST https://api.tokeflow.com/api/v1/transactions/tx_777/capture \
-H "Authorization: Bearer sk_live_mer_…" \
-H "Content-Type: application/json" \
-d '{ "amount": 10000 }'Respuesta de ejemplo — 200 OK
{
"success": true,
"data": {
"id": "tx_777",
"merchant_id": "mrc_123",
"amount_authorized": 15000,
"amount_captured": 15000,
"currency": "BRL",
"payment_method": "credit_card",
"charge_type": "payment",
"country": "BR",
"status": "authorized",
"applied_routing_rule_id": "node_2",
"mode": "live",
"timeline": [
{
"attempt_number": 1,
"is_fallback": false,
"connector_id": "conn_a1b2c3",
"provider_slug": "acquirer_a",
"status": "success",
"started_at": "2026-01-15T12:30:00.000Z",
"finished_at": "2026-01-15T12:30:02.000Z",
"error_category": null,
"error_code": null,
"decline_reason": null
}
],
"payment_instructions": null,
"metadata": {},
"created_at": "2026-01-15T12:30:00.000Z",
"updated_at": "2026-01-15T12:35:00.000Z"
},
"request_id": "req_a4e9",
"timestamp": "2026-01-15T12:35:00.000Z"
}Se devuelve un 400 (validation_error) si la transacción no está en el estado capture_pending o el importe supera el importe autorizado.
POST/api/v1/transactions/:id/void
Auth: clave de Organization (cualquier transacción de la organización) o clave de Merchant (sus propias transacciones). Scope: transactions:write.
Anula una autorización antes de que sea capturada, liberando los fondos retenidos. La transacción debe estar en el estado capture_pending o authorized; tras anularla pasa a voided.
Solicitud de ejemplo
curl -X POST https://api.tokeflow.com/api/v1/transactions/tx_777/void \
-H "Authorization: Bearer sk_live_mer_…"Respuesta de ejemplo — 200 OK
{
"success": true,
"data": {
"id": "tx_777",
"status": "voided",
"updated_at": "2026-01-15T12:36:00.000Z"
},
"request_id": "req_b8c0",
"timestamp": "2026-01-15T12:36:00.000Z"
}Se devuelve un 400 (validation_error) si la transacción no está en un estado anulable. Una anulación que pierde frente a una captura ya registrada responde 409 (conflict_error); una anulación que encuentra la retención ya liberada por el proveedor tiene éxito.
Para revertir fondos después de la captura, emite un reembolso en lugar de una anulación. Consulta Reembolsos.
Errores
Todos los errores usan el sobre estándar. Los casos más comunes para este recurso:
| HTTP | type | Typical cause |
|---|---|---|
400 | validation_error | Campo obligatorio faltante, una combinación inválida de campos de origen de tarjeta (payment_instrument_id solo, credential_on_file con un ciphertext, un ciphertext one_time con save_payment_instrument, un instrumento aún sin credencial almacenada), un payer_token_id inutilizable (INVALID_PAYER_TOKEN), o captura/anulación en el estado equivocado. |
401 | authentication_error | Clave de API faltante o inválida. |
403 | authorization_error | La clave carece del scope requerido. |
404 | not_found_error | Transacción no encontrada o no perteneciente al merchant. |
409 | conflict_error | Una captura y una anulación compitieron sobre la misma autorización y esta llamada perdió. Vuelve a leer la transacción; no reintentes a ciegas. |
422 | business_rule_error | Ningún conector elegible para el cargo — por ejemplo, la moneda, la marca de tarjeta o el plan de cuotas no es compatible con el conector seleccionado por el enrutamiento o fijado. |
429 | rate_limit_error | Límite de tasa superado: aplica retroceso exponencial. |
Consulta Errores para conocer el sobre completo y el catálogo de tipos.
Relacionado
- Upsells y downsells en un clic — la guía completa de
save_payment_instrumentycredential_on_file. - Idempotencia y límites de tasa — reintentos seguros y limitación.
- Reembolsos — revertir fondos capturados.
- Autenticación — aprovisionar claves y scopes.
- Cómo funciona Tokeflow — enrutamiento, cascada y conmutación por error.