---
title: "Virtual account deposit not received? Why deposits get delayed, held, or returned"
seoTitle: "Virtual account deposit not received? Holds and returns"
description: "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."
date: "2026-09-13"
category: "payments"
author: "BlindPay Team"
faq:
  - q: "How long does a virtual account deposit take to arrive?"
    a: "It depends on the rail. On the networks, ACH settles in 1 to 3 business days, Same-Day ACH and domestic wires on the same business day, and SWIFT in up to 5 business days. Transfers sent after the daily cut-off start counting from the next business day. At BlindPay, the arrival window for ACH and wire deposits is up to 5 business days."
  - q: "Why is my virtual account deposit on hold?"
    a: "A deposit goes on hold when transaction monitoring flags it for manual compliance review, for example an unusual activity pattern or an amount that's large for that customer. It's a pause, not a rejection. At BlindPay, your team may get a request for information about the sender and the purpose. If it isn't answered within 24 hours, the deposit may be refunded to the sender."
  - q: "Why was my virtual account deposit returned?"
    a: "Deposits usually come back because the details didn't match: a wrong account or routing number, a beneficiary name that isn't the account holder's, or an account that's closed or restricted. Unmet compliance requirements, including a hold nobody answered, can also end in a refund. Fiat refunds reach the payer once the banking network returns the funds, and fees may apply."
  - q: "Can a US virtual account receive SEPA, Pix, or RTP payments?"
    a: "Not at BlindPay. A US virtual account receives USD over ACH, wire, and SWIFT, depending on the account type. It has no IBAN, so SEPA payers need the SWIFT details instead, and Pix is a Brazilian rail with its own instructions. RTP payins go through BlindPay's shared memo-code account, not the dedicated account, even when the customer has an approved virtual account."
  - q: "Why did less money arrive than the payer sent?"
    a: "On wires, and SWIFT payments in particular, banks in the chain can deduct their own fees before the money lands. With the SHA charge option, the payer covers their own bank and the beneficiary absorbs intermediary and receiving fees. With BEN, every fee comes out of the amount. Ask the payer for the MT103, which shows the charge code, and book the gap as a bank fee."
---

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.

## Key takeaways

- ACH and wire deposits can take up to 5 business days, and anything sent after the cut-off starts counting from the next business day.
- A deposit `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.
- Returns usually trace back to details that don't match: a wrong account number, a beneficiary name that isn't the account holder, or a closed account.
- A US virtual account takes USD over ACH, wire, and SWIFT. Not SEPA, not Pix, and at BlindPay, not RTP.
- To find a missing wire, ask the payer for the bank reference: the IMAD for a domestic wire, the UETR for SWIFT.

## What usually goes wrong with a virtual account deposit?

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](/resources/more/what-is-a-virtual-account).

## Why hasn't the deposit arrived yet?

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](/docs/kb/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](/docs/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.

## Which statuses will a virtual account deposit go through?

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](/docs/learn/webhooks-events)). Signature checks and duplicate handling are in [stablecoin API webhooks](/resources/more/stablecoin-api-webhooks-reconciliation).

## Why is a deposit on hold?

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](/docs/kb/cut-off-times#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](/docs/kb/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](/docs/kb/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](/resources/more/virtual-account-requirements-kyc-kyb) covers what the review looks at.

## Why do deposits get returned to the sender?

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.

- **Wrong account or routing number.** ACH returns carry a reason code: R03 means the receiving bank couldn't locate the account, R04 means the account number is invalid, R02 means it's closed. A wire with a bad account number comes back the same way, just slower.
- **Beneficiary name doesn't match.** A named virtual account is in your customer's name. The payer should use that exact name as the beneficiary, not your platform's brand or a trading nickname. Receiving banks can reject wires where the name and the account don't line up.
- **The account isn't live, or isn't anymore.** A BlindPay virtual account has no rail numbers until it's approved, so any details a payer has from before approval are wrong. Payments to an account that's closed or restricted fail or get refunded.
- **Compliance requirements aren't met.** This includes the hold from the section above where nobody answered the RFI.
- **The payer used a rail the account doesn't take.** RTP isn't one: at BlindPay, no virtual account carries an RTP rail, and an `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](/docs/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.

## How do you trace a missing wire or SWIFT payment?

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.

1. **Confirm the window has passed.** Up to 5 business days for ACH, wire, and SWIFT, counted from the first business day after the cut-off.
2. **Check the details against the right rail.** The account object carries separate ACH and wire details. A payer who copied the ACH numbers into a wire form, or the reverse, may have sent the money somewhere else.
3. **Get the reference.** For ACH, the 15-digit trace number. For a domestic wire, the Fedwire IMAD (Input Message Accountability Data). For SWIFT, the UETR, a 36-character reference that follows a payment end to end.
4. **Ask for the MT103 on SWIFT payments.** It shows the beneficiary name (field 59), the amount and currency, the charge code (field 71A: OUR, SHA, or BEN), and the intermediary banks.
5. **Have the payer's bank trace it.** With the UETR, the sending bank can see which bank in the chain is holding the payment and why.
6. **Send everything to your provider.** Include the virtual account id, the expected amount, the date sent, and the reference.
7. **If it was returned, resend with corrected details** once the return has credited the payer.

Where the days go on a SWIFT payment, hop by hop, is in [why are cross-border payments slow](/resources/more/why-are-cross-border-payments-slow).

## What does a held SWIFT deposit look like, start to finish?

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.

1. **Day 0.** The client's bank sends the payment late in the afternoon, so it starts moving the next business day.
2. **Day 3.** An intermediary bank deducts 30 USD. 4,770 USD lands on the virtual account. The payin is created (`payin.new`) and moves to `processing`.
3. **Day 3, an hour later.** Monitoring flags it: first payment from this sender, and about four times the customer's usual deposit. The payin goes `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](/resources/more/virtual-account-fees).

## Where does BlindPay fit?

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](/docs/virtual-accounts), and the flow from bank deposit to wallet is in [accept bank transfers and settle in stablecoins](/resources/more/accept-bank-transfers-settle-in-stablecoins).

## What to do next

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.*
