Transactions

Create, list, capture, and void payment transactions through Tokeflow's orchestration engine — with smart routing, fallback timelines, and idempotent creation.

A transaction is a single attempt to move money for an order through Tokeflow's orchestration engine. You describe the intent — amount, currency, payment method, country, and the card source — and Tokeflow routes the charge across the payment providers you have connected, applying your routing rules and cascading to a fallback provider when one declines or errors.

Tokeflow orchestrates the charge; it does not process or settle funds. Authorization, capture, and settlement are performed by the connected payment providers. Tokeflow normalizes their behavior behind one consistent transaction object so your integration stays the same no matter which provider handles the payment.

Every transaction records a timeline of routing attempts — which connector was tried, in what order, and how each responded. That timeline is your audit trail and your debugging tool. See The timeline.

How a transaction flows

A single API call can fan out to several providers behind the scenes. The request and response shapes are stable regardless of which provider ultimately authorizes the charge.

The transaction object

FieldTypeDescription
idstringTransaction ID, prefixed tx_.
organization_idstringOwning organization, prefixed org_.
merchant_idstringOwning merchant, prefixed mrc_.
order_idstring | nullOrder this charge belongs to, prefixed ord_. Tokeflow auto-creates an order for direct API charges.
subscription_idstring | nullSubscription created from this charge when the underlying offer is recurring, prefixed sub_. Null otherwise.
external_order_idstring | nullYour own order reference, echoed back for reconciliation.
customer_idstring | nullCustomer the charge is attributed to, prefixed cust_.
payment_instrument_idstring | nullSaved instrument used, prefixed pi_. Null for one-off card or async charges.
amount_authorizedintegerAmount authorized, in minor units.
amount_capturedintegerAmount captured, in minor units.
currencystringISO 4217 currency code.
payment_methodstringOne of credit_card, debit_card, pix, boleto, wallet.
charge_typestringpayment or setup_verification.
countrystringISO 3166-1 alpha-2 country code.
statusstringCurrent transaction status. See Status lifecycle.
applied_routing_rule_idstring | nullThe routing rule node that produced the successful attempt.
timelinearrayOrdered list of routing attempts. See The timeline.
payment_instructionsobject | nullCustomer-facing instructions for async methods (PIX, boleto). Null for synchronous card charges.
metadataobject | nullArbitrary key-value pairs you attached at creation.
created_atstringCreation timestamp (ISO 8601 UTC).
updated_atstringLast update timestamp (ISO 8601 UTC).

The timeline

The timeline is the ordered record of every provider attempt Tokeflow made for this transaction. It is how cascade and fallback become observable.

FieldTypeDescription
attempt_numberinteger1-based sequence number of the attempt.
is_fallbackbooleantrue if this attempt ran only because a previous attempt failed.
connector_idstringThe connector used for this attempt.
provider_slugstringNeutral slug for the provider behind the connector.
statusstringpending, success, failed, or error.
started_atstringWhen the attempt began (ISO 8601 UTC).
finished_atstring | nullWhen the attempt resolved (ISO 8601 UTC), or null if still pending.
error_categorystring | nullHigh-level error class when the attempt did not succeed.
error_codestring | nullNormalized error code when the attempt did not succeed.

For a richer, per-attempt view — including 3DS status, normalized error messages, and gateway fees — call GET /transactions/:id/attempts.

Status lifecycle

The full status enum:

pending, pre_authorized, authorized, failed, canceled, voided, charged_back, refund_pending, capture_pending, refunded, partially_refunded, expired.

A failed charge is not an HTTP error. When a provider declines, Tokeflow still returns 201 Created with status: "failed" and a timeline explaining why. Always branch on the status field — never assume a 2xx response means the money was authorized.

Charge type

ValueMeaning
paymentA real charge for goods or services. Uses amount.
setup_verificationA zero-or-nominal-amount verification used to validate and store a card for later charges, without billing the customer.

Card sources

Every card charge needs exactly one card source. Pick the one that matches your scenario:

ScenarioField to sendNotes
New cardcard_ciphertext_idThe single-use encrypted card reference (tok_…) returned by the Bridge SDK.
Saved cardpayment_instrument_idA stored instrument, prefixed pi_.
Checkoutcheckout_session_idCharge a completed checkout session, prefixed cks_.

