[{"data":1,"prerenderedAt":1253},["ShallowReactive",2],{"content-\u002Fresources\u002Fmore\u002Fhow-to-integrate-a-crypto-on-ramp-api":3,"resources-category-how-to-integrate-a-crypto-on-ramp-api":970},{"id":4,"title":5,"authors":6,"body":7,"categories":6,"category":916,"categoryType":6,"compare":6,"contributors":6,"date":917,"description":918,"extension":919,"faq":920,"howto":939,"isBlog":960,"isChangelog":960,"meta":961,"navigation":963,"path":964,"pillar":960,"products":6,"rawbody":965,"role":6,"seo":966,"seoTitle":967,"stem":968,"thumbnail":6,"updated":917,"__hash__":969},"content\u002Fresources\u002Fmore\u002Fhow-to-integrate-a-crypto-on-ramp-api.md","How to integrate a crypto on-ramp API: payin quotes, deposit instructions, and webhooks",null,{"type":8,"value":9,"toc":901},"minimark",[10,14,28,33,61,65,68,78,94,98,101,143,163,167,170,242,245,249,252,365,368,418,445,449,452,506,513,587,595,610,614,617,637,672,676,679,730,734,737,780,784,787,795,799,802,816,819,823,826,852,871,875,887,897],[11,12,13],"p",{},"A crypto on-ramp integration follows six steps: verify the customer, choose the wallet that receives the stablecoins, request a quote, create the payment and show the payer deposit instructions, handle webhooks until the payment settles, and reconcile. The quote locks the rate and fees. Webhooks, not polling, tell you when the fiat landed.",[11,15,16,17,22,23,27],{},"This guide covers the on-ramp direction: fiat in, stablecoins out. For the payout direction, see ",[18,19,21],"a",{"href":20},"\u002Fresources\u002Fmore\u002Fhow-to-integrate-a-stablecoin-api","integrating a stablecoin API",". Examples use BlindPay's API on a development instance. Field names are real, but check the ",[18,24,26],{"href":25},"\u002Fdocs\u002Fpayins","payins docs"," for the current shape before you ship.",[29,30,32],"h2",{"id":31},"key-takeaways","Key takeaways",[34,35,36,40,43,46,49],"ul",{},[37,38,39],"li",{},"The quote is the contract. It fixes the amount, fees, and destination for a short window, and the payment must be created inside it.",[37,41,42],{},"Each rail shows the payer something different: bank details and a memo code, a Pix code, a CLABE, a CBU, or a payment link.",[37,44,45],{},"Deposits arrive on the payer's schedule. Design for minutes on Pix and SPEI and days on ACH.",[37,47,48],{},"Verify webhook signatures on the raw body, deduplicate retries, and never move a payment backwards from a final status.",[37,50,51,52,56,57,60],{},"Force failures in the sandbox before production. ",[53,54,55],"code",{},"failed"," and ",[53,58,59],{},"refunded"," mean different things for your ledger.",[29,62,64],{"id":63},"what-does-an-on-ramp-integration-look-like","What does an on-ramp integration look like?",[11,66,67],{},"Your backend talks to the on-ramp API. The provider talks to the banks and the blockchain. Events come back to you.",[69,70,76],"pre",{"className":71,"code":73,"language":74,"meta":75},[72],"language-text","your app ──► on-ramp API ──► bank rails + liquidity ──► stablecoins to the wallet\n    ▲                                                          │\n    └──────────────────────── webhooks ◄───────────────────────┘\n","text","",[53,77,73],{"__ignoreMap":75},[11,79,80,81,85,86,89,90,93],{},"Three objects carry the whole flow: a ",[82,83,84],"strong",{},"customer"," (who is paying in), a ",[82,87,88],{},"wallet"," (where the stablecoins land), and a ",[82,91,92],{},"payin"," (one deposit, created from a quote). Everything else is detail on those three.",[29,95,97],{"id":96},"how-do-you-onboard-and-verify-the-customer","How do you onboard and verify the customer?",[11,99,100],{},"Every payin belongs to a verified customer. On BlindPay that takes two calls.",[102,103,104,118],"ol",{},[37,105,106,109,110,113,114,117],{},[82,107,108],{},"Terms of service."," Generate a terms-of-service URL with ",[53,111,112],{},"POST \u002Fv1\u002Fe\u002Finstances\u002F{instance_id}\u002Ftos",", send the customer to it, and keep the ",[53,115,116],{},"tos_id"," it returns.",[37,119,120,123,124,127,128,130,131,134,135,138,139,142],{},[82,121,122],{},"Create the customer."," ",[53,125,126],{},"POST \u002Fv1\u002Finstances\u002F{instance_id}\u002Fcustomers"," with the ",[53,129,116],{},", ",[53,132,133],{},"type"," (",[53,136,137],{},"individual"," or ",[53,140,141],{},"business","), and the KYC or KYB fields.",[11,144,145,146,149,150,153,154,157,158,162],{},"Then wait. KYC Standard for individuals is automated and takes about 60 seconds. KYB for businesses and KYC Enhanced for high-risk countries are manual reviews of 3 hours to 1 business day. A ",[53,147,148],{},"customer.update"," webhook tells you when ",[53,151,152],{},"kyc_status"," changes. Don't request quotes until it reads ",[53,155,156],{},"approved",". ",[18,159,161],{"href":160},"\u002Fresources\u002Fmore\u002Fhow-to-automate-kyc-kyb-stablecoin-payments","How to automate KYC and KYB"," covers the data you need to collect.",[29,164,166],{"id":165},"where-should-the-stablecoins-land","Where should the stablecoins land?",[11,168,169],{},"Pick the destination before you quote, because the quote needs its ID.",[171,172,173,192],"table",{},[174,175,176],"thead",{},[177,178,179,183,186,189],"tr",{},[180,181,182],"th",{},"Destination",[180,184,185],{},"ID",[180,187,188],{},"Custody",[180,190,191],{},"When to use it",[193,194,195,212,228],"tbody",{},[177,196,197,201,206,209],{},[198,199,200],"td",{},"External blockchain wallet",[198,202,203],{},[53,204,205],{},"bw_...",[198,207,208],{},"The customer holds the keys",[198,210,211],{},"The customer already has a wallet, or you never want to hold funds",[177,213,214,217,222,225],{},[198,215,216],{},"Managed wallet (beta)",[198,218,219],{},[53,220,221],{},"bl_...",[198,223,224],{},"BlindPay custodies the balance",[198,226,227],{},"You want a balance without running wallet infrastructure",[177,229,230,233,236,239],{},[198,231,232],{},"Virtual account",[198,234,235],{},"Settles to a linked wallet",[198,237,238],{},"Depends on the linked wallet",[198,240,241],{},"US payers send ACH or wire to a dedicated account number",[11,243,244],{},"An external wallet is registered once per address. On EVM networks the customer can sign a message so BlindPay recovers the address from the signature. On Stellar, Solana, and Tron you submit the address directly, so validate it twice: a stablecoin sent to the wrong address can't be recovered. The network is read from the wallet record, so you never pass a network on the quote.",[29,246,248],{"id":247},"how-do-you-request-a-quote","How do you request a quote?",[11,250,251],{},"The payin quote locks the numbers. Send it the amount, the rail, the token, who pays the fee, and the destination.",[69,253,257],{"className":254,"code":255,"language":256,"meta":75,"style":75},"language-bash shiki shiki-themes github-light","curl https:\u002F\u002Fapi.blindpay.com\u002Fv1\u002Finstances\u002Fin_000000000000\u002Fpayin-quotes \\\n  --request POST \\\n  --header 'Authorization: Bearer YOUR_API_KEY' \\\n  --header 'Content-Type: application\u002Fjson' \\\n  --data '{\n    \"blockchain_wallet_id\": \"bw_000000000000\",\n    \"payment_method\": \"pix\",\n    \"currency_type\": \"sender\",\n    \"request_amount\": 100000,\n    \"cover_fees\": false,\n    \"token\": \"USDB\",\n    \"payer_rules\": { \"pix_allowed_tax_ids\": [\"14747677786\"] }\n  }'\n","bash",[53,258,259,276,287,298,308,317,323,329,335,341,347,353,359],{"__ignoreMap":75},[260,261,264,268,272],"span",{"class":262,"line":263},"line",1,[260,265,267],{"class":266},"s7eDp","curl",[260,269,271],{"class":270},"sYBdl"," https:\u002F\u002Fapi.blindpay.com\u002Fv1\u002Finstances\u002Fin_000000000000\u002Fpayin-quotes",[260,273,275],{"class":274},"sYu0t"," \\\n",[260,277,279,282,285],{"class":262,"line":278},2,[260,280,281],{"class":274},"  --request",[260,283,284],{"class":270}," POST",[260,286,275],{"class":274},[260,288,290,293,296],{"class":262,"line":289},3,[260,291,292],{"class":274},"  --header",[260,294,295],{"class":270}," 'Authorization: Bearer YOUR_API_KEY'",[260,297,275],{"class":274},[260,299,301,303,306],{"class":262,"line":300},4,[260,302,292],{"class":274},[260,304,305],{"class":270}," 'Content-Type: application\u002Fjson'",[260,307,275],{"class":274},[260,309,311,314],{"class":262,"line":310},5,[260,312,313],{"class":274},"  --data",[260,315,316],{"class":270}," '{\n",[260,318,320],{"class":262,"line":319},6,[260,321,322],{"class":270},"    \"blockchain_wallet_id\": \"bw_000000000000\",\n",[260,324,326],{"class":262,"line":325},7,[260,327,328],{"class":270},"    \"payment_method\": \"pix\",\n",[260,330,332],{"class":262,"line":331},8,[260,333,334],{"class":270},"    \"currency_type\": \"sender\",\n",[260,336,338],{"class":262,"line":337},9,[260,339,340],{"class":270},"    \"request_amount\": 100000,\n",[260,342,344],{"class":262,"line":343},10,[260,345,346],{"class":270},"    \"cover_fees\": false,\n",[260,348,350],{"class":262,"line":349},11,[260,351,352],{"class":270},"    \"token\": \"USDB\",\n",[260,354,356],{"class":262,"line":355},12,[260,357,358],{"class":270},"    \"payer_rules\": { \"pix_allowed_tax_ids\": [\"14747677786\"] }\n",[260,360,362],{"class":262,"line":361},13,[260,363,364],{"class":270},"  }'\n",[11,366,367],{},"Four fields cause most bugs:",[34,369,370,382,394,410],{},[37,371,372,377,378,381],{},[82,373,374],{},[53,375,376],{},"request_amount"," is an integer in minor units. ",[53,379,380],{},"100000"," is R$1,000.00. For MXN, COP, and ARS it must also be a whole currency unit (a multiple of 100).",[37,383,384,389,390,393],{},[82,385,386],{},[53,387,388],{},"currency_type"," says which side the amount is in. On a payin quote, ",[53,391,392],{},"sender"," means fiat. On a payout quote it means stablecoin. Same field, opposite meaning.",[37,395,396,401,402,405,406,409],{},[82,397,398],{},[53,399,400],{},"cover_fees"," decides who pays: ",[53,403,404],{},"false"," takes the fee out of the stablecoins delivered, ",[53,407,408],{},"true"," adds it to the fiat the payer sends.",[37,411,412,417],{},[82,413,414],{},[53,415,416],{},"payer_rules"," names who may pay. Pix needs the allowed CPF or CNPJ tax IDs, Transfers 3.0 needs a CUIT or CUIL, and PSE needs the payer's name, document, email, phone, and bank code.",[11,419,420,421,130,424,427,428,431,432,435,436,439,440,444],{},"The response returns ",[53,422,423],{},"sender_amount",[53,425,426],{},"receiver_amount",", the market rate (",[53,429,430],{},"commercial_quotation","), the rate with fees (",[53,433,434],{},"blindpay_quotation","), each fee line, and ",[53,437,438],{},"expires_at"," in epoch milliseconds. You have 5 minutes. ",[18,441,443],{"href":442},"\u002Fresources\u002Fmore\u002Fstablecoin-api-quotes-explained","Stablecoin API quotes explained"," covers fee direction and units in depth.",[29,446,448],{"id":447},"how-do-you-create-the-payin-and-show-deposit-instructions","How do you create the payin and show deposit instructions?",[11,450,451],{},"Create the payin from the quote, then show the payer what their rail needs.",[69,453,455],{"className":254,"code":454,"language":256,"meta":75,"style":75},"curl https:\u002F\u002Fapi.blindpay.com\u002Fv1\u002Finstances\u002Fin_000000000000\u002Fpayins\u002Fevm \\\n  --request POST \\\n  --header 'Authorization: Bearer YOUR_API_KEY' \\\n  --header 'Content-Type: application\u002Fjson' \\\n  --header 'Idempotency-Key: 6f1c2a5e-payin-0001' \\\n  --data '{ \"payin_quote_id\": \"pq_000000000000\" }'\n",[53,456,457,466,474,482,490,499],{"__ignoreMap":75},[260,458,459,461,464],{"class":262,"line":263},[260,460,267],{"class":266},[260,462,463],{"class":270}," https:\u002F\u002Fapi.blindpay.com\u002Fv1\u002Finstances\u002Fin_000000000000\u002Fpayins\u002Fevm",[260,465,275],{"class":274},[260,467,468,470,472],{"class":262,"line":278},[260,469,281],{"class":274},[260,471,284],{"class":270},[260,473,275],{"class":274},[260,475,476,478,480],{"class":262,"line":289},[260,477,292],{"class":274},[260,479,295],{"class":270},[260,481,275],{"class":274},[260,483,484,486,488],{"class":262,"line":300},[260,485,292],{"class":274},[260,487,305],{"class":270},[260,489,275],{"class":274},[260,491,492,494,497],{"class":262,"line":310},[260,493,292],{"class":274},[260,495,496],{"class":270}," 'Idempotency-Key: 6f1c2a5e-payin-0001'",[260,498,275],{"class":274},[260,500,501,503],{"class":262,"line":319},[260,502,313],{"class":274},[260,504,505],{"class":270}," '{ \"payin_quote_id\": \"pq_000000000000\" }'\n",[11,507,508,509,512],{},"The path says ",[53,510,511],{},"evm"," for every method, including Pix, SPEI, PSE, and Transfers. The name is historical; it doesn't restrict the network. The response fills only the field for your rail:",[171,514,515,525],{},[174,516,517],{},[177,518,519,522],{},[180,520,521],{},"Payment method",[180,523,524],{},"Show the payer",[193,526,527,542,553,565,576],{},[177,528,529,532],{},[198,530,531],{},"ACH, wire",[198,533,534,537,538,541],{},[53,535,536],{},"blindpay_bank_details"," plus the ",[53,539,540],{},"memo_code"," to include in the transfer",[177,543,544,547],{},[198,545,546],{},"Pix",[198,548,549,552],{},[53,550,551],{},"pix_code",", as copyable text or a QR code",[177,554,555,558],{},[198,556,557],{},"SPEI",[198,559,560,561,564],{},"The ",[53,562,563],{},"clabe"," to transfer to",[177,566,567,570],{},[198,568,569],{},"Transfers 3.0",[198,571,572,573],{},"The account (CVU, CBU, or alias) in ",[53,574,575],{},"tracking_transaction.transfers_instruction",[177,577,578,581],{},[198,579,580],{},"PSE",[198,582,583,584],{},"The payment link in ",[53,585,586],{},"tracking_transaction.pse_instruction",[11,588,589,590,594],{},"If the customer has an approved ",[18,591,593],{"href":592},"\u002Fresources\u002Fmore\u002Fstablecoin-virtual-accounts-explained","virtual account",", ACH and wire deposits go to that dedicated account and the memo code is ignored. RTP is the exception: it always uses the memo-code path.",[11,596,597,598,604,605,609],{},"A created payin can't be cancelled. If the payer never pays, it fails after the rail's waiting window. Send the idempotency key on every create, so a network retry can't produce two payins. The header follows the ",[18,599,603],{"href":600,"rel":601},"https:\u002F\u002Fdatatracker.ietf.org\u002Fdoc\u002Fdraft-ietf-httpapi-idempotency-key-header\u002F",[602],"nofollow","IETF Idempotency-Key draft",", and ",[18,606,608],{"href":607},"\u002Fresources\u002Fmore\u002Fstablecoin-api-idempotency-keys","why idempotency keys matter"," covers the failure it prevents.",[29,611,613],{"id":612},"how-do-you-handle-on-ramp-webhooks","How do you handle on-ramp webhooks?",[11,615,616],{},"Three events cover a payin's life:",[34,618,619,625,631],{},[37,620,621,624],{},[53,622,623],{},"payin.new"," when the payin is created, including deposits into a virtual account.",[37,626,627,630],{},[53,628,629],{},"payin.update"," at intermediate steps, such as an arrival check or manual review.",[37,632,633,636],{},[53,634,635],{},"payin.complete"," when it finishes: delivered, refunded, or failed.",[11,638,639,640,130,643,604,646,649,650,655,656,658,659,130,662,664,665,157,667,671],{},"Every call is signed with ",[53,641,642],{},"svix-id",[53,644,645],{},"svix-timestamp",[53,647,648],{},"svix-signature"," headers. Verify the signature on the exact raw bytes, before you parse the JSON, following ",[18,651,654],{"href":652,"rel":653},"https:\u002F\u002Fdocs.svix.com\u002Freceiving\u002Fverifying-payloads\u002Fhow",[602],"Svix's verification guide",". The ",[53,657,642],{}," stays the same across redeliveries of one event, so it's your deduplication key. Events can arrive out of order, so store a status only if it moves the payment forward, and never overwrite ",[53,660,661],{},"completed",[53,663,55],{},", or ",[53,666,59],{},[18,668,670],{"href":669},"\u002Fresources\u002Fmore\u002Fstablecoin-api-webhooks-reconciliation","Stablecoin API webhooks"," has the code-level detail.",[29,673,675],{"id":674},"how-do-you-reconcile-on-ramp-payments","How do you reconcile on-ramp payments?",[11,677,678],{},"Treat webhooks as the fast path and a daily job as the truth.",[11,680,681,682,685,686,130,689,130,692,130,694,664,696,698,699,702,703,130,706,130,709,130,712,715,716,719,720,723,724,729],{},"The payin's top-level ",[53,683,684],{},"status"," is the source of truth: ",[53,687,688],{},"processing",[53,690,691],{},"on_hold",[53,693,661],{},[53,695,55],{},[53,697,59],{},". Four ",[53,700,701],{},"tracking_*"," objects (",[53,704,705],{},"tracking_transaction",[53,707,708],{},"tracking_payment",[53,710,711],{},"tracking_complete",[53,713,714],{},"tracking_partner_fee",") expose a finer ",[53,717,718],{},"step"," for status screens. Each day, list payins with ",[53,721,722],{},"GET \u002Fv1\u002Finstances\u002F{instance_id}\u002Fpayins"," and compare them with your ledger: amounts, statuses, fees. Match on the payin ID, not the transaction hash, because a transaction replaced during a ",[18,725,728],{"href":726,"rel":727},"https:\u002F\u002Fethereum.org\u002Fen\u002Fdevelopers\u002Fdocs\u002Fgas\u002F",[602],"gas spike"," can land under a different hash.",[29,731,733],{"id":732},"what-edge-cases-should-you-handle","What edge cases should you handle?",[11,735,736],{},"These show up in the first week of production:",[34,738,739,745,751,757,763,774],{},[37,740,741,744],{},[82,742,743],{},"Expired quote."," The payin create fails. Request a new quote; don't retry the old one.",[37,746,747,750],{},[82,748,749],{},"Amount out of range."," Payin quotes enforce a minimum and maximum per currency, and the customer's per-transaction limit applies too. Read the error for the range instead of hardcoding it.",[37,752,753,756],{},[82,754,755],{},"The payer never pays."," Pix, SPEI, Transfers, and PSE payins wait up to 30 minutes before failing. ACH and wire wait up to 5 business days.",[37,758,759,762],{},[82,760,761],{},"On hold."," Transaction monitoring can hold a payin for review. Answer any request for information quickly; an unanswered one may end in a refund.",[37,764,765,123,768,770,771,773],{},[82,766,767],{},"Refunded vs failed.",[53,769,59],{}," means the deposit went back to the sender. Fiat refunds wait on the bank network and can carry fees. ",[53,772,55],{}," needs a look before you tell the customer anything.",[37,775,776,779],{},[82,777,778],{},"Wrong destination."," A wallet registered with the wrong address receives the stablecoins anyway. Validate addresses at registration, not at delivery.",[29,781,783],{"id":782},"how-do-you-test-an-on-ramp-integration","How do you test an on-ramp integration?",[11,785,786],{},"Development instances run the whole flow without real money. Payins complete automatically about 30 seconds after creation and deliver USDB, a test stablecoin, on testnets such as Sepolia, Base Sepolia, Polygon Amoy, Stellar testnet, and Solana devnet.",[11,788,789,790,794],{},"Force the outcomes you can't wait for in real life: a payin for 666.00 fails and one for 777.00 is refunded. Run both through your webhook handler and ledger. Two things the sandbox can't show you: Tron has no testnet, and real deposits arrive on real rail timing. Plan one small supervised payin per rail in production. ",[18,791,793],{"href":792},"\u002Fresources\u002Fmore\u002Fstablecoin-api-sandbox-vs-production","Sandbox vs production"," lists the rest.",[29,796,798],{"id":797},"abstracted-or-advanced-which-api-flavor-should-you-use","Abstracted or Advanced: which API flavor should you use?",[11,800,801],{},"BlindPay's docs come in two flavors over the same API, the same keys, and the same webhooks.",[34,803,804,810],{},[37,805,806,809],{},[82,807,808],{},"Abstracted"," is for teams that think in bank payments. Payins are deposits, virtual accounts are deposit accounts, and the stablecoin settles behind the scenes in the linked wallet.",[37,811,812,815],{},[82,813,814],{},"Advanced"," exposes the stablecoin layer: chains, tokens, managed and external wallets, and on-chain authorization for payouts.",[11,817,818],{},"Choose Abstracted if your users never see a wallet address. Choose Advanced if your product is a wallet, or if your users pick the network. You can switch at any time; nothing about your account changes.",[29,820,822],{"id":821},"how-do-you-use-a-coding-agent-to-build-the-integration","How do you use a coding agent to build the integration?",[11,824,825],{},"AI coding agents are good at this kind of work, if they get the API's rules up front. BlindPay ships three surfaces for them:",[34,827,828,837,843],{},[37,829,830,134,833,836],{},[82,831,832],{},"An MCP server",[53,834,835],{},"@blindpay\u002Fmcp",") that exposes the API as tools for Claude Code, Codex, Cursor, and other MCP clients.",[37,838,839,842],{},[82,840,841],{},"Agent Skills"," that teach the agent the API's conventions.",[37,844,845,848,849,851],{},[82,846,847],{},"Prebuilt prompts",", including a payin quickstart prompt that encodes the gotchas (minor units, the 5-minute quote window, the ",[53,850,511],{}," path).",[11,853,854,855,858,859,862,863,865,866,870],{},"A prompt that works: \"Using the BlindPay API on a development instance, build a payin flow for Pix: create a customer, register a Solana wallet, request a payin quote with ",[53,856,857],{},"cover_fees: false",", create the payin, render the Pix code, and handle ",[53,860,861],{},"payin.*"," webhooks with Svix signature verification and deduplication on ",[53,864,642],{},". Write tests for completed, failed (666.00), and refunded (777.00).\" The ",[18,867,869],{"href":868},"\u002Fdocs\u002Fbuild-with-ai","build with AI"," page has the setup.",[29,872,874],{"id":873},"what-to-do-next","What to do next",[11,876,877,878,56,882,886],{},"Get a development instance, run one Pix or ACH payin end to end, and force a failure and a refund. If your handler and ledger stay correct through all three, you're ready for the production checklist. If you're still choosing a provider, read ",[18,879,881],{"href":880},"\u002Fresources\u002Fmore\u002Fbusiness-vs-consumer-crypto-on-ramps","business vs consumer crypto on-ramps",[18,883,885],{"href":884},"\u002Fresources\u002Fmore\u002Fcrypto-on-ramp-fees-explained","crypto on-ramp fees explained"," first.",[11,888,889],{},[890,891,892,893,896],"em",{},"This article is general information, not legal, tax, or financial advice. API fields and behavior change; the ",[18,894,895],{"href":25},"BlindPay docs"," are the reference.",[898,899,900],"style",{},"html pre.shiki code .s7eDp, html code.shiki .s7eDp{--shiki-default:#6F42C1}html pre.shiki code .sYBdl, html code.shiki .sYBdl{--shiki-default:#032F62}html pre.shiki code .sYu0t, html code.shiki .sYu0t{--shiki-default:#005CC5}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"title":75,"searchDepth":278,"depth":278,"links":902},[903,904,905,906,907,908,909,910,911,912,913,914,915],{"id":31,"depth":278,"text":32},{"id":63,"depth":278,"text":64},{"id":96,"depth":278,"text":97},{"id":165,"depth":278,"text":166},{"id":247,"depth":278,"text":248},{"id":447,"depth":278,"text":448},{"id":612,"depth":278,"text":613},{"id":674,"depth":278,"text":675},{"id":732,"depth":278,"text":733},{"id":782,"depth":278,"text":783},{"id":797,"depth":278,"text":798},{"id":821,"depth":278,"text":822},{"id":873,"depth":278,"text":874},"payments","2026-09-20","The on-ramp API flow step by step: verify the customer, pick the wallet, quote, create the payin, show deposit instructions, and handle webhooks.","md",[921,924,927,930,933,936],{"q":922,"a":923},"What is the basic flow of a crypto on-ramp API?","Onboard and verify the customer, register the wallet that will receive the stablecoins, request a quote, create the payment from that quote, show the payer the deposit instructions, and listen for webhooks until the payment is complete. The quote is the step that locks the rate and fees.",{"q":925,"a":926},"How long does an on-ramp quote stay valid?","Usually a few minutes. On BlindPay a payin quote expires 5 minutes after creation, except OTC quotes, which expire in 10 seconds. The expiry is returned in epoch milliseconds, so parse it carefully, and request a new quote if the window has passed.",{"q":928,"a":929},"Why use webhooks instead of polling for on-ramp status?","Deposits arrive on the payer's schedule, not yours. A Pix payment can land in seconds and an ACH credit can take days. Webhooks tell you the moment the status changes, while polling either wastes calls or reacts late. Keep a daily reconciliation job as a backstop for missed events.",{"q":931,"a":932},"What happens if the payer never sends the money?","The payment waits for a window that depends on the rail, then fails. On BlindPay, Pix, SPEI, Transfers, and PSE payins wait up to 30 minutes before failing, and ACH or wire payins wait up to 5 business days. A created payin can't be cancelled, so let it expire and create a new quote if the payer comes back.",{"q":934,"a":935},"Can I test an on-ramp integration without real money?","Yes. A sandbox or development instance simulates deposits. On BlindPay, development payins complete about 30 seconds after creation and deliver a test stablecoin, USDB, on testnets. Set the amount to 666.00 to force a failure or 777.00 to force a refund, and check that your code handles both.",{"q":937,"a":938},"Should I use an SDK or call the REST API directly?","Use the SDK if one exists for your language, since it handles authentication and types. Generate a client from the OpenAPI spec otherwise. BlindPay ships SDKs for Node.js, Python, Go, PHP, and Swift, and an OpenAPI 3.1 spec for everything else.",{"name":940,"steps":941},"How to integrate a crypto on-ramp API",[942,945,948,951,954,957],{"name":943,"text":944},"Onboard and verify the customer","Have the customer accept the provider's terms of service, create the customer with KYC or KYB data, and wait for the approval webhook before quoting.",{"name":946,"text":947},"Choose where the stablecoins land","Register an external wallet the customer controls, or use a provider-managed wallet or a virtual account, and save its ID.",{"name":949,"text":950},"Request a live quote","Send the amount in minor units, the payment method, the token, who pays the fee, and the destination wallet. Save the quote ID and its expiry.",{"name":952,"text":953},"Create the payin and show deposit instructions","Create the payin from the quote before it expires and show the payer the instructions for their rail: bank details and a memo code, a Pix code, a CLABE, or a payment link.",{"name":955,"text":956},"Handle webhooks","Verify each webhook signature on the raw body, deduplicate by message ID, and move your payment record forward only, never back from a final status.",{"name":958,"text":959},"Reconcile and test failure paths","Reconcile payins against your ledger daily, and force failed and refunded outcomes in the sandbox before going live.",false,{"author":962},"BlindPay Team",true,"\u002Fresources\u002Fmore\u002Fhow-to-integrate-a-crypto-on-ramp-api","---\ntitle: \"How to integrate a crypto on-ramp API: payin quotes, deposit instructions, and webhooks\"\nseoTitle: \"How to integrate a crypto on-ramp API: quote to webhook\"\ndescription: \"The on-ramp API flow step by step: verify the customer, pick the wallet, quote, create the payin, show deposit instructions, and handle webhooks.\"\ndate: \"2026-09-20\"\nupdated: \"2026-09-20\"\nauthor: \"BlindPay Team\"\ncategory: \"payments\"\nhowto:\n  name: \"How to integrate a crypto on-ramp API\"\n  steps:\n    - name: \"Onboard and verify the customer\"\n      text: \"Have the customer accept the provider's terms of service, create the customer with KYC or KYB data, and wait for the approval webhook before quoting.\"\n    - name: \"Choose where the stablecoins land\"\n      text: \"Register an external wallet the customer controls, or use a provider-managed wallet or a virtual account, and save its ID.\"\n    - name: \"Request a live quote\"\n      text: \"Send the amount in minor units, the payment method, the token, who pays the fee, and the destination wallet. Save the quote ID and its expiry.\"\n    - name: \"Create the payin and show deposit instructions\"\n      text: \"Create the payin from the quote before it expires and show the payer the instructions for their rail: bank details and a memo code, a Pix code, a CLABE, or a payment link.\"\n    - name: \"Handle webhooks\"\n      text: \"Verify each webhook signature on the raw body, deduplicate by message ID, and move your payment record forward only, never back from a final status.\"\n    - name: \"Reconcile and test failure paths\"\n      text: \"Reconcile payins against your ledger daily, and force failed and refunded outcomes in the sandbox before going live.\"\nfaq:\n  - q: \"What is the basic flow of a crypto on-ramp API?\"\n    a: \"Onboard and verify the customer, register the wallet that will receive the stablecoins, request a quote, create the payment from that quote, show the payer the deposit instructions, and listen for webhooks until the payment is complete. The quote is the step that locks the rate and fees.\"\n  - q: \"How long does an on-ramp quote stay valid?\"\n    a: \"Usually a few minutes. On BlindPay a payin quote expires 5 minutes after creation, except OTC quotes, which expire in 10 seconds. The expiry is returned in epoch milliseconds, so parse it carefully, and request a new quote if the window has passed.\"\n  - q: \"Why use webhooks instead of polling for on-ramp status?\"\n    a: \"Deposits arrive on the payer's schedule, not yours. A Pix payment can land in seconds and an ACH credit can take days. Webhooks tell you the moment the status changes, while polling either wastes calls or reacts late. Keep a daily reconciliation job as a backstop for missed events.\"\n  - q: \"What happens if the payer never sends the money?\"\n    a: \"The payment waits for a window that depends on the rail, then fails. On BlindPay, Pix, SPEI, Transfers, and PSE payins wait up to 30 minutes before failing, and ACH or wire payins wait up to 5 business days. A created payin can't be cancelled, so let it expire and create a new quote if the payer comes back.\"\n  - q: \"Can I test an on-ramp integration without real money?\"\n    a: \"Yes. A sandbox or development instance simulates deposits. On BlindPay, development payins complete about 30 seconds after creation and deliver a test stablecoin, USDB, on testnets. Set the amount to 666.00 to force a failure or 777.00 to force a refund, and check that your code handles both.\"\n  - q: \"Should I use an SDK or call the REST API directly?\"\n    a: \"Use the SDK if one exists for your language, since it handles authentication and types. Generate a client from the OpenAPI spec otherwise. BlindPay ships SDKs for Node.js, Python, Go, PHP, and Swift, and an OpenAPI 3.1 spec for everything else.\"\n---\n\nA crypto on-ramp integration follows six steps: verify the customer, choose the wallet that receives the stablecoins, request a quote, create the payment and show the payer deposit instructions, handle webhooks until the payment settles, and reconcile. The quote locks the rate and fees. Webhooks, not polling, tell you when the fiat landed.\n\nThis guide covers the on-ramp direction: fiat in, stablecoins out. For the payout direction, see [integrating a stablecoin API](\u002Fresources\u002Fmore\u002Fhow-to-integrate-a-stablecoin-api). Examples use BlindPay's API on a development instance. Field names are real, but check the [payins docs](\u002Fdocs\u002Fpayins) for the current shape before you ship.\n\n## Key takeaways\n\n- The quote is the contract. It fixes the amount, fees, and destination for a short window, and the payment must be created inside it.\n- Each rail shows the payer something different: bank details and a memo code, a Pix code, a CLABE, a CBU, or a payment link.\n- Deposits arrive on the payer's schedule. Design for minutes on Pix and SPEI and days on ACH.\n- Verify webhook signatures on the raw body, deduplicate retries, and never move a payment backwards from a final status.\n- Force failures in the sandbox before production. `failed` and `refunded` mean different things for your ledger.\n\n## What does an on-ramp integration look like?\n\nYour backend talks to the on-ramp API. The provider talks to the banks and the blockchain. Events come back to you.\n\n```text\nyour app ──► on-ramp API ──► bank rails + liquidity ──► stablecoins to the wallet\n    ▲                                                          │\n    └──────────────────────── webhooks ◄───────────────────────┘\n```\n\nThree objects carry the whole flow: a **customer** (who is paying in), a **wallet** (where the stablecoins land), and a **payin** (one deposit, created from a quote). Everything else is detail on those three.\n\n## How do you onboard and verify the customer?\n\nEvery payin belongs to a verified customer. On BlindPay that takes two calls.\n\n1. **Terms of service.** Generate a terms-of-service URL with `POST \u002Fv1\u002Fe\u002Finstances\u002F{instance_id}\u002Ftos`, send the customer to it, and keep the `tos_id` it returns.\n2. **Create the customer.** `POST \u002Fv1\u002Finstances\u002F{instance_id}\u002Fcustomers` with the `tos_id`, `type` (`individual` or `business`), and the KYC or KYB fields.\n\nThen wait. KYC Standard for individuals is automated and takes about 60 seconds. KYB for businesses and KYC Enhanced for high-risk countries are manual reviews of 3 hours to 1 business day. A `customer.update` webhook tells you when `kyc_status` changes. Don't request quotes until it reads `approved`. [How to automate KYC and KYB](\u002Fresources\u002Fmore\u002Fhow-to-automate-kyc-kyb-stablecoin-payments) covers the data you need to collect.\n\n## Where should the stablecoins land?\n\nPick the destination before you quote, because the quote needs its ID.\n\n| Destination | ID | Custody | When to use it |\n| --- | --- | --- | --- |\n| External blockchain wallet | `bw_...` | The customer holds the keys | The customer already has a wallet, or you never want to hold funds |\n| Managed wallet (beta) | `bl_...` | BlindPay custodies the balance | You want a balance without running wallet infrastructure |\n| Virtual account | Settles to a linked wallet | Depends on the linked wallet | US payers send ACH or wire to a dedicated account number |\n\nAn external wallet is registered once per address. On EVM networks the customer can sign a message so BlindPay recovers the address from the signature. On Stellar, Solana, and Tron you submit the address directly, so validate it twice: a stablecoin sent to the wrong address can't be recovered. The network is read from the wallet record, so you never pass a network on the quote.\n\n## How do you request a quote?\n\nThe payin quote locks the numbers. Send it the amount, the rail, the token, who pays the fee, and the destination.\n\n```bash\ncurl https:\u002F\u002Fapi.blindpay.com\u002Fv1\u002Finstances\u002Fin_000000000000\u002Fpayin-quotes \\\n  --request POST \\\n  --header 'Authorization: Bearer YOUR_API_KEY' \\\n  --header 'Content-Type: application\u002Fjson' \\\n  --data '{\n    \"blockchain_wallet_id\": \"bw_000000000000\",\n    \"payment_method\": \"pix\",\n    \"currency_type\": \"sender\",\n    \"request_amount\": 100000,\n    \"cover_fees\": false,\n    \"token\": \"USDB\",\n    \"payer_rules\": { \"pix_allowed_tax_ids\": [\"14747677786\"] }\n  }'\n```\n\nFour fields cause most bugs:\n\n- **`request_amount`** is an integer in minor units. `100000` is R$1,000.00. For MXN, COP, and ARS it must also be a whole currency unit (a multiple of 100).\n- **`currency_type`** says which side the amount is in. On a payin quote, `sender` means fiat. On a payout quote it means stablecoin. Same field, opposite meaning.\n- **`cover_fees`** decides who pays: `false` takes the fee out of the stablecoins delivered, `true` adds it to the fiat the payer sends.\n- **`payer_rules`** names who may pay. Pix needs the allowed CPF or CNPJ tax IDs, Transfers 3.0 needs a CUIT or CUIL, and PSE needs the payer's name, document, email, phone, and bank code.\n\nThe response returns `sender_amount`, `receiver_amount`, the market rate (`commercial_quotation`), the rate with fees (`blindpay_quotation`), each fee line, and `expires_at` in epoch milliseconds. You have 5 minutes. [Stablecoin API quotes explained](\u002Fresources\u002Fmore\u002Fstablecoin-api-quotes-explained) covers fee direction and units in depth.\n\n## How do you create the payin and show deposit instructions?\n\nCreate the payin from the quote, then show the payer what their rail needs.\n\n```bash\ncurl https:\u002F\u002Fapi.blindpay.com\u002Fv1\u002Finstances\u002Fin_000000000000\u002Fpayins\u002Fevm \\\n  --request POST \\\n  --header 'Authorization: Bearer YOUR_API_KEY' \\\n  --header 'Content-Type: application\u002Fjson' \\\n  --header 'Idempotency-Key: 6f1c2a5e-payin-0001' \\\n  --data '{ \"payin_quote_id\": \"pq_000000000000\" }'\n```\n\nThe path says `evm` for every method, including Pix, SPEI, PSE, and Transfers. The name is historical; it doesn't restrict the network. The response fills only the field for your rail:\n\n| Payment method | Show the payer |\n| --- | --- |\n| ACH, wire | `blindpay_bank_details` plus the `memo_code` to include in the transfer |\n| Pix | `pix_code`, as copyable text or a QR code |\n| SPEI | The `clabe` to transfer to |\n| Transfers 3.0 | The account (CVU, CBU, or alias) in `tracking_transaction.transfers_instruction` |\n| PSE | The payment link in `tracking_transaction.pse_instruction` |\n\nIf the customer has an approved [virtual account](\u002Fresources\u002Fmore\u002Fstablecoin-virtual-accounts-explained), ACH and wire deposits go to that dedicated account and the memo code is ignored. RTP is the exception: it always uses the memo-code path.\n\nA created payin can't be cancelled. If the payer never pays, it fails after the rail's waiting window. Send the idempotency key on every create, so a network retry can't produce two payins. The header follows the [IETF Idempotency-Key draft](https:\u002F\u002Fdatatracker.ietf.org\u002Fdoc\u002Fdraft-ietf-httpapi-idempotency-key-header\u002F), and [why idempotency keys matter](\u002Fresources\u002Fmore\u002Fstablecoin-api-idempotency-keys) covers the failure it prevents.\n\n## How do you handle on-ramp webhooks?\n\nThree events cover a payin's life:\n\n- `payin.new` when the payin is created, including deposits into a virtual account.\n- `payin.update` at intermediate steps, such as an arrival check or manual review.\n- `payin.complete` when it finishes: delivered, refunded, or failed.\n\nEvery call is signed with `svix-id`, `svix-timestamp`, and `svix-signature` headers. Verify the signature on the exact raw bytes, before you parse the JSON, following [Svix's verification guide](https:\u002F\u002Fdocs.svix.com\u002Freceiving\u002Fverifying-payloads\u002Fhow). The `svix-id` stays the same across redeliveries of one event, so it's your deduplication key. Events can arrive out of order, so store a status only if it moves the payment forward, and never overwrite `completed`, `failed`, or `refunded`. [Stablecoin API webhooks](\u002Fresources\u002Fmore\u002Fstablecoin-api-webhooks-reconciliation) has the code-level detail.\n\n## How do you reconcile on-ramp payments?\n\nTreat webhooks as the fast path and a daily job as the truth.\n\nThe payin's top-level `status` is the source of truth: `processing`, `on_hold`, `completed`, `failed`, or `refunded`. Four `tracking_*` objects (`tracking_transaction`, `tracking_payment`, `tracking_complete`, `tracking_partner_fee`) expose a finer `step` for status screens. Each day, list payins with `GET \u002Fv1\u002Finstances\u002F{instance_id}\u002Fpayins` and compare them with your ledger: amounts, statuses, fees. Match on the payin ID, not the transaction hash, because a transaction replaced during a [gas spike](https:\u002F\u002Fethereum.org\u002Fen\u002Fdevelopers\u002Fdocs\u002Fgas\u002F) can land under a different hash.\n\n## What edge cases should you handle?\n\nThese show up in the first week of production:\n\n- **Expired quote.** The payin create fails. Request a new quote; don't retry the old one.\n- **Amount out of range.** Payin quotes enforce a minimum and maximum per currency, and the customer's per-transaction limit applies too. Read the error for the range instead of hardcoding it.\n- **The payer never pays.** Pix, SPEI, Transfers, and PSE payins wait up to 30 minutes before failing. ACH and wire wait up to 5 business days.\n- **On hold.** Transaction monitoring can hold a payin for review. Answer any request for information quickly; an unanswered one may end in a refund.\n- **Refunded vs failed.** `refunded` means the deposit went back to the sender. Fiat refunds wait on the bank network and can carry fees. `failed` needs a look before you tell the customer anything.\n- **Wrong destination.** A wallet registered with the wrong address receives the stablecoins anyway. Validate addresses at registration, not at delivery.\n\n## How do you test an on-ramp integration?\n\nDevelopment instances run the whole flow without real money. Payins complete automatically about 30 seconds after creation and deliver USDB, a test stablecoin, on testnets such as Sepolia, Base Sepolia, Polygon Amoy, Stellar testnet, and Solana devnet.\n\nForce the outcomes you can't wait for in real life: a payin for 666.00 fails and one for 777.00 is refunded. Run both through your webhook handler and ledger. Two things the sandbox can't show you: Tron has no testnet, and real deposits arrive on real rail timing. Plan one small supervised payin per rail in production. [Sandbox vs production](\u002Fresources\u002Fmore\u002Fstablecoin-api-sandbox-vs-production) lists the rest.\n\n## Abstracted or Advanced: which API flavor should you use?\n\nBlindPay's docs come in two flavors over the same API, the same keys, and the same webhooks.\n\n- **Abstracted** is for teams that think in bank payments. Payins are deposits, virtual accounts are deposit accounts, and the stablecoin settles behind the scenes in the linked wallet.\n- **Advanced** exposes the stablecoin layer: chains, tokens, managed and external wallets, and on-chain authorization for payouts.\n\nChoose Abstracted if your users never see a wallet address. Choose Advanced if your product is a wallet, or if your users pick the network. You can switch at any time; nothing about your account changes.\n\n## How do you use a coding agent to build the integration?\n\nAI coding agents are good at this kind of work, if they get the API's rules up front. BlindPay ships three surfaces for them:\n\n- **An MCP server** (`@blindpay\u002Fmcp`) that exposes the API as tools for Claude Code, Codex, Cursor, and other MCP clients.\n- **Agent Skills** that teach the agent the API's conventions.\n- **Prebuilt prompts**, including a payin quickstart prompt that encodes the gotchas (minor units, the 5-minute quote window, the `evm` path).\n\nA prompt that works: \"Using the BlindPay API on a development instance, build a payin flow for Pix: create a customer, register a Solana wallet, request a payin quote with `cover_fees: false`, create the payin, render the Pix code, and handle `payin.*` webhooks with Svix signature verification and deduplication on `svix-id`. Write tests for completed, failed (666.00), and refunded (777.00).\" The [build with AI](\u002Fdocs\u002Fbuild-with-ai) page has the setup.\n\n## What to do next\n\nGet a development instance, run one Pix or ACH payin end to end, and force a failure and a refund. If your handler and ledger stay correct through all three, you're ready for the production checklist. If you're still choosing a provider, read [business vs consumer crypto on-ramps](\u002Fresources\u002Fmore\u002Fbusiness-vs-consumer-crypto-on-ramps) and [crypto on-ramp fees explained](\u002Fresources\u002Fmore\u002Fcrypto-on-ramp-fees-explained) first.\n\n*This article is general information, not legal, tax, or financial advice. API fields and behavior change; the [BlindPay docs](\u002Fdocs\u002Fpayins) are the reference.*\n",{"title":5,"description":918},"How to integrate a crypto on-ramp API: quote to webhook","resources\u002Fmore\u002Fhow-to-integrate-a-crypto-on-ramp-api","L95CNyA1aqa5GSKo5kJc-tvDnPGSnIYrr24GVO3M5Tc",[971,975,979,983,987,991,995,999,1003,1007,1011,1015,1019,1023,1027,1031,1035,1038,1042,1046,1050,1054,1058,1059,1063,1067,1071,1075,1079,1083,1087,1091,1094,1097,1101,1105,1109,1113,1117,1121,1125,1128,1131,1134,1138,1142,1146,1150,1154,1158,1162,1166,1169,1173,1177,1181,1185,1189,1193,1197,1201,1205,1209,1213,1217,1221,1225,1229,1233,1237,1241,1245,1249],{"path":972,"title":973,"description":974},"\u002Fresources\u002Fmore\u002Fagent-payment-protocols-compared","AP2 vs ACP vs x402: agent payment protocols compared","AP2, ACP, and x402 each verify that an AI agent had permission to spend. Here is what every protocol covers, who backs it, and the reconciliation gap none of them close.",{"path":976,"title":977,"description":978},"\u002Fresources\u002Fmore\u002Fbest-stablecoin-payment-platform-fintech-2026","Best stablecoin payment platforms for fintech in 2026: a US comparison","Seven stablecoin payment platforms compared for US fintechs in 2026: what makes an API production-ready, how each provider handles compliance, settlement speed against ACH, and how to run the evaluation.",{"path":980,"title":981,"description":982},"\u002Fresources\u002Fmore\u002Fbest-stablecoin-payment-providers-2026","Best stablecoin payment providers in 2026: how to choose","How to choose a stablecoin payment provider in 2026: the four provider types, a comparison of 10 options, and the questions that decide the fit.",{"path":984,"title":985,"description":986},"\u002Fresources\u002Fmore\u002Fwhat-are-blockchain-payments","Blockchain payments explained: how stablecoins move money without correspondent banks","Blockchain payments move a stablecoin on a public ledger instead of messages between banks. How they work, what they cost, and how they compare with SWIFT.",{"path":988,"title":989,"description":990},"\u002Fresources\u002Fmore\u002Fbuild-vs-buy-stablecoin-payments","Build vs buy: should you build stablecoin payouts in-house or use an API?","Building stablecoin payouts in-house means wallets, liquidity, banking partners, licenses, and a compliance program. When building makes sense.",{"path":992,"title":993,"description":994},"\u002Fresources\u002Fmore\u002Fcan-a-virtual-account-replace-a-bank-account","Can a virtual account replace a business bank account? What each one does for cross-border companies","Usually not. A virtual account collects and settles payments; a bank account runs payroll, taxes, and credit. A job-by-job guide for cross-border teams.",{"path":996,"title":997,"description":998},"\u002Fresources\u002Fmore\u002Flatam-payout-liquidity-partner-pix-spei","Choosing a liquidity partner for LatAm payouts: Pix, SPEI, and beyond","How to choose a liquidity partner for payouts into Latin America: how Pix and SPEI work, how a stablecoin liquidity layer replaces local bank accounts, and a checklist for coverage, pricing, and compliance.",{"path":1000,"title":1001,"description":1002},"\u002Fresources\u002Fmore\u002Fstablecoin-payout-mistakes","Common stablecoin payout mistakes: wrong network, expired quotes, and bad bank details","The mistakes that make stablecoin payouts fail or stall: wrong network or token, expired quotes, deposits below minimums, bad bank details, and cut-offs.",{"path":1004,"title":1005,"description":1006},"\u002Fresources\u002Fmore\u002Fcorrespondent-banking-vs-stablecoin-liquidity","Correspondent banking vs stablecoin liquidity: why pre-funding traps your capital","Correspondent banking keeps cross-border payouts liquid by parking cash in nostro accounts in every country. What that trapped capital costs a treasury team, and what stablecoin liquidity changes.",{"path":1008,"title":1009,"description":1010},"\u002Fresources\u002Fmore\u002Fcrypto-payment-processor-for-businesses","Crypto payment processor for businesses: what to compare before you choose","Compare crypto payment processors on six criteria: settlement speed, stablecoins, compliance, dev effort, payout coverage, and pricing. Scorecard inside.",{"path":1012,"title":1013,"description":1014},"\u002Fresources\u002Fmore\u002Fcustodial-vs-non-custodial-off-ramps","Custodial vs non-custodial off-ramps: who holds the money, and what happens if the provider fails","A custodial off-ramp holds your stablecoins; a non-custodial one pulls them only at payout. What changes in insolvency, de-banking, and failed payouts.",{"path":1016,"title":1017,"description":1018},"\u002Fresources\u002Fmore\u002Fcustodial-vs-non-custodial-vs-mpc-wallets","Custodial vs non-custodial vs MPC wallets: how to choose","Custodial, non-custodial, and MPC wallets differ in who holds the keys. Compare control, recovery, risk, and regulation, with product examples for each.",{"path":1020,"title":1021,"description":1022},"\u002Fresources\u002Fmore\u002Fstablecoin-cross-border-payments-savings","How businesses use stablecoins for cross-border payments (and where the savings come from)","Correspondent hops, FX markup, and pre-funding: what stablecoin settlement does to each cost of a cross-border payment, with a $50,000 example to Brazil.",{"path":1024,"title":1025,"description":1026},"\u002Fresources\u002Fmore\u002Fhow-a-stablecoin-payment-works","How does a stablecoin payment move? From bank deposit to local payout, step by step","A stablecoin payment moves in legs: fiat collected, stablecoin settled, fiat paid out. What happens at each step, where delays hide, what recipients see.",{"path":1028,"title":1029,"description":1030},"\u002Fresources\u002Fmore\u002Fcross-border-merchant-payments-without-pre-funding","How global merchants get paid across borders with stablecoins, no pre-funding required","Pre-funding means parking local currency in every market before money moves. Stablecoin virtual accounts remove it. A worked example across 4 countries.",{"path":1032,"title":1033,"description":1034},"\u002Fresources\u002Fmore\u002Fstablecoin-payout-settlement-times","How long does a stablecoin payout take? Settlement times by country and rail","Stablecoin payouts settle in minutes on Pix, SPEI, RTP, and Transfers 3.0, and in 1 to 5 business days on ACH, SEPA, and SWIFT. Full table by rail.",{"path":884,"title":1036,"description":1037},"How much does a crypto on-ramp cost? Fees, spreads, and how to read a quote","A crypto on-ramp charges through the rate spread, a service fee, the payment rail, and sometimes the network. How each works, and how to read the quote.",{"path":1039,"title":1040,"description":1041},"\u002Fresources\u002Fmore\u002Fstablecoin-off-ramp-fees-explained","How much does a stablecoin off-ramp cost? Fees per transaction vs a bank wire","What a stablecoin off-ramp costs per transaction: network fee, FX spread, percentage and flat fees, worked at $200, $2,000, and $20,000 vs a bank wire.",{"path":1043,"title":1044,"description":1045},"\u002Fresources\u002Fmore\u002Fhow-to-add-stablecoin-payments-to-your-wallet-integration","How to add stablecoin payments to your wallet integration","Connect the wallets you already run to bank deposits and local payouts: register addresses, open virtual accounts, quote, authorize, and track webhooks.",{"path":1047,"title":1048,"description":1049},"\u002Fresources\u002Fmore\u002Fhow-to-choose-a-virtual-account-provider","How to choose a virtual account provider: a 12-point checklist for developers and finance teams","Twelve criteria for evaluating a virtual account API, from rails and naming to custody, webhooks, and pricing, plus red flags and a scorecard to copy.",{"path":1051,"title":1052,"description":1053},"\u002Fresources\u002Fmore\u002Fhow-to-choose-on-off-ramp-provider","How to choose the best on\u002Foff ramp provider for your fintech app","Six criteria for evaluating a crypto on\u002Foff ramp provider: corridor coverage, live quotes, fiat settlement speed, licensing, API quality, and liquidity depth. Each with concrete tests to run, a comparison table, and a scoring framework.",{"path":1055,"title":1056,"description":1057},"\u002Fresources\u002Fmore\u002Fhow-to-evaluate-payment-orchestration-platform","How to evaluate a payment orchestration platform for cross-border payments","Six criteria that decide whether an orchestration platform works for cross-border money: rail coverage, compliance per corridor, developer experience, settlement speed, FX transparency, and pricing.",{"path":964,"title":5,"description":918},{"path":1060,"title":1061,"description":1062},"\u002Fresources\u002Fmore\u002Fhow-to-issue-stablecoin-cards-api","How to issue stablecoin-funded cards through an API: a developer's guide","Build vs. buy for stablecoin card issuing, the objects a card issuing API must expose, a step-by-step integration flow, and where KYC and KYB sit in it.",{"path":1064,"title":1065,"description":1066},"\u002Fresources\u002Fmore\u002Fhow-to-off-ramp-usdc-to-us-bank-account","How to off-ramp USDC to a US bank account: ACH, RTP, or wire","Cashing out USDC or USDT to a US bank account: when ACH, Same Day ACH, RTP, and wire pay out, the cut-offs in ET, the fields you need, and what delays it.",{"path":1068,"title":1069,"description":1070},"\u002Fresources\u002Fmore\u002Fhow-to-off-ramp-usdc-to-euros-sepa","How to off-ramp USDC to euros over SEPA: networks, IBAN details, and timing","Converting USDC to EUR in a SEPA bank account: which networks work, the IBAN details you need, SEPA vs SEPA Instant timing, limits, and what MiCA changes.",{"path":1072,"title":1073,"description":1074},"\u002Fresources\u002Fmore\u002Fhow-to-off-ramp-usdt-latin-america","How to off-ramp USDT to local currency in Latin America","Converting USDT to BRL, MXN, ARS, or COP: which networks work, the payout rail in each country, weekend timing, fees, and the documents a business needs.",{"path":1076,"title":1077,"description":1078},"\u002Fresources\u002Fmore\u002Fhow-to-on-ramp-local-currency-latin-america","How to on-ramp BRL, MXN, ARS, and COP into stablecoins: Pix, SPEI, Transfers 3.0, and PSE","How Latin American bank payments become USDC or USDT: what each rail shows the payer, the payer data it needs, how fast it lands, and the traps by country.",{"path":1080,"title":1081,"description":1082},"\u002Fresources\u002Fmore\u002Fhow-to-send-usdc-to-bank-account-brazil","How to send USDC to a bank account in Brazil","Step-by-step: convert USDC to Brazilian reais and deliver them to a bank account over Pix using a stablecoin payout API. Quote, verify, send, settle in minutes.",{"path":1084,"title":1085,"description":1086},"\u002Fresources\u002Fmore\u002Fhow-to-test-virtual-accounts-sandbox","How to test a virtual accounts API integration before going live","The integration sequence for a virtual accounts API, what a sandbox simulates and what it can't, and a test plan with the statuses and webhooks to expect.",{"path":1088,"title":1089,"description":1090},"\u002Fresources\u002Fmore\u002Fvirtual-account-reconciliation","How virtual accounts automate payment reconciliation (with a worked example)","Virtual accounts match each deposit to a customer by account number, not a free-text reference. A worked example with partial payments and micro-deposits.",{"path":607,"title":1092,"description":1093},"Idempotency keys in a stablecoin API: how to never send the same payout twice","A timeout on a payout call is the most common way to pay someone twice. How idempotency keys prevent it, what replays, what conflicts, and how to retry.",{"path":20,"title":1095,"description":1096},"Integrating a stablecoin API: a developer's guide to cross-border payments with BlindPay","Step-by-step integration of a stablecoin API: authenticate, onboard a customer, create a virtual USD account, quote and send a cross-border payout, and handle signed webhooks. Endpoints, statuses, and SDKs for BlindPay.",{"path":1098,"title":1099,"description":1100},"\u002Fresources\u002Fmore\u002Fliquidity-risk-global-payouts","Managing liquidity risk in global payouts: a practical guide for fintechs and PSPs","Liquidity risk in payouts is the chance funds aren't available at the right rate, in the right currency, when a payout settles. Its four sources and a six-step framework to manage them.",{"path":1102,"title":1103,"description":1104},"\u002Fresources\u002Fmore\u002Fmarketplace-stablecoin-payouts-latam","Marketplace payouts in Latin America: stablecoin rails for sellers in Brazil, Mexico, Colombia, and Argentina","How marketplaces pay sellers, creators, and vendors across Latin America with stablecoin settlement: supported rails (Pix, SPEI, PSE, Argentine transfers), the end-to-end payout workflow, API integration, and what changes for speed, minimums, and FX cost.",{"path":1106,"title":1107,"description":1108},"\u002Fresources\u002Fmore\u002Fnon-custodial-payments-explained","Non-custodial payments: what they are and why they reduce risk for businesses","A non-custodial payment provider moves your money without holding it between payments. Who controls the funds, who carries the risk, and what to ask.",{"path":1110,"title":1111,"description":1112},"\u002Fresources\u002Fmore\u002Fon-off-ramp-liquidity-live-quotes","On\u002Foff ramp liquidity with live quotes: how it works and why it matters","What on\u002Foff ramp liquidity with live quotes means for developers: live quote vs batch rate, the quote ID flow in an API, what happens on expiry, how liquidity depth changes spread by transaction size, rate windows and UX, and a checklist for evaluating a live quote API.",{"path":1114,"title":1115,"description":1116},"\u002Fresources\u002Fmore\u002Fpayment-orchestration-vs-payment-gateway","Payment orchestration vs payment gateway: what's the difference?","A gateway connects you to one processor. An orchestration platform connects to many rails and picks the best path per transaction. The table, the triggers, and a worked USD to BRL example.",{"path":1118,"title":1119,"description":1120},"\u002Fresources\u002Fmore\u002Fstablecoin-api-openapi-sdks","Stablecoin API SDKs: how one OpenAPI spec keeps five languages in sync","BlindPay's stablecoin API is described by one OpenAPI 3.1 spec that drives validation, docs, SDKs for Node, Python, Go, PHP, and Swift, and the MCP server.",{"path":1122,"title":1123,"description":1124},"\u002Fresources\u002Fmore\u002Fstablecoin-api-sla-settlement-finality","Stablecoin API SLAs and settlement finality explained","Stablecoin API uptime numbers cluster near 99.9% for a reason: most providers measure API acceptance instead of the point where money becomes final and spendable.",{"path":442,"title":1126,"description":1127},"Stablecoin API quotes explained: expiry, fee direction, and minor units","A stablecoin API quote locks the rate, fees, and amounts for a few minutes. How expiry works, which side pays the fee, and the field that flips meaning.",{"path":792,"title":1129,"description":1130},"Stablecoin API sandbox vs production: what testing misses","Most stablecoin API sandboxes pass every integration test and still leave a team unprepared for production, because webhook delivery and idempotent retries are exactly what sandboxes fake or skip.",{"path":669,"title":1132,"description":1133},"Stablecoin API webhooks: signature checks, duplicate events, and reconciliation","How to handle stablecoin API webhooks in production: verify signatures on raw bytes, dedupe retries, never regress a final status, reconcile daily.",{"path":1135,"title":1136,"description":1137},"\u002Fresources\u002Fmore\u002Fstablecoin-fx-slippage-live-quotes","Stablecoin FX slippage: how live quotes turn the quoted rate into the rate you get","FX slippage is the gap between the rate a stablecoin on-ramp or off-ramp shows and the rate that settles. Why quote freshness is a liquidity signal, and how to check a quote-then-execute flow.",{"path":1139,"title":1140,"description":1141},"\u002Fresources\u002Fmore\u002Fstablecoin-cards-latin-america","Stablecoin cards in Latin America: how they work in Brazil, Mexico, Argentina, and Colombia","How USD stablecoin cards work in Brazil, Mexico, Argentina, and Colombia: local card and crypto rules, costs at the point of sale, and when a Pix or SPEI payout fits better.",{"path":1143,"title":1144,"description":1145},"\u002Fresources\u002Fmore\u002Fstablecoin-liquidity-provider-vs-fx-desk","Stablecoin liquidity providers vs traditional FX desks: what finance teams should know","A bank FX desk prices cross-border payouts by relationship. A stablecoin liquidity provider prices them by API. How the two compare on cost, speed, minimums, coverage, and compliance.",{"path":1147,"title":1148,"description":1149},"\u002Fresources\u002Fmore\u002Fstablecoin-payment-fees-vs-card-processing-fees","Stablecoin payment fees vs credit card processing fees: what merchants actually pay","Cards cost merchants 1.5% to 3.5% plus cross-border, FX, and chargeback fees. Stablecoin payments cost cents on-chain plus a sub-percent conversion spread.",{"path":1151,"title":1152,"description":1153},"\u002Fresources\u002Fmore\u002Fstablecoin-payments-guide","Stablecoin payments explained: a guide for businesses","Stablecoin payments move dollar-pegged tokens between parties and settle in minutes, 24\u002F7. How they work, what they cost, and how businesses accept and send them.",{"path":1155,"title":1156,"description":1157},"\u002Fresources\u002Fmore\u002Fstablecoin-payout-statuses-explained","Stablecoin payout statuses explained: processing, on hold, completed, failed, and refunded","What each stablecoin payout status means, which are final, why an on-chain confirmation isn't a completed payout, and how to test every failure.",{"path":1159,"title":1160,"description":1161},"\u002Fresources\u002Fmore\u002Fstablecoin-payroll-latam-contractors","Stablecoin payroll for LATAM contractors: how it actually works in 2026","How US companies pay contractors in Argentina, Brazil, Mexico, and Colombia with stablecoins in 2026: USDC vs USDT, the step-by-step payout flow, US tax reporting, a platform comparison, and how to start.",{"path":1163,"title":1164,"description":1165},"\u002Fresources\u002Fmore\u002Fstablecoin-settlement-for-merchants","Stablecoin settlement explained: how merchants get paid faster than card networks","Stablecoin payments settle in seconds to minutes, final and 24\u002F7. Cards take 1 to 3 business days and wires up to 5. How it works and how to cash out.",{"path":592,"title":1167,"description":1168},"Stablecoin virtual accounts explained: from bank transfer to wallet balance","A stablecoin virtual account is a bank account in your customer's name whose deposits convert to USDC or USDT. How approval, deposits, and fees work.",{"path":1170,"title":1171,"description":1172},"\u002Fresources\u002Fmore\u002Fstablecoin-virtual-cards-cross-border-payouts","Stablecoin-funded virtual cards vs. traditional virtual cards for cross-border payouts","Stablecoin-funded vs. bank-funded virtual cards for paying contractors and vendors abroad: funding speed, pre-funding, FX cost, settlement finality, and a Brazil walkthrough.",{"path":1174,"title":1175,"description":1176},"\u002Fresources\u002Fmore\u002Fstablecoins-local-rails-latin-america","Stablecoins plus local rails: how cross-border payments actually land in Latin America","A stablecoin crosses the border in seconds, but the payment lands over Pix, SPEI, or another local rail. How that last mile works in Brazil and Mexico.",{"path":1178,"title":1179,"description":1180},"\u002Fresources\u002Fmore\u002Fstablecoin-vs-swift-b2b-payments","Stablecoins vs SWIFT for B2B cross-border payments: a real comparison","Where SWIFT wires still win, where stablecoin settlement wins, and how to compare the two on cost, speed, traceability, and failure modes for business payments in 2026.",{"path":1182,"title":1183,"description":1184},"\u002Fresources\u002Fmore\u002Fusdc-to-ars-routes-2026","USDC to ARS in 2026: routes, fees, and rules compared","Four ways to convert USDC to Argentine pesos in 2026: stablecoin payout APIs, local exchanges, P2P, and global exchanges with Transfers 3.0. Fees, speed, KYC, and Argentina's PSAV rules compared.",{"path":1186,"title":1187,"description":1188},"\u002Fresources\u002Fmore\u002Fusdc-to-brl-routes-2026","USDC to BRL in 2026: routes, fees, and rules compared","Four ways to convert USDC to Brazilian reais in 2026: stablecoin payout APIs, local exchanges, P2P, and global exchanges with Pix. Fees, speed, KYC, and Brazil's VASP rules compared.",{"path":1190,"title":1191,"description":1192},"\u002Fresources\u002Fmore\u002Fusdc-to-cop-routes-2026","USDC to COP in 2026: routes, fees, and rules compared","Four ways to convert USDC to Colombian pesos in 2026: stablecoin payout APIs, local exchanges, P2P, and global exchanges with PSE. Fees, speed, KYC, and Colombia's VASP rules compared.",{"path":1194,"title":1195,"description":1196},"\u002Fresources\u002Fmore\u002Fusdc-to-mxn-routes-2026","USDC to MXN in 2026: routes, fees, and rules compared","Four ways to convert USDC to Mexican pesos in 2026: stablecoin payout APIs, local exchanges, P2P, and global exchanges with SPEI. Fees, speed, KYC, and Mexico's rules compared.",{"path":1198,"title":1199,"description":1200},"\u002Fresources\u002Fmore\u002Fvirtual-account-deposit-not-received","Virtual account deposit not received? Why deposits get delayed, held, or returned","Why a virtual account deposit is late, on hold, or returned: arrival windows, payin statuses, RFIs, wrong rails, and how to trace a wire or SWIFT payment.",{"path":1202,"title":1203,"description":1204},"\u002Fresources\u002Fmore\u002Fvirtual-account-vs-virtual-iban","Virtual account vs virtual IBAN vs real bank account: what's the difference?","A real account holds funds for one holder. A virtual account routes deposits into a master account. A virtual IBAN is the IBAN version. When to use each.",{"path":1206,"title":1207,"description":1208},"\u002Fresources\u002Fmore\u002Fvirtual-accounts-cross-border-payments","Virtual accounts for cross-border payments: use cases, payment rails, and costs","How virtual accounts let payers abroad pay a local-style account, which rails collect and pay out, what drives the cost, and five questions to ask.",{"path":1210,"title":1211,"description":1212},"\u002Fresources\u002Fmore\u002Fpix-key-cpf-clabe-payout-details","What details do you need to pay someone in Brazil or Mexico? Pix keys, CPF, and CLABE","What a payout to Brazil or Mexico needs from the recipient: Pix key types, CPF and CNPJ formats, the 18-digit CLABE, and the checks that stop a bad payout.",{"path":1214,"title":1215,"description":1216},"\u002Fresources\u002Fmore\u002Fno-pre-funding-stablecoin-payouts","What does \"no pre-funding\" mean in a stablecoin API?","No pre-funding means each payout is funded when you send it, not from a balance parked in advance. The three funding models, the math, and what to ask.",{"path":1218,"title":1219,"description":1220},"\u002Fresources\u002Fmore\u002Fwhat-is-a-crypto-on-ramp-and-off-ramp","What is a crypto on-ramp and off-ramp? A guide for fintech builders","A crypto on-ramp converts fiat into stablecoins or crypto; an off-ramp converts them back into fiat in a bank account. How each works step by step, how they differ, which payment methods on-ramps support, and who they are built for.",{"path":1222,"title":1223,"description":1224},"\u002Fresources\u002Fmore\u002Fwhat-is-a-liquidity-market-cross-border-payments","What is a liquidity market in cross-border payments? And why stablecoin liquidity is changing it","A liquidity market in cross-border payments is where the currency to settle a transfer gets sourced. How correspondent banks pre-fund it, and how stablecoin liquidity changes the model.",{"path":1226,"title":1227,"description":1228},"\u002Fresources\u002Fmore\u002Fwhat-is-a-stablecoin-offramp","What is a stablecoin off-ramp? How crypto becomes cash","A stablecoin off-ramp converts stablecoins like USDC or USDT back into fiat currency in a bank account. How the conversion works and who regulates it.",{"path":1230,"title":1231,"description":1232},"\u002Fresources\u002Fmore\u002Fwhat-is-a-virtual-account","What is a virtual account? A plain-English guide for fintech teams","A virtual account is a unique set of bank details that routes incoming payments to one customer or purpose. How it works, who uses it, and where it fits.",{"path":1234,"title":1235,"description":1236},"\u002Fresources\u002Fmore\u002Fwhat-is-payment-orchestration","What is payment orchestration? The routing layer, explained","Payment orchestration is the routing layer between your app and every processor, bank, and rail you use. The five layers, how stablecoin settlement fits, and how it differs from a gateway.",{"path":1238,"title":1239,"description":1240},"\u002Fresources\u002Fmore\u002Fstablecoin-payments-provider-due-diligence","What to ask a stablecoin payments provider: 30 due diligence questions","The questions to ask a stablecoin payments vendor before you sign: licensing, custody, pricing, rails, compliance, failure handling, security, and exit.",{"path":1242,"title":1243,"description":1244},"\u002Fresources\u002Fmore\u002Fhow-to-track-a-crypto-off-ramp-payout","Where is my off-ramp payout? How to track it rail by rail, and what to tell the recipient","Track an off-ramp payout from transaction hash to bank: the reference each rail gives you (Pix E2E ID, SPEI key, ACH trace, UETR) and status copy.",{"path":1246,"title":1247,"description":1248},"\u002Fresources\u002Fmore\u002Fwhy-are-cross-border-payments-slow","Why are cross-border payments slow? Where the days go in an international wire","Most SWIFT payments reach the destination bank within an hour. The days go to cut-offs, correspondent hops, compliance checks, and local crediting.",{"path":1250,"title":1251,"description":1252},"\u002Fresources\u002Fmore\u002Fwhy-crypto-on-ramp-deposits-fail","Why crypto on-ramp deposits fail: missing references, late transfers, holds, and refunds","Most failed on-ramps fail on the fiat side: a missing reference, the wrong payer, a late transfer, a hold. What happens to the money in each case.",1790867704257]