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.
A virtual account deposit that hasn't shown up is usually one of four things: it's still inside the rail's settlement window, it's held for compliance review, a bank returned it because the details didn't match, or the payer used a rail the account doesn't accept. The deposit's status and the payer's bank reference tell you which one.
Start with the status, not the support ticket.
on_hold is waiting on compliance review. Answer the request for information the same day: an unanswered hold can end in a refund to the sender.Most missing deposits fit one of eight patterns, and each has a different fix. Match the symptom first, then act.
| Symptom | Likely cause | What to do |
|---|---|---|
| Payer sent it today, nothing shows | Still in the settlement window, or sent after the cut-off | Wait out the rail's window before escalating |
| Nothing after 5 business days | Wrong account or routing number, or the transfer never left the payer's bank | Ask the payer for the bank reference and trace it |
Deposit shows as on_hold | Flagged for compliance review | Watch for a request for information and answer it within 24 hours |
Deposit shows as refunded | Returned to the sender after a mismatch or an unanswered hold | Find the reason, fix it, ask the payer to resend |
| Less money arrived than was sent | Intermediary or receiving bank fees on a wire or SWIFT payment | Reconcile it as a bank fee, not an underpayment |
| Foreign payer asks for an IBAN | US virtual accounts have no IBAN | Send the SWIFT details and ask for USD |
| Payer sent an instant RTP payment | RTP isn't a rail into a BlindPay virtual account | Ask for ACH or wire, or use an RTP payin's own instructions |
| A $0.01 deposit appears | A platform verifying the account with a micro-deposit | Reconcile it, it's expected |
New to the account itself? Start with what is a virtual account.
Most of the time, it's still on the rail. Bank transfers settle on business days, every rail has a daily cut-off, and a transfer sent after the cut-off is processed the next business day. Weekends, US federal holidays, and international banking holidays don't count.
These are the network windows from BlindPay's cut-off times reference:
| Rail | Cut-off (ET) | Typical network settlement |
|---|---|---|
| ACH | 9:00 PM | 1 to 3 business days |
| Same-Day ACH | 3:00 PM | Same business day |
| Domestic wire | 3:00 PM | Same business day |
| International SWIFT | 10:30 AM | Up to 5 business days |
Those are network times, not end-to-end ETAs. For ACH and wire deposits, BlindPay's own arrival window is up to 5 business days (payins). A SWIFT payment sent at 4:00 PM ET on the Friday before a US holiday can lose several calendar days before anyone has a reason to worry.
Check the payer's side too. Banks cap daily ACH and wire amounts, and a transfer over the cap can sit at the sending bank waiting for approval. From your side, that looks like a slow rail.
Rule of thumb: don't open a trace until the rail's full window has passed. Until then, the most useful thing your product can show is an expected arrival date.
Every deposit into a BlindPay virtual account creates a payin, and the payin's status tells you where the money is. There are five statuses, and three of them are final. Because the deposit itself creates the payin, no payin at all usually means the money hasn't reached the account.
| Status | What it means | Final? | What to show your customer |
|---|---|---|---|
processing | The deposit is arriving, or stablecoins are being converted and sent | No | "Payment received, processing" |
on_hold | Held for manual risk or compliance review | No | "Under review, we may ask for details" |
completed | Stablecoins delivered to the linked wallet | Yes | "Funds available" |
failed | The payin didn't go through | Yes | "Payment failed" plus the next step |
refunded | The deposit went back to the sender | Yes | "Returned to sender" plus the reason |
For a finer view, each tracking_* object on the payin has its own step: processing, on_hold, pending_review, pending_refund_review, or completed. tracking_transaction covers the fiat leg and carries a separate status that stays null until the bank side resolves to completed or failed.
The webhooks follow the same shape. payin.new fires when the deposit creates the payin, payin.update fires on intermediate steps like an arrival check or a manual review, and payin.complete fires when the payin is sent, refunded, or failed. So payin.complete doesn't mean success. Read the status (webhook events). Signature checks and duplicate handling are in stablecoin API webhooks.
A deposit lands on_hold when transaction monitoring flags it for manual review. It's a pause, not a rejection: if compliance clears it, the payin continues and the stablecoins go out.
The triggers BlindPay lists include unusual activity patterns, amounts that are large compared with the customer's history, sanctions or watchlist screening matches, and an open request for information on the customer (compliance holds).
If the flag can't be cleared internally, BlindPay emails your team (or sends a Slack message) with a request for information, or RFI. It asks for the relationship between the sender and your customer, the purpose of the payment, and the expected outcome. Per on-hold transactions, if the RFI isn't answered within 24 hours, the transaction may be refunded to the sender. A hold can last up to 30 days, and a timeout without a decision fails the transaction.
Don't mix this up with a customer-level RFI. When KYC or KYB review needs more documents, the customer moves to compliance_request, can't send or receive funds until it's resolved, and gets 27 days to respond (information requests). Different trigger, different clock.
The best prevention is boring: keep an invoice or contract on file for each large payer, and make sure the business description from onboarding matches what flows through the account. Virtual account requirements covers what the review looks at.
A deposit comes back when a bank in the chain or the compliance review can't accept it. The usual reasons are wrong details, a name mismatch, a closed or restricted account, unmet compliance requirements, or a rail the account doesn't take.
rtp payin always uses the shared memo-code account. SEPA needs an IBAN, which a US account doesn't have. SWIFT works, but only once the account is approved, since there's no memo-code fallback for SWIFT (payins).When a deposit is refunded, the money goes back to the sender, not to the wallet. Fiat refunds reach the payer once the banking network returns the funds, which depends on each bank's processing time, and fees may apply. Your customer's client can get back less than they sent.
Trace with the payer's bank reference, not the amount. Every rail has one, and it's the only thing a bank's operations team can search by.
Where the days go on a SWIFT payment, hop by hop, is in why are cross-border payments slow.
Here's one deposit through two endings. Amounts and timings are illustrative, not quotes.
Setup. A client in Germany pays a 4,800 USD invoice to your customer's US virtual account by SWIFT, with the SHA charge option.
payin.new) and moves to processing.on_hold (payin.update), and your team gets an RFI email.Ending A: you answer the same day. You send the invoice and the service contract. Compliance releases the hold, the 4,770 USD converts to USDC, and because the deposit is over $100, BlindPay's fee is deducted from the delivered amount at transaction time (transaction_fee_amount). payin.complete arrives with status completed. Your ledger books 4,800 invoiced, 30 bank fee, the BlindPay fee, and the net USDC received. Done.
Ending B: nobody answers for 24 hours. The transaction may be refunded. The payin ends refunded, and the 4,770 USD travels back through the banking network, possibly minus more fees. The client gets a partial refund days later and has to pay again. Same money, two weeks lost.
The difference between the two endings is one email. Put RFIs on someone's on-call rota.
How each fee in that chain works, including where the BlindPay fee lands below and above $100, is in virtual account fees.
BlindPay issues US virtual accounts in your customer's own name. They receive ACH, wire, and SWIFT, depending on the account type, and every deposit converts to USDC or USDT and settles to the wallet linked to the account. The account doesn't hold a balance. The money ends up in the wallet.
Each deposit is a payin with a status, tracking steps, and payin.* webhooks, so "where is my money" has an API answer. Holds come with an RFI to your team.
What it doesn't do: IBANs, SEPA, or RTP into the dedicated account. If your payers are in Europe, they pay by SWIFT in USD. The full account behavior is in virtual accounts, and the flow from bank deposit to wallet is in accept bank transfers and settle in stablecoins.
Map all five payin statuses to customer-facing messages, and name an owner for on_hold RFIs, before your next account goes live. Then build the failure screens on a development instance: a payin with a request_amount of $666.00 forces failed, and $777.00 forces refunded. You'll see both in production eventually. Better to see them first in a sandbox.
This article is for general information only and is not legal, tax, or financial advice.
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.
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.
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.