Never send raw card data to this endpoint. Tokeflow's secure fields run inside isolated, cross-origin iframes; card data is encrypted in the browser and never touches your servers. The browser receives a single-use encrypted card reference (tok_…), which you pass as card_ciphertext_id. For PIX, boleto, and wallet methods, no card source is required.

Need a tok_… to test this endpoint? Use the hosted Bridge SDK tester at card.tokeflow.com: run it against your merchant with a public key, then copy the returned encrypted card reference and send it here as card_ciphertext_id. See Test the Bridge SDK without code.


Endpoints

POST/api/v1/transactions

OrgMerchant

Auth: Organization key (with merchant_id) or Merchant key. Scope: transactions:write.

Creates and submits a payment transaction. Tokeflow evaluates your routing rules, attempts the charge (cascading to a fallback provider on failure), and auto-creates an order for the charge.

Request fields

FieldTypeRequiredDescription
payment_methodstringYesOne of credit_card, debit_card, pix, boleto, wallet.
charge_typestringYespayment or setup_verification.
countrystringYesISO 3166-1 alpha-2 country code. Used for routing and acquirer selection.
amountintegerConditionalAmount in minor units (e.g. R$150.00 = 15000). Use 0 for setup_verification. Required unless checkout_session_id is provided.
currencystringConditionalISO 4217 currency code. Required unless checkout_session_id is provided.
merchant_idstringConditionalTarget merchant. Required with an Organization key; inferred from a Merchant key.
card_ciphertext_idstringConditionalThe single-use encrypted card reference (tok_…) returned by the Bridge SDK when you tokenize a new card. Required for a new card unless payment_instrument_id is sent.
payment_instrument_idstringConditionalSaved instrument to charge. Required for a saved card unless card_ciphertext_id is sent.
checkout_session_idstringConditionalCompleted checkout session to charge. When provided, amount and currency are derived from the session and any values sent are ignored.
wallet_typestringConditionalRequired when payment_method is wallet.
customer_idstringNoCustomer to attribute the charge to. Recommended for saved-credential resolution.
external_order_idstringNoYour order reference, stored for reconciliation.
capturebooleanNotrue (default) = auth + capture in one step. false = pre-authorize only; capture later.
risk_scoreintegerNoPre-auth fraud score from 0 to 100. Stored on the transaction.
installmentsobjectNoInstallment plan details, where supported.
idempotency_keystringNoPrevents duplicate charges. Can also be sent as the Idempotency-Key header.
metadataobjectNoArbitrary key-value pairs stored on the transaction.

Always send an idempotency key on creation. Pass a unique value per charge attempt as the Idempotency-Key header (or idempotency_key in the body). If a network hiccup makes you retry, replaying the same key returns the original transaction (HTTP 200) instead of charging the customer twice. See Idempotency and rate limits.

Response codes

CodeWhen
201 CreatedFirst submission of this transaction. Inspect status for the result.
200 OKIdempotent replay — the same Idempotency-Key was seen before; the original transaction is returned.
400 Bad RequestInvalid parameters or missing required fields.
401 UnauthorizedMissing or invalid API key.
403 ForbiddenAuthenticated but missing the required scope.

Example request

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" }
  }'

Example response201 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",
    "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"
      },
      {
        "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
      }
    ],
    "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"
}

The example above shows a cascade: the primary connector declined, and Tokeflow's fallback authorized the charge — all in one API call.

A provider decline returns 201 with status: "failed" and an explanatory timeline, not an HTTP error. Branch on status. See The timeline for the fields that explain a failure.

Async methods (PIX and boleto)

For PIX and boleto, the response carries payment_instructions instead of an immediate authorization. The transaction stays pending until the customer pays; the final status arrives via webhook.

{
  "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
      }
    ],
    "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"
}

GET/api/v1/transactions

OrgMerchant

Auth: Organization key (with merchant_id) or Merchant key. Scope: transactions:read.

Returns a paginated list of transactions, newest first.

Query parameters

