---
title: "Rails-first vs chain-first: choosing between an abstracted and an advanced blockchain payments API"
seoTitle: "Abstracted vs advanced blockchain payments API"
description: "Rails-first or chain-first? How BlindPay's Abstracted and Advanced API flavors differ, what changes in your code, and a go-live checklist for both."
date: "2026-10-18"
updated: "2026-10-18"
category: "payments"
author: "BlindPay Team"
faq:
  - q: "What is the difference between an abstracted and an advanced blockchain payments API?"
    a: "An abstracted API speaks in bank-rail terms: virtual accounts, deposits, and payouts over ACH, wire, SWIFT, Pix, or SPEI, with stablecoins settling behind the scenes. An advanced API exposes the blockchain layer: wallets, chains, tokens, on-chain authorization, and cross-chain transfers. BlindPay documents one API in both flavors, so you pick the view that matches where your users' money lives."
  - q: "Are BlindPay's Abstracted and Advanced flavors different APIs?"
    a: "No. They are two views of the same REST API at api.blindpay.com, with the same endpoints, fields, and keys. The docs switch between them with a flavor setting. The Abstracted flavor hides wallet and chain details behind bank-rail concepts, and the Advanced flavor shows the stablecoin mechanics, such as ERC-20 approvals, Stellar signing, and Solana delegation."
  - q: "Which flavor should a fintech start with?"
    a: "Start with Abstracted if your users think in dollars, reais, or pesos and never hold crypto: collect bank transfers, keep a managed balance, and pay out to bank accounts. Start with Advanced if your users already hold USDC or USDT in their own wallets, or if your product moves stablecoins between wallets and chains. Many teams use both."
  - q: "How do you authorize a stablecoin payout from an external wallet?"
    a: "It depends on the chain. On EVM chains such as Ethereum, Base, Polygon, and Arbitrum, the wallet calls ERC-20 approve for the quoted amount. On Stellar, you request an unsigned transaction from BlindPay, sign the XDR, and submit it. On Solana, you delegate the quoted token amount to BlindPay. A BlindPay-managed wallet needs no signing at all."
  - q: "What is USDB in BlindPay?"
    a: "USDB is BlindPay's test stablecoin. It exists only on development instances, on eight testnets: Ethereum Sepolia, Base Sepolia, Arbitrum Sepolia, Polygon Amoy, Stellar Testnet, Solana Devnet, Tempo Testnet, and Arc Testnet. You fund a wallet with USDB by creating a payin, which auto-completes on development instances. Production instances use real USDC or USDT on mainnets instead."
  - q: "What should be on a go-live checklist for a blockchain payments API?"
    a: "Verified webhook signatures with duplicate handling, idempotency keys on every mutating call, handling for expired quotes and on-hold payouts, a reconciliation job keyed on payment IDs and transaction hashes, alerts for payouts stuck in review, separate API keys per environment with IP allowlists, and a production test payout on each rail before real volume."
---

Rails-first or chain-first is a choice about what your code talks to. An abstracted blockchain payments API speaks in bank terms: virtual accounts, payins, and payouts over ACH, wire, SWIFT, Pix, or SPEI, with stablecoins settling underneath. An advanced API exposes wallets, chains, tokens, and on-chain authorization. BlindPay documents one API in both flavors.

If you are still deciding whether you need a blockchain at all, start with [blockchain payments vs crypto payments](/resources/more/blockchain-payments-vs-crypto-payments). This page assumes you are building and want to pick an integration shape.

**Key takeaways**

- Abstracted means bank-rail concepts. Advanced means wallets, chains, and tokens. Same API, same keys.
- Pick by where your users' money lives: in bank accounts, or in wallets they control.
- External wallets authorize each payout on-chain: ERC-20 approve, a signed Stellar XDR, or a Solana delegation.
- Development instances use USDB on testnets and complete payouts automatically.
- Go live with five things in place: webhooks, idempotency, error handling, reconciliation, monitoring.

## What are the Abstracted and Advanced flavors?

They are two ways of reading the same BlindPay API. The [overview](/docs/overview) page has both: the Abstracted flavor describes bank rails, and the Advanced flavor describes the stablecoin mechanics.

> **Definition:** An **abstracted payments API** presents payment-rail objects (bank accounts, deposits, payouts) and handles the blockchain leg internally. An **advanced payments API** exposes that leg: which wallet holds funds, which chain and token settle the transfer, and how the sender authorizes it.

In the Abstracted flavor, every dollar or real still settles through stablecoins, but BlindPay manages the conversion step. You never sign anything on-chain. In the Advanced flavor, you choose between BlindPay-managed wallets and customer-controlled wallets, pick networks and tokens, and handle authorization per chain.

