Integrating a custom fiat on-ramp into your app
Privy offers out of the box support for fiat on-ramp providers like Moonpay and Coinbase
here. If you’re looking to integrate a custom fiat on-ramp provider,
you can follow the instructions below.
- how to choose the right fiat on-ramp provider for your app
- how to integrate a fiat on-ramp provider
- a complete demo implementation of a fiat on-ramp integrated alongside Privy
Choosing a fiat on-ramp provider
To start, you’ll need to choose a fiat on-ramp provider that meets your app’s requirements. Different on-ramp providers vary in their support of:- different tokens (ETH, USDC, Dai, POL, etc.)
- different networks (Ethereum, Polygon, Optimism, etc.)
- different regions (US, Europe, Brazil, South Korea, India, etc.).
- different payment methods (credit cards, debit cards, ACH, instant ACH, etc. )
Integrating the provider
For the remainder of this guide, we will assume Moonpay is our chosen fiat on-ramp provider (though you should choose the provider that is best for your app). The overall integration shape is roughly the same across different providers, and generally looks like:- In your frontend, collect details about your user (wallet address, email, etc.) and the assets they want to purchase (which tokens, what network, amount, etc.). Make a request to your backend with these details.
- In your backend, once you receive the request from step (1), construct a fiat on-ramp URL for your user. Each provider will give you a base URL for a generic on-ramp flow, and you can tailor the flow to be specific to your user by setting the details from step (1) as query parameters. Send this URL back to your frontend.
- In you frontend, once you receive the URL from step (2), you can either redirect your user to that URL or embed it in an
iframe
within your site. Within the new page/iframe
, your user will complete their purchase flow and any required identity verification steps.
1. Collect information about the user’s on-ramp flow in your frontend
To start, we’ll add afundWallet
method to our frontend that collects information about our user and our desired on-ramp flow, and sends it to our backend.
In this example app, users login with their email address and create a Privy embedded wallet upon logging in. Thus, we can get the user’s email and wallet address from their user
object and include it in this request. This ensures the user doesn’t have to enter this manually when completing the on-ramp flow later.
Getting the email and wallet address of the user
iframe
. Thus, we can get the URL of the current page (window.location.href
) and include it in this request. This allows the on-ramp provider to redirect the user back to this page once they have completed their purchase.
Getting the URL of the current page
- If users of your app only ever need to pay gas on Ethereum mainnet, you can pre-populate the asset to be purchased to always be ‘eth’ and the network to always be ‘ethereum’.
- If your app is cross-chain and needs users to have different assets on different chains, you can instead surface UI elements to allow the user to select which asset and network they’d like to fund their wallet with.
When completing the on-ramp flow, your user will have to manually enter/select any information
that you do not pre-fill here (e.g. wallet address, which asset to purchase, etc.).
fundWallet
method to send this data to our backend, authorizing the request with the user’s Privy auth token.
Requesting the on-ramp URL from the server
fundWallet
parses the response returned by the server (we’ll implement this below) and returns the fiat on-ramp URL as a string.
2. Construct the on-ramp URL in your backend
Now, we’ll implement the logic in our backend to construct the fiat on-ramp URL based on the configuration we collected in step (1). In particular, we’ll implement aPOST /api/onramp
handler that receives the request from step (1) and responds with the on-ramp URL.
In our handler, we’ll start by parsing the request body for the user’s wallet address
, email
, and redirectUrl
. If you included additional information in your request (e.g. asset type, amount), you should parse the request body for those values as well.
Parsing the request body
Initializing the on-ramp with our base URL
Configuring our on-ramp via URL query parameters
Authorizing the on-ramp URL with a signature
Returning the on-ramp URL to the client
3. Redirect your user to the on-ramp URL in your frontend
With steps (1) and (2) completed, ourfundWallet
method in our front-end should now return a configured, authorized on-ramp URL where our user can complete their purchase.
Getting the on-ramp URL
Redirecting our user to complete the on-ramp flow
redirectUrl
we configured in steps (1) and (2). On this redirect, Moonpay will also append a transactionId
that we can optionally use to monitor the status of the user’s transaction.
If you redirect your user to the fiat on-ramp URL, as we have done here, we suggest that you show
them some introductory context about the fiat on-ramp (e.g. in a modal) provider and why they need
to purchase crypto for your app.
iframe
embedded within your site:
Embedding the on-ramp URL in an iframe
NFT Checkout
If your app needs users to fund their wallets specifically so they can purchase NFTs, you should consider integrating an NFT Checkout flow in addition to, or instead of, a generic fiat on-ramp flow. NFT checkout flows generally offer a smoother user experience, due to less rigid identity verification requirements, higher payment success rates, and clearer context about what the user gets by purchasing crypto. Many fiat on-ramp providers, including Moonpay and Sardine, offer NFT checkout integrations as well. The shape of this integration is much like that of the generic fiat on-ramp (outlined in this guide), but you will have to configure additional information about your NFT sale (contract address, token type, payments) in each provider’s dashboard. See each provider’s documentation for more details, or reach out with any questions.Demo integration
Check out our fiat on-ramp demo app to see an end-to-end integration of a fiat on-ramp alongside Privy. Take a look at the source code to see how the code snippets from this guide fit into a real app. This demo app uses a sandbox instance of Moonpay, and you should use certain test values when completing the purchase flow as a user:- When entering in payment details, do not use a real payment method. Use the test credit card listed here.
- When completing identity verification, you will not be prompted to actually submit identity documents (as you would in production). Instead, you will be able to choose whether you’d like to simulate a successful or failed identity verification.