Funding wallets
Privy makes it simple for your user to fund their wallets with a variety of assets, through our default fiat on-ramp integration with MoonPay. Using MoonPay, your users can purchase cryptocurrency via familiar payment methods including bank (ACH) transfer, credit/debit cards, and mobile payments like Google/Apple Pay.
To use MoonPay's fiat on-ramp in your app, follow the instructions below!
Fiat on-ramps are not one-size fits all; the best on-ramp provider for your app will vary based on your app experience and user base. Some considerations in choosing the right fiat on-ramp provider include:
- Token Support: On-ramp providers are required to obtain a license for each token they offer. Not all on-ramp providers will support all tokens. You can find the supported tokens in this integration here.
- Regional Support: On-ramp providers can only process purchases in select regions, and not all tokens may be supported in all regions. Make sure the on-ramp provider you integrate is appropriate for the geographies of your user base.
- Payment Methods: Different on-ramp providers support different payment methods, with varying degrees of payment success. MoonPay recommends that users purchase with a debit card, but your users may be more familiar with other methods.
- Purchase Minimums: MoonPay has strict minimums for cryptocurrency purchases. If your users regularly need to purchase low dollar-value assets (<30 USD), this integration may not be right for you.
If you'd like to use your own fiat on-ramp (e.g. other than MoonPay) that's better suited to your app's needs, you can easily do so! Follow this guide to integrate your own fiat on-ramp alongside Privy.
This feature is also compatible with embedded wallets!
1. Enable the MoonPay Fiat On-Ramp plugin for your app
In the Privy Console, select your app from the App Dropdown in the left sidebar and navigate to the Plugins page. Find the MoonPay Fiat On-Ramp plugin and click Request Access.
Once you've requested access, the Privy team will review your request and enable this plugin for your account. In order to comply with MoonPay's Know Your Business (KYB) policies, we may request additional information about your product.
After the Privy team has enabled the MoonPay Fiat On-Ramp plugin for your account, go back to the Plugins page; you will find a toggle where you previously saw the Request Access button. You can use this toggle to enable/disable the MoonPay Fiat On-Ramp for your app.
2. Invoking the on-ramp
Once you've enabled the MoonPay Fiat On-Ramp plugin for your app, there are two ways to invoke this flow for a user:
Directly
To invoke the on-ramp directly, first, find the desired wallet's ConnectedWallet
object from the useWallets
array:
const {wallets} = useWallets();
const wallet = wallets[0]; // Replace 0 with the index of the desired wallet
Then, use the object's fund
method to use the MoonPay fiat on-ramp to fund that wallet:
await wallet.fund({config: fundWalletConfig});
Once invoked, fund
will open a Privy modal that contains some introductory context about MoonPay and the purchase they are about to make.