The docs switch flavor with a query parameter, so `/docs/payouts?flavor=abstracted` and `/docs/payouts?flavor=advanced` are the same page through two lenses.

## How does Store, Receive, Send look in each flavor?

The same three verbs, described two ways. This table summarizes BlindPay's [Store](/docs/store), [Receive](/docs/receive), and [Send](/docs/send) pages plus payins and payouts.

| Verb | Abstracted reading | Advanced reading |
| --- | --- | --- |
| Store | A balance BlindPay holds for the customer (managed wallet) | A managed wallet (`bl_...`, custodial, beta) or an external blockchain wallet (`bw_...`, customer-controlled) |
| Receive | A bank deposit (ACH, wire, SWIFT, Pix, SPEI, Transfers, PSE) becomes a payin | Stablecoins arrive in a managed wallet, tracked by `wallet.inbound`; or a payin delivers stablecoins to any registered wallet |
| Send | A payout to a bank account over ACH, wire, RTP, SWIFT (POBO/COBO), Pix, SPEI, ACH COP, Transfers, SEPA, or Faster Payments | Stablecoins move out of a managed wallet to another address, or are pulled from a wallet to fund a fiat payout |

The Abstracted flavor maps to what a finance team already knows. The Advanced flavor maps to what a crypto-native product already does. Neither one is the beginner version.

## What changes in your code between the two?

Mostly the funding step of a payout. Everything before it (customer, bank account, quote) and after it (status, webhooks) is the same.

Every payout starts with a [payout quote](/docs/payout-quotes): a `bank_account_id`, a `network` and `token` for the funding leg, `currency_type`, `cover_fees`, and `request_amount` in minor units. The quote locks the rate and fees for 5 minutes. Then the funding source decides the next call:

| Funding source | Authorization | Execute call |
| --- | --- | --- |
| BlindPay-managed wallet | None, BlindPay moves the funds | `POST /payouts/evm` with the quote ID and the wallet address, on any supported chain |
| External wallet on an EVM chain | ERC-20 `approve` for the amount in the quote's `contract` object | `POST /payouts/evm` with the quote ID and sender address |
| External wallet on Stellar | `POST /payouts/stellar/authorize` returns an unsigned transaction; you sign the XDR | `POST /payouts/stellar` |
| External wallet on Solana | `POST /prepare-delegate-solana`, then sign and submit the delegation | `POST /payouts/evm` with the quote ID and Solana address |

