
Stablecoin card issuing: funding the authorization in time
A stablecoin card has to answer one question in about two seconds: can this person spend $48.20 right now? The card network does not care that the money sits on Solana or Base. It wants an approve or a decline before its timer runs out, and it will not wait for your chain to finalize. That constraint, not the choice of chain, is the real system design in stablecoin card issuing.
There are three honest ways to fund that answer. You hold fiat float and debit your own ledger, you lock the user's stablecoins as collateral and approve against a credit line, or you read the on-chain balance and approve on trust. Each one moves the risk to a different place. This guide walks through how to pick one and how to build the authorization path so it answers inside the budget.
Why this is suddenly everyone's problem
Stablecoin cards stopped being a crypto niche this year. Western Union launched Stablecard with Rain, a wallet plus a Visa secured credit card backed by USDPT, a dollar token issued by Anchorage Digital Bank on Solana, live across 37 markets at launch. On September 9, 2026, BVNK and Marqeta announced a partnership so Marqeta's issuing customers can back cards with stablecoin balances, with BVNK moving the stablecoins and Marqeta handling issuance and network relationships.
The state of stablecoin cards survey from Insights4VC puts Rain at roughly $3B annualized volume and Reap above $6B. Those are real programs clearing real transactions, and every one of them has solved the same timing problem somehow. The interesting part is which risk each one decided to carry.
The timing problem, precisely
A card authorization is a synchronous request. The merchant's acquirer sends it through the network to your issuer processor, the processor asks your system, and the answer travels back. If you use a processor with gateway just-in-time funding, the clock on your part is explicit. Marqeta's timeout documentation states that if your gateway does not respond within three seconds, the platform declines the transaction to the network. Subtract your own network hops and you should design for two.
Now look at the chain. Solana's commitment levels give you a processed state in about 0.4 seconds, a confirmed state (a supermajority of stake has voted) in about 0.6 seconds, and finalized after 32 further slots, roughly 13 seconds. Ethereum mainnet finality takes minutes. So a design that moves funds on-chain and waits for finality inside the authorization is dead on arrival.
Here is the part most teams miss: finality is not actually the hard problem. Confirmed blocks on Solana have not reverted in practice. The hard problem is that an authorization is a promise that lasts days. The network clears the transaction later, often a day or more after the swipe, and sometimes for a different amount (tips, fuel pumps, hotel holds). Whatever you approved against has to still be there when clearing arrives. If the user can move their stablecoins out of reach between authorization and clearing, you have issued an unsecured loan without meaning to.
Step 1: Decide where the balance lives at swipe time
This is the one decision that shapes everything else. Put the three models side by side.
| What you approve against | Your internal ledger balance | A credit line sized to locked stablecoins | A live read of the user's wallet |
| Who can move the funds after approval | Only you | User, but only after a withdrawal delay | User, instantly |
| Risk you carry | Float cost and treasury drift | Collateral price and liquidation timing | Clearing arrives after the wallet is empty |
| Custody posture | Custodial | User-owned contract, issuer lien | Self-custody |
| Latency in the auth path | Database read | Database read of an indexed contract state | RPC call unless you index |
| Good fit | Neobank style wallets, remittance | Corporate and self-custody cards | Low limits, trusted users only |
Pre-funded fiat float. The user's stablecoins sit in a wallet you custody. You keep a fiat float at the issuing bank sized to expected daily spend, and at authorization you debit your own ledger. Sweeping stablecoins to refill the float happens off the hot path. This is the simplest to operate and the most expensive in working capital.
Locked collateral. The user keeps stablecoins in a contract they own, but withdrawals go through a request and a delay, so you always have time to claim what outstanding authorizations need. You approve against a credit line sized to the locked balance and settle with the network from your own funds, then recover from the collateral. Rain describes this model: the customer owns a dedicated smart contract, Rain extends credit against it, fronts the fiat, and settles using the collateral. It is also why Stablecard is structured as a secured credit card rather than a debit card.
Optimistic on-chain read. You check the wallet balance at authorization and approve if it covers the amount. Nothing stops the user spending the same dollars on-chain a minute later. This only works with low limits and users you would lend to anyway.
For most programs the answer is the first or second model. Pick based on custody: if you already hold the keys, run float. If the product promise is self-custody, run locked collateral, and make the withdrawal delay longer than your worst realistic clearing lag.
Step 2: Answer from your ledger, never from the chain
Whichever model you pick, the authorization handler must never make a blockchain call. RPC providers have tail latencies measured in seconds on a bad day, and a three-second budget does not survive one slow request. Instead, maintain an available balance in your own database, fed by an indexer that watches deposits and withdrawal requests at confirmed commitment.
The number the handler reads is not the on-chain balance. It is:
available = confirmed_onchain_balance
- open_authorization_holds
- pending_withdrawal_requests
- safety_margin
This is a double-entry ledger problem wearing a card costume. Model each hold as a posting against the user's available balance into a pending holds account, so clearing, reversal, and expiry are just further postings and the sum always balances.
Step 3: Place the hold atomically and idempotently
Networks retry. Processors retry. You will see the same authorization more than once, and you must place exactly one hold. Key the hold on the processor's transaction token and make the insert and the balance check a single transaction.
async function authorize(req: AuthRequest): Promise<AuthDecision> {
return db.transaction(async (tx) => {
const existing = await tx.holds.findByToken(req.token);
if (existing) return existing.decision; // replay, same answer
const acct = await tx.accounts.lockForUpdate(req.accountId);
const amount = toMinorUnits(req.amount, req.currency);
const decision = acct.available >= amount ? "APPROVE" : "DECLINE";
await tx.holds.insert({ token: req.token, accountId: acct.id, amount, decision });
if (decision === "APPROVE") await tx.accounts.debitAvailable(acct.id, amount);
return decision;
});
}
The same discipline from idempotency keys in payment APIs applies, with one twist: the replay must return the original decision even if the balance has since changed.
Watch the units. USDC and most dollar stablecoins use six decimals on-chain, card amounts arrive in currency minor units. Convert once at the boundary and store integers.
Step 4: Design your fallback before the network designs it for you
Your gateway will be unreachable at some point. Two things then happen without you. The network may run stand-in processing and approve on its own rules, and processors offer their own fallback: Marqeta calls it Commando Mode, where the platform decides on business rules you define and queues webhooks for later.
Configure those rules deliberately. A stand-in limit of zero means every outage is a wall of declines. A generous one means an outage is an unsecured lending event. Size the stand-in limit to what one user can spend during your realistic outage window, and make sure the webhook consumer replays those decisions into your ledger as holds when you come back.
Step 5: Settle clearing against the hold
Clearing is where the money actually moves. The flow for a locked collateral program looks like this.
From swipe to settled, locked collateral model
Step 1 of 5Authorize
Ledger check against available balance, hold placed, approve returned inside the budget.
Holds that never clear must expire on a schedule and release back to available. Clearings with no matching hold (forced posts, stand-in approvals you missed) must still post, and they are the first thing your reconciliation engine should flag.
Pitfalls that show up in production
- Reading processed commitment. Indexing deposits at processed rather than confirmed lets a dropped transaction inflate available balance. Use confirmed for deposits, and treat withdrawals as pending from the moment they are requested.
- Forgetting incremental authorizations. Restaurants, hotels, and car rentals add to a hold after the first approval. Each increment is a new authorization against available balance, not a free pass.
- Treating the float as static. Spend is spiky around paydays and weekends. Size float from observed daily peaks, alert on drawdown, and automate the stablecoin to fiat sweep so a person is not the refill mechanism.
- Letting the withdrawal delay be shorter than clearing lag. If users can exit collateral in one hour and clearing sometimes lands in three days, you have created exactly the exposure the model exists to prevent.
Verify it before a card is live
Run the authorization handler under injected latency and confirm it still answers inside two seconds at your p99, with the RPC provider switched off entirely. Replay a day of authorizations twice and check that the second pass changes nothing. Then reconcile daily: every clearing matched to a hold, every expired hold released, and one exposure number (approved but not yet recovered) that someone looks at every morning. If that number surprises you, the design has a leak.
Stablecoin card issuing is mostly a ledger and a timer, which is also what we found when shipping stablecoin rails for a remittance corridor: the chain was the easy part. If you are working out which funding model fits your program, our stablecoin payment infrastructure team builds exactly this path, and we are happy to talk through your card program design.
New posts, in your inbox
Get an email when we publish a new deep-dive. No spam, unsubscribe anytime.