Deposits

Create deposit workflows for receiving any crypto in your app

⚠️

IMPORTANT: Deposits is currently available for private beta testing. Login here: https://moonpay.dev.hel.io/ (devnet) or https://moonpay.hel.io/ (mainnet) and use the following query parameter: ?permission=deposit.

Let users fund your app with any crypto, ideal for gaming deposits, embedded wallets and trading apps. This works via unique, self-custodial deposit addresses that are securely generated and identifiable per customer and session.

How It Works

  • Set up a Deposit in the MoonPay Commerce dashboard
  • Generate unique customer deposit IDs via API
  • Serve the deposit widget in your app via iframe/API
    • User copies/scan the wallet QR code to deposit their crypto of choice
  • MoonPay Commerce auto-bridges/swaps the crypto to your preferred currency & recipient wallet
  • Use webhooks to confirm deposits on your backend and credit the deposit to your customer's account
  1. Set Up a Deposit ID

Login to the MoonPay Commerce dashboard, create a payment and select Deposits as the payment type.

  • Deposit name - Set a name for the deposit. You can also enable options such as “Deposit with card” and email notifications for successful deposits.
  • Recipient currency – The currency in which you want to receive the payment
  • Test customer deposit session - Use the prebuilt UI in step 2 to generate a test customer deposit session by defining a customer ID and recipient wallet
  • Theming - Go to Settings -> Merchant Settings to theme your deposit widget
  1. Create Customer Deposit via the API

Once you’ve created a Deposit ID, you can generate your API keyin the dashboard.
Use it to programmatically create and serve unique customer deposit sessions via the deposit API endpoint. When creating customer deposits, specify a unique customer identifier, recipient wallet, and (optionally) an additionalJson payload.

Example Request:

curl --request POST \
  --url "https://api.hel.io/v1/deposit-customers/api-key?apiKey=YOUR_PUBLIC_KEY" \        
  --header 'Authorization: Bearer YOUR_PRIVATE_KEY' \  
  --header 'Content-Type: application/json' \           
  --data '{
    "customerId": "<customer-identifier>", // The ID you set for the customer
    "depositId": "68f23471cff6f1f4c16cb7c8", // ID of the deposit
    "recipientPublicKeys": [ // Recipient public key
      "Gvga5AysVCokomFstCDJRmNjLFnJt7VkmqxXJVgfKLGj"
    ],
    "additionalJSON": "{\"createdFromTempDemoUi\": true}" // Optional metadata
  }'

Example Response:

{
    "id": "68f2348ecff6f1f4c16cb7e1", // Unique identifier for this transaction or operation
    "deposit": "68f23471cff6f1f4c16cb7c8", // Reference ID of the related deposit
    "token": "acac3ec9-f8f6-4128-8159-a91e418e2581", // API or session token used for authentication
    "customerId": "<customer-identifier>", // Unique identifier of the customer
    "recipientPublicKeys": [ // Array of recipient public keys
        "Gvga5AysVCokomFstCDJRmNjLFnJt7VkmqxXJVgfKLGj"
    ]
}
  1. Serve the Deposit UI in Your App via Iframe

Embed the deposit widget using the HTML snippet below. It lets users deposit crypto or pay by card directly on your site without leaving your app.

<iframe
  allow="clipboard-write"
  style="width:420px; height:260px;"
  src="https://moonpay.hel.io/embed/deposit/acac3ec9-f8f6-4128-8159-a91e418e2581"
/>

Replace the token at the end of the src URL with your own token returned when creating the customer deposit via the API (e.g. acac3ec9-f8f6-4128-8159-a91e418e2581) to render the correct deposit widget.

Callbacks

Our deposit widget instantly notifies your app of key events, deposit_completed, deposit_error, and deposit_height_changed, so you can respond in real time without ever reloading the page.

EventPayloadWhen it fires
deposit_completed{} (empty object)Deposit finished successfully
deposit_error{ message: string }Something went wrong
deposit_height_changed{ height: number } (pixels)The widget needs a new height (e.g. after a step change)
  1. Use Webhooks to Confirm Deposits on Your Backend

You can create a webhook to listen for customer deposit events using the curl request below.

curl --request POST \
  --url "https://api.hel.io/v1/webhook/deposit/api-key?apiKey=YOUR_PUBLIC_KEY" \        
  --header 'Authorization: Bearer YOUR_PRIVATE_KEY' \  
  --header 'Content-Type: application/json' \           
  --data '{
    "name": "string",
    "depositId": "string",
    "targetUrl": "string"
  }'

Listen to the webhook payload, which includes details such as customerId, amount received, fees, and amount sent (if you choose to credit the full amount and absorb the fees). Use the Get Deposit functions to query this data via the API for all transactions or by customer token.

Supported Chains and Currencies

These are the supported currencies for each blockchain network. Users can choose their preferred network and currency when making a deposit. Deposited funds will be bridged and swapped into your specified recipient currency.

ChainSupported Currencies
SolanaSOL, USDC, USDT
Ethereum (EVM)ETH, USDC, USDT
Polygon (EVM)POL, USDC, USDT
Base (EVM)ETH, USDC, USDT
Binance Smart Chain (EVM)BNB, USDT
BitcoinBTC
Arbitrum (EVM)ETH, USDC, USDT

*You can request support for any currency on EVM & Solana. Additional chains coming soon including Tron, Ton, SUI and more.


User FAQs

What is a deposit address?

It's your unique crypto wallet address where you can send funds. Deposits are swapped/bridged to the correct currency, and then credited to your account balance.

How do I use crypto deposits?

  • Select your token and network.
  • Copy the address or scan the QR code.
  • Paste it into your wallet or exchange withdrawal page.
  • Enter your amount (must meet the minimum) and select the correct currency.
  • Double-check the wallet address and currency, then confirm.
  • Track your transfer in the widget, most transfers arrive within 30 seconds (except BTC which takes 20-30 mins).

What is price impact and slippage?

Price impact and slippage represent the estimated difference between the market price when you initiate the deposit and the actual conversion rate when your transaction is processed. This typically ranges from 0.1% to 1% and varies based on market volatility and network congestion. You might also pay a small gas fee.

Do I always need to send tokens to cover gas?

No, MoonPay covers gas fees for SPL & ERC-20 tokens. For example, you can send USDC on Solana or Ethereum without needing to send SOL or ETH.

Are there deposit limits?

Yes. Minimums are $5 on Solana and EVM L2s, and $25 on Ethereum and Bitcoin. No maximums. If you send less, you can top up to reach the minimum.

Can I reuse the same deposit address?

It depends on the app you're funding, addresses are customer ID specific. Always use the one shown in your current widget.

What should I do if my deposit hasn't arrived?

First, you can always verify the transaction on the blockchain explorer using your deposit wallet address. Check that you sent to the correct address and used the right network. If the transaction is confirmed on the blockchain but hasn't appeared in your account after the expected processing time, wait a short time or contact support with your wallet address.