The three authorization methods match each chain's own token model. [EIP-20](https://eips.ethereum.org/EIPS/eip-20) defines `approve` as allowing a spender to withdraw up to a set value. Solana's [token program](https://spl.solana.com/token) lets an account owner delegate authority over some or all of a balance with the Approve instruction. Stellar encodes transactions in [XDR](https://developers.stellar.org/docs/learn/fundamentals/data-format/xdr), so the sender signs a payment transaction instead of granting an allowance.

Quotes and approvals are single-use. To send again, quote again and authorize again. The per-chain tutorials are [payout with EVM](/docs/payout-evm), [payout with Stellar](/docs/payout-stellar), and [payout with Solana](/docs/payout-solana).

## Which chains and tokens can you use?

Nine chains, with token support that varies by chain. The [supported chains reference](/docs/kb/supported-chains) is the source of truth for `network` and `token` values; check it rather than the shorter tables inside individual guides.

| Chain | Mainnet stablecoins | Development testnet |
| --- | --- | --- |
| Ethereum | USDC, USDT | Ethereum Sepolia |
| Polygon | USDC, USDT | Polygon Amoy |
| Base | USDC | Base Sepolia |
| Arbitrum | USDC | Arbitrum Sepolia |
| Tempo | USDC, USDT | Tempo Testnet |
| Arc | USDC | Arc Testnet |
| Stellar | USDC | Stellar Testnet |
| Solana | USDC, USDT | Solana Devnet |
| Tron | USDT | none |

Production instances accept only USDC or USDT on mainnets. Development instances accept only USDB on testnets, and a mismatched pair is rejected. Tron has no testnet, so Tron flows can only be exercised in production.

In the Advanced flavor you can also move USDC between managed wallets across Ethereum, Polygon, Base, Arbitrum, and Arc with [Circle's CCTP v2](https://developers.circle.com/cctp), which burns USDC on the source chain and mints it on the destination. Other tokens stay on the same network. If the newer chains are unfamiliar, [payment blockchains like Tempo and Arc](/resources/more/payment-blockchains-tempo-arc-explained) explains what they are.

## Which flavor fits your product?

Decide by who holds the money between steps. Five common shapes:

| Product | Flavor | Why |
| --- | --- | --- |
| Payroll or contractor payouts funded by bank transfer | Abstracted | Users never see a wallet; deposit, hold a balance, pay out |
| A US account for customers abroad (collections) | Abstracted | Virtual accounts and payins are bank objects |
| A crypto wallet app adding cash-out to local banks | Advanced | Users already control wallets; payouts are authorized from them |
| A treasury tool moving USDC between chains | Advanced | Transfers, networks, and CCTP routes are the product |
| A platform doing both | Both | Abstracted screens for finance users, Advanced flows for crypto users |

Custody follows from the choice. BlindPay operates as a non-custodial payment processor for payout flows from customer-controlled wallets: you authorize the exact amount and BlindPay executes that single transaction. If a payout cannot be delivered after the stablecoins are collected, BlindPay refunds them to the quote's refund wallet, or to the sending wallet when none is set; on Pix and other non-USD local rails the refund is automatic, while USD payouts and payouts whose review times out are refunded after an operator review. Optional BlindPay-managed wallets (beta) are custodial when you choose that path. The [wallet custody comparison](/resources/more/custodial-vs-non-custodial-vs-mpc-wallets) covers the trade-offs.

## How do you test both flavors before going live?

On a development instance, which behaves like production without real money. Per the [sandbox vs production guide](/docs/learn/sandbox-vs-production):

- Every customer is auto-approved. Name one `Fail` to test a rejection.
- Wallets use USDB, funded by a payin that auto-completes about 30 seconds after creation.
- Payouts still run the on-chain authorization step, then complete automatically with no real bank transfer.
- A payout quote with `request_amount` of 66600 forces `failed`, and 77700 forces `refunded`.

Run each flavor's happy path, then both forced outcomes, and confirm your webhook handler, database, and user-facing screens all agree. [What sandbox testing misses](/resources/more/stablecoin-api-sandbox-vs-production) lists the gaps to cover in production.

## What belongs on the go-live checklist?

Five areas, the same for both flavors. Tick every line before the first production payout.

**1. Webhooks**

- Register an `https` endpoint per instance; BlindPay allows up to 25.
- Verify `svix-id`, `svix-timestamp`, and `svix-signature` against the raw body, and reject timestamps outside a 5-minute window ([verification docs](/docs/learn/webhooks-verification)).
- Deduplicate on `svix-id`, which stays the same across redeliveries.
- For payouts, handle `payout.new`, `payout.update`, and `payout.complete`, and branch on `status`, since a failed payout can arrive as an update.

**2. Idempotency**

- Send an `Idempotency-Key` header on every `POST`, `PUT`, `PATCH`, and `DELETE`.
- Retry with the exact same body bytes. A different body returns `422 idempotency_key_payload_mismatch`.
- Respect `409 idempotency_key_in_flight` and its `Retry-After` header. Keys last 24 hours ([idempotency docs](/docs/learn/idempotency)).

**3. Error handling**

- Treat an expired quote as normal: re-quote, show the new numbers, ask again. Never execute a stale quote.
- Map a `400` on an unsupported network and token pair to a configuration bug, not a user error.
- Expect SWIFT payouts to third parties to start `on_hold` until compliance documents are approved.

**4. Reconciliation**

- Store amounts in minor units, exactly as the API returns them.
- Keep your own payment ID next to the BlindPay quote, payout, or payin ID, and the on-chain transaction hash from the tracking objects.
- Run a daily job that matches your ledger to payout and payin statuses. The [webhooks and reconciliation guide](/resources/more/stablecoin-api-webhooks-reconciliation) has the matching logic.

**5. Monitoring**

- Alert on payouts in `on_hold` or `processing` longer than the rail's documented window.
- A `failed` payout, or one sitting past review, does not refund on its own. Contact support rather than wait.
- Use separate API keys for development and production, restrict production keys to your server IPs with `ip_whitelist`, and rotate by deleting and recreating a key ([API keys docs](/docs/learn/api-keys)).

Then send one small production payout on each rail you plan to use, and watch it all the way to `completed`.

## What to do next

Pick the flavor that matches where your users' money lives, then run its happy path and both forced outcomes on a development instance. If you are still comparing vendors, read the [best blockchain payment processors for fintechs](/resources/more/best-blockchain-payment-processors-fintech-2026) first.

[Open the BlindPay payout quickstart, pick your flavor, and send a USDB test payout today](/docs/quickstart-payout).
