Privy: fiat deposits, payouts, and KYC on the same wallet APIs logoPrivy: fiat deposits, payouts, and KYC on the same wallet APIs
Verify the entity once. Provision a reusable fiat deposit account. Pay out to us, gb, iban, pix, or swift. Bridge under the hood.
devrels.xyz/a/294Privy now moves fiat in and out of the same wallets you already create. Verify the user or organization once, give a wallet a reusable bank account, convert inbound funds to stablecoins, and pay out to a bank. Post: privy.io/blog/fiat-deposits-payouts-kyc-orchestration. Docs: fiat deposits and fiat payouts.
Bridge does conversion, virtual accounts, and settlement. You register a Bridge API key in the Privy dashboard, then stay on Privy IDs. Fiat stays blocked until verification completes. Eligibility and Bridge terms apply.
KYC / KYB on the entity
Verification is scoped to the wallet's entity (user or organization), not to each wallet. Hosted KYC for people, KYB for businesses. One call returns a URL. Privy accepts the flow and fires webhooks. Your app never holds the provider's customer records, virtual accounts, or payout addresses. See KYC and KYB.
Deposits
Create a persistent fiat deposit account on a wallet. No memo. Same details every time. Incoming fiat converts to the destination asset and lands on-chain. Webhooks follow the lifecycle.
import {PrivyClient} from "@privy-io/node";
const privy = new PrivyClient({
appId: process.env.PRIVY_APP_ID!,
appSecret: process.env.PRIVY_APP_SECRET!,
});
const {fiat_deposit_account: account} = await privy
.wallets()
.depositAccounts.fiat.create("<wallet-id>", {
provider: "bridge",
environment: "sandbox",
source: {currency: "usd"},
destination: {asset: "usdc", chain: "solana"},
});
// account.deposit_instructions holds the bank details to displayREST: POST /v1/wallets/{wallet_id}/deposit_accounts/fiat. Pass an Idempotency-Key. Accounts are billed resources at the provider. source.currency examples in docs: usd, eur. Privy returns the payment rails available for that currency. Destination chain must match the wallet's chain_type. Docs name tempo, base, and solana.
Launch rails
The 1 Sep 2026 post lists US ACH and wire, UK Faster Payments, SEPA in Europe, and Brazil PIX. Do not invent a bank whitelist. bank_name on payout registration is a free string.
Payouts
Register an external bank account on the user or organization. Then one wallet action sends crypto on-chain and settles fiat. Account types: us (ACH or wire), gb (Faster Payments), iban (SEPA), pix, swift.
const {external_fiat_account: bankAccount} = await privy
.users()
.externalFiatAccounts.create("did:privy:xxxxx", {
provider: "bridge",
environment: "sandbox",
currency: "usd",
account_owner_name: "Jane Doe",
account: {
type: "us",
account_number: "1234567899",
routing_number: "121212121",
checking_or_savings: "checking",
},
address: {
street_line_1: "123 Washington St",
city: "New York",
state: "NY",
postal_code: "10001",
country: "USA",
},
});
// bankAccount.id is the fiat_account_id to pay out toREST create: POST /v1/users/{user_id}/external_fiat_accounts or /v1/organizations/{organization_id}/external_fiat_accounts. PIX takes exactly one of pix_key or br_code.
Card onramps
Card, Apple Pay, and Google Pay are a separate Privy funding path. This piece is bank transfer in and bank payout out. Wallet keys and server signing stay in Privy white-label wallets.
Resources
Keep reading
Stablecoin rails are useless at the last mile if users only have cash. MoneyGram Ramps is the Foundation’s bid to wire that last mile into SDP payments.
How Avici’s neobank stack fits together: self-custodial escrow credit, fiat on-ramp accounts, and read-only agent access.
Move money between bank rails and crypto programmatically — quote, swap, withdraw, webhooks — with request signing instead of bearer tokens.
Get new articles in your inbox
Technical deep-dives on Solana tooling, infrastructure, and ecosystem. No noise.