FieldTypeRequiredDescription
statusstringNoFilter by status. Repeatable or comma-separated for multiple (e.g. status=refunded,partially_refunded).
merchant_idstringConditionalRequired with an Organization key; inferred from a Merchant key.
customer_referencestringNoFilter by customer reference.
order_idstringNoFilter by order.
payment_methodstringNoFilter by payment method.
currencystringNoFilter by ISO 4217 currency code.
date_fromstringNoCreated on or after this timestamp (ISO 8601).
date_tostringNoCreated on or before this timestamp (ISO 8601).
pageintegerNoPage number (default 1, min 1).
limitintegerNoItems per page (default 20, max 100).

Example request

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"

Example response200 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",
      "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
        }
      ],
      "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

OrgMerchant

Auth: Organization key (any transaction in the org) or Merchant key (its own transactions). Scope: transactions:read.

Retrieves a single transaction, including its full routing timeline. Returns the transaction object.

Example request

curl https://api.tokeflow.com/api/v1/transactions/tx_777 \
  -H "Authorization: Bearer sk_live_mer_…"

Example response200 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",
    "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
      }
    ],
    "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"
}

A 404 (not_found_error) is returned if the transaction does not exist or does not belong to the authenticated merchant.


GET/api/v1/transactions/:id/attempts

OrgMerchant

Auth: Organization key (any transaction in the org) or Merchant key (its own transactions). Scope: transactions:read.

Returns every individual provider attempt for a transaction, with more detail than the inline timeline — including 3DS status, normalized error messages, and gateway fees. Use it to debug declines and analyze routing behavior.

Attempt fields

FieldTypeDescription
idstringAttempt ID.
payment_transaction_idstringParent transaction, prefixed tx_.
merchant_connector_idstringConnector used for this attempt.
provider_slugstringNeutral provider slug.
attempt_numberinteger1-based sequence number.
is_fallbackbooleanWhether the attempt ran as a fallback.
statusstringpending, success, failed, or error.
three_ds_statusstring | null3DS authentication outcome, when applicable.
error_categorystring | nullHigh-level error class, on failure.
error_codestring | nullNormalized error code, on failure.
error_messagestring | nullHuman-readable error, on failure.
psp_transaction_idstring | nullProvider-side transaction reference.
gateway_feeinteger | nullGateway fee in minor units.
started_atstringWhen the attempt began (ISO 8601 UTC).
finished_atstring | nullWhen the attempt resolved (ISO 8601 UTC).

Example request

curl https://api.tokeflow.com/api/v1/transactions/tx_777/attempts \
  -H "Authorization: Bearer sk_live_mer_…"

Example response200 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",
      "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,
      "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

OrgMerchant

Auth: Organization key (any transaction in the org) or Merchant key (its own transactions). Scope: transactions:write.

Captures a transaction that was pre-authorized with capture: false. The transaction must be in capture_pending status; after a successful capture it becomes authorized.

Request fields

FieldTypeRequiredDescription
amountintegerNoAmount to capture, in minor units. Omit to capture the full authorized amount. For a partial capture, must be ≤ amount_authorized.

Most providers allow only one capture per authorization. On a partial capture, the uncaptured remainder is automatically released.

Example request — full capture

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 '{}'

Example request — partial capture

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 }'

Example response200 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",
    "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
      }
    ],
    "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"
}

A 400 (validation_error) is returned if the transaction is not in capture_pending status or the amount exceeds the authorized amount.


POST/api/v1/transactions/:id/void

OrgMerchant

Auth: Organization key (any transaction in the org) or Merchant key (its own transactions). Scope: transactions:write.

Voids an authorization before it is captured, releasing the held funds. The transaction must be in capture_pending or authorized status; after voiding it becomes voided.

Example request

curl -X POST https://api.tokeflow.com/api/v1/transactions/tx_777/void \
  -H "Authorization: Bearer sk_live_mer_…"

Example response200 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"
}

A 400 (validation_error) is returned if the transaction is not in a voidable status.

To reverse funds after capture, issue a refund instead of a void. See Refunds.


Errors

Every error uses the standard envelope. The most common cases for this resource:

HTTPtypeTypical cause
400validation_errorMissing required field, or capture/void in the wrong state.
401authentication_errorMissing or invalid API key.
403authorization_errorKey lacks the required scope.
404not_found_errorTransaction not found or not owned by the merchant.
429rate_limit_errorRate limit exceeded — back off exponentially.

See Errors for the full envelope and type catalog.

On this page