> For the complete documentation index, see [llms.txt](https://docs.swapper.finance/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.swapper.finance/deposit-methods/transfer-crypto.md).

# Transfer Crypto (QR)

**Key:** [`transferCrypto`](/widget-integration/configuration.md#supporteddepositoptions) · **UI:** "Buy with QR" / "Deposit with QR" · **Deposit `method`:** `smart_wallet` or `relay_deposit_address`

The QR flow lets a user fund your destination by **sending crypto to an address** — from any wallet or exchange, on any supported chain. There's no wallet to connect and nothing to sign in the widget: the user picks what they'll send, copies the address (or scans the QR code), and makes the transfer however they like. Swapper detects the deposit, swaps and bridges it, and delivers your destination token.

## What the user experiences

1. Chooses **Buy with QR** (or **Deposit with QR** with [`actionLabel: "deposit"`](/widget-integration/configuration.md#actionlabel)).
2. Picks the **token and network** they'll send from. The widget suggests USDC and, when possible, the same chain as your destination (a single-chain transfer is cheaper).
3. Sees a **deposit address and QR code**, the **minimum** to send ("Ensure you transfer min. … USD in USDC on Base") and the estimated fee. **More Details** shows the route.
4. Sends the tokens to that address from any wallet or exchange — possibly minutes later, or from another device.
5. The widget detects the deposit, shows its progress, and confirms when your destination token has arrived at `depositWalletAddress`.

The user can send any amount at or above the minimum; the swap runs on what actually arrives.

## Two kinds of deposit address

The QR shows one of two kinds of address, depending on what the user sends. The UX is the same; how the deposit is settled — and reported — differs.

### A smart wallet (`smart_wallet`)

The address is the user's own per-user **smart wallet** (account abstraction, via ZeroDev / EIP-7702). Its owner key is created in the widget and stays with the user; Swapper holds only a **scoped session key** with spending limits, which lets it swap what arrives into your destination token — and nothing else. Funds sent there sit in an address the user controls.

* **Recovery keys.** From **More Details → Recovery Keys** the user can reveal the 12-word recovery phrase of that address.
* **Fiat sweeps.** The same smart wallets also receive [card on-ramp](/deposit-methods/fiat-onramp.md) purchases that need a further swap; those produce two linked deposits (`onramp` + `smart_wallet`); make sure your accounting counts the flow **once**. See [Webhooks → Linking](/tracking-deposits/webhooks.md#linking-onramp--smart-wallet-deposit).

### A deposit address (`relay_deposit_address`)

The QR shows a **deposit address** issued for the route. When funds arrive there, they're swept, swapped and delivered to your destination. No smart wallet, session key or recovery phrase is involved.

* If such a deposit can't be completed, it's refunded **through Swapper support** rather than sent back to the sending address automatically — QR deposits often come from exchange withdrawals, where an automatic refund would go to the exchange's hot wallet. Ask the user for the hash of their transfer and open a ticket in [Discord](https://discord.gg/y8eevERxBz).
* [Custom contract calls](/widget-integration/custom-contract-calls.md) work here too: the deposit is first delivered to the user's smart wallet on the destination chain, which then runs your calls as a second step. You still receive a single deposit and a single webhook.

## When the authorization is created

On EVM, creating a smart-wallet authorization has a cost, so the widget only does it for users who actually open the widget. If you **preload** the widget hidden (via [`preloadSwapperModal` / `preloadSwapperEmbed`](/widget-integration/modal-and-embed.md) or [`deferSmartWalletAuth`](/widget-integration/iframe-sdk.md#preloading-and-deferred-authorization)), authorization is deferred until the widget is first revealed — everything else loads in the background so opening is still instant.

## Minimums and fees

* The minimum shown is the greater of your [`minDepositUsd`](/widget-integration/configuration.md#mindepositusd--maxdepositusd) (or your integrator minimum) and an estimate of the route's cost, so a deposit always covers its fees. Some chains have a fixed floor (e.g. Ethereum and Bitcoin).
* For a smart wallet the fee estimate is the cost of its swap (gas plus any cross-chain fee); for a deposit address it's the cost of filling the deposit.

## What your app receives

A [`transaction.completed` webhook](/tracking-deposits/webhooks.md) per deposit, with `flow: "transfer_crypto"` and:

* **Smart wallet** — `method: "smart_wallet"` and `providerData.type = "smart_wallet"`:

  ```json
  {
    "type": "smart_wallet",
    "authorizationId": "0x…-1-1782205341782",
    "executionId": "1782652045143-0x…",
    "smartWalletAddress": "0xbf642c3512b344517aa827864cc64723aa1d2ac0"
  }
  ```

  The deposit carries `fundingTxs` — every on-chain tx that funded the swap — and may carry `deposited` (what the user sent) alongside `source` (what entered the swap).
* **Deposit address** — `method: "relay_deposit_address"` and `providerData.type = "relay_deposit_address"` (with the `depositAddress` and the `depositor`). `depositTxHash` is the user's own transfer into the deposit address — the hash they'll quote to you.

See [Webhooks → Deposit methods](/tracking-deposits/webhooks.md#deposit-methods) for the full field list.

In the browser you also get a [`transaction_success` widget event](/tracking-deposits/widget-events.md) with `depositOption: "transferCrypto"`, including `txHash`, `explorerUrl`, `tokenSymbol`, `tokenAddress`, `chainId`, and `amountReceived` when known.

## Chaining actions after the swap

Attach [custom contract calls](/widget-integration/custom-contract-calls.md) to stake, wrap, or otherwise put the funds to work in the same flow. With a smart wallet they run in its swap; with a deposit address they run as the second step described above.

## Debugging a stuck deposit

If a deposit sits in the smart wallet and never executes, the usual suspects are a stuck delegation job, a sponsorship failure, an EIP-7702 authorization problem, or a transaction that reverts in simulation. Gather the `authorizationId`, `executionId`, `smartWalletAddress`, and funding tx hash and open a ticket in [Discord](https://discord.gg/y8eevERxBz). For a deposit address, send the address and the user's transfer hash.