Introductory screen for the MoonPay on-ramp flow.
Once the user clicks Continue in the screen above, they will be redirected to MoonPay in a new tab to complete their purchase. As part of this purchase:
- If the user does not already have a MoonPay account, they will need to create one within this tab, and go through identity verification. This is required by law. They may be asked for their SSN/EIN, home address, and/or a government-issued ID. This flow may also require your users to wait on manual approval by MoonPay and follow-up information gathering requests.
- If the user already has a MoonPay account and has completed their identity verification flow before, they will not need to re-complete this flow, and can immediately continue to their purchase.
While the user is completing their purchase in the MoonPay tab, the Privy modal will show a status indicator within your site indicating if the purchase is in progress, is awaiting authorization, is successful, or has failed.
Please note that purchases are not always instantaneous, and there may be some time before the user completes their purchase and the funds are available in their wallet.
3. Customizing the on-ramp flow
To better guide your user, you can provide a FundWalletConfig
object to tailor the on-ramp flow for your specific use case.
Within this object, you can provide the following fields to customize them (all optional):
FundWalletConfig Fields
Field | Description | Type |
---|---|---|
currencyCode | Indicates the cryptocurrency you'd like the user to purchase, and takes the form {TOKEN_SYMBOL}_{NETWORK_NAME_} (e.g. ETH_ETHEREUM for ETH on Ethereum Mainnet). If a currencyCode is set, the user can only purchase the set cryptocurrency. If no currencyCode is set, the user will see ETH on Ethereum Mainnet as the default currency to purchase, but can select any other cryptocurrency supported in their region. We recommend setting this parameter to ensure your user purchases the right token for your app. | See the currencyCode s table below. |
quoteCurrencyAmount | Indicates the amount of the currency specified by currencyCode that you'd like the user to purchase. If set, the user will not be able to edit this amount. | number |
paymentMethod | Indicates the payment method you'd like your user to use when completing their purchase. Supported paymentMethod s are listed on the right. | 'ach_bank_transfer' , 'credit_debit_card' , 'gbp_bank_transfer' , 'gbp_open_banking_payment' , 'mobile_wallet' , 'sepa_bank_transfer' , 'sepa_open_banking_payment' , 'pix_instant_payment' , 'yellow_card_bank_transfer' |
uiConfig.accentColor | Hex string indicating an accent color for MoonPay's fiat on-ramp UIs | string |
uiConfig.theme | Theme to use for MoonPay's fiat on-ramp UIs | 'light' , 'dark' |
currencyCode Options for the FundWalletConfig
These are the values you may use for the currencyCode
field of the FundWalletConfig
above. For ERC-20 tokens, the corresponding contract is linked in the token description below.
Please note that not all currencies are supported in all regions. You can find a list of unsupported regions within the US for each token below.
currencyCode | Description | Unsupported Regions |
---|---|---|
'AVAX_CCHAIN' | AVAX token on Avalanche's C-Chain network. | Hawaii, Louisiana, New York, Texas, US Virgin Islands |
'CELO_CELO' | CELO token on Celo network. | Hawaii, Louisiana, New York, Texas, US Virgin Islands |
'CUSD_CELO' | cUSD stablecoin on Celo network. | New York, Texas, US Virgin Islands |
'DAI_ETHEREUM' | Dai stablecoin on Ethereum mainnet. | Hawaii, New York, US Virgin Islands |
'ETH_ETHEREUM' | ETH token on Ethereum mainnet. | Hawaii, US Virgin Islands |
'ETH_ARBITRUM' | ETH token on Arbitrum network. | Hawaii, New York, US Virgin Islands |
'ETH_POLYGON' | ETH token on Polygon. | Hawaii, Louisiana, New York Texas, US Virgin Islands |
'FIL_FVM' | FIL token on Filecoin Virtual Machine. | None |
'MATIC_ETHEREUM' | MATIC token on Ethereum mainnet. | None |
'MATIC_POLYGON' | MATIC token on Polygon | Hawaii, Louisiana, New York, Texas, US Virgin Islands |
'USDC_ETHEREUM' | USDC stablecoin on Ethereum mainnet. | Hawaii, US Virgin Islands |
'USDC_ARBITRUM' | USDC stablecoin on Arbitrum network. | Hawaii, New York, Texas, US Virgin Islands |
'USDC_OPTIMISM' | USDC stablecoin on OP Mainnet. | Hawaii, Louisiana, New York, Texas, US Virgin Islands |
'USDC_POLYGON' | USDC stablecoin on Polygon network. | Hawaii, Louisiana, New York, Texas, US Virgin Islands |
'USDT_ETHEREUM' | USDT stablecoin on Ethereum mainnet. | Hawaii, New York, US Virgin Islands |
'USDT_POLYGON' | USDT stablecoin on Polygon network. | New York |
As an example, you might construct a FundWalletConfig
like below:
const fundWalletConfig = {
currencyCode: 'ETH_ETHEREUM', // Purchase ETH on Ethereum mainnet
quoteCurrencyAmount: 0.05, // Purchase 0.05 ETH
paymentMethod: 'credit_debit_card', // Purchase with credit or debit card
uiConfig: {accentColor: '#696FFD', theme: 'light'} // Styling preferences for MoonPay's UIs
}
You can then pass this FundWalletConfig
as an optional parameter to wallet.fund()
(for the direct on-ramp):
await wallet.fund({config: fundWalletConfig});
That's it! Your users can now fund their wallets via Privy's fiat on-ramp integration with MoonPay.
Want to test the fiat on-ramp in MoonPay's sandbox environment?
By default, using the MoonPay Fiat On-Ramp plugin as described above will use MoonPay's production environment.
If you'd like to use the sandbox environment for testing, simply update your PrivyProvider
's config
property as follows:
<PrivyProvider
appId='insert-your-privy-app-id'
config={{
...restOfYourConfig,
fiatOnRamp: {
useSandbox: true, // This defaults to false
},
}}
>
{/* your app's components/pages*/}
</PrivyProvider>
When testing in sandbox, note that:
- You should purchase an amount of cryptocurrency that corresponds to <200 USD. If the amount exceeds 200 USD, the transaction may fail.
- Do not input a real payment method. Instead, use one of MoonPay's test credit cards for your payment method
- Instead of completing an actual identity verification flow, you will be asked to choose between three options to simulate the flow: Approve, Final Rejection, and Request Additional Information.
- For sandbox, MoonPay will send different cryptocurrencies than they would in production:
- For ETH on Ethereum, MoonPay will send ETH on the Ethereum Goerli testnet.
- For ERC-20s on Ethereum, MoonPay will send its sample ERC-20 token on the Ethereum Goerli testnet.
- For tokens on L2s, MoonPay will send 0.001 ETH on the Ethereum Goerli testnet instead.
Please note that supported tokens and regions may vary between the production and sandbox environments.
Debugging failed transactions
When purchasing cryptocurrency with fiat payments, users may run into issues due to stringent regulations around digital asset purchases. For instance, MoonPay's identity verification provider may deem the user too high-risk to complete this transaction, or the user's bank may reject the transaction.
Please note that Privy is not a payment processor nor identity verification provider and has extremely limited visibility into these issues.
If your users are running into such issues, please have them contact MoonPay support. We are unable to directly assist with a resolution in these cases.