Integration Guide
Please read the below guide carefully and work with the MoonPay Product and Engineering team to help you answer questions.
Step One: Choose Supported Geographies
Today, MoonPay's Embedded Balances product supports GBP, EUR and USD Balances. Embedded Balances does not yet support multi currency accounts, meaning UK users can use GBP accounts, European users can use EUR accounts, and users from the United States can use USD accounts. We recommend you support all three geographies, as this will give you the most holistic experience; MoonPay handles most of the complexity behind these currencies and geographies.
Step Two: Build Balance Entry Points
To allow end-users to start their experience, you'll need to build entry points to Balances, Balance Top Ups, and Balance Withdrawals within your experience. These should be buttons on your home page labeled 'Top Up' and 'Withdraw'. These buttons should only be available in the geographies you choose on Step One, and you should look to ensure the withdraw button is not available for users with no Balance.
Top Up:: Clicking Top Up should generate an iFrame via this URL (https://buy.moonpay.com/balance/deposit), which can be embedded in your experience, loaded in a new tab, or loaded in a web view.
Parameter | Description |
---|---|
apiKey (required) | Your publishable API key. This is used to assign customers and transactions to your MoonPay account. |
externalCustomerID (required) | An identifier you would like to associate with the customer. This identifier will be present whenever we pass you customer data, allowing you to match our data with your own existing customer data. |
baseCurrencyCode | The code of the Fiat currency your user would like to top up. You can pass usd gbp or eur |
baseCurrencyAmount | A positive integer representing how much fiat the customer wants to top up. |
Withdraw:: Clicking Withdraw should generate an iFrame via this URL (https://sell.moonpay.com/balance/withdraw), which can be embedded in your experience, loaded in a new tab, or loaded in a web view. Please note that to create a smooth user experience, before passing baseCurrencyAmount
you should validate the user has sufficient available Balance to withdraw. Once authenticated, MoonPay will validate this ourselves, but catching errors earlier in the funnel will lead to a better user experience.
Parameter | Description |
---|---|
apiKey (required) | Your publishable API key. This is used to assign customers and transactions to your MoonPay account. |
externalCustomerID (required) | An identifier you would like to associate with the customer. This identifier will be present whenever we pass you customer data, allowing you to match our data with your own existing customer data. |
baseCurrencyCode | The code of the Fiat currency your user would like to withdraw. You can pass usd gbp or eur |
baseCurrencyAmount | A positive integer representing how much fiat the customer wants to withdraw |
Step Three: Build Beautiful Balance Top Up and Balance Withdrawal Experiences
To create a beautiful top up and withdrawal experience, you may want to make use of our Webhooks to update users in your wallet or application, or to build your own transaction tracking states for users.
Balance Transaction Created
{
type: "balance_transaction_created",
body: {
transactionId: "123",
timestamp: "2024-01-01T12:00:00Z",
currencyCode: "USD",
transactionType: "deposit",
status: "completed",
amount: 100.00,
customerId: "123"
}
}
Balance Transaction Updated
{
type: "balance_transaction_updated",
body: {
transactionId: "123",
timestamp: "2024-01-01T12:00:00Z",
currencyCode: "USD",
transactionType: "deposit",
status: "completed",
amount: 100.00,
customerId: "123"
}
}
Balance Transaction Failed
{
type: "balance_transaction_failed",
body: {
transactionId: "123",
timestamp: "2024-01-01T12:00:00Z",
currencyCode: "USD",
transactionType: "deposit",
status: "failed",
amount: 100.00,
customerId: "123",
failureReason: "some_reason"
}
}
Step Four: Generate Private & Public Key Pair and Upload it on MoonPay Dashboard
- Generate your key pair using these commands
openssl genrsa -out private_key.pem 2048
openssl rsa -in private_key.pem -pubout -out public_key.pem
- Save your private key and don't share it with anyone; we will never ask you to share your private key.
- Login to MoonPay Dashboard
- Go to Developers Tab and click on API Keys
- Find Public Key field on the page, copy the Public Key content that you generated in Step 1, and paste it in.
- Press the Upload button to upload your Public Key.
Step Five: Sign your request payloads
Before sending out any request to Embedded Balances API, you must sign your request payload using the Private Key you generated at the previous step.
Here's an example of how we expect you to sign your payloads and send a request.
const fs = require('fs');
const crypto = require('crypto');
const axios = require('axios');
const { DateTime } = require('luxon');
const privateKey = fs.readFileSync('./private_key.pem', 'utf8');
const publishableKey = 'pk_live_vDksS3d4tkdF4FHbajFW8OC9AQ2GIz'
const timestamp = DateTime.now().toMillis();
const queryString = `/v1/balances/customers/[email protected]/balance?apiKey=×tamp=${timestamp}`;
const sign = crypto.createSign('SHA256');
sign.update(queryString);
const signature = sign.sign(privateKey, 'base64');
axios
.get(`https://api.moonpay.com${queryString}`, {
headers: {
'x-signature': signature,
},
})
.then((res) => {
console.log(res.data);
});
We expect you to pass down your Publishable Key and a Timestamp in milliseconds as Query Parameters.
The Signed Request is only valid for 5 minutes; after that, it will expire to prevent replay attacks.
Step Six: Send Out Requests to Embedded Balances API
You can retrieve a users balance by calling the endpoint below with the users externalCustomerID
passed in as a parameter. You can see an example:
Parameter | Description |
---|---|
apiKey (required) | Your publishable API key. This is used to assign customers and transactions to your MoonPay account. |
externalCustomerID (required) | An identifier you would like to associate with the customer. This identifier will be present whenever we pass you customer data, allowing you to match our data with your own existing customer data. |
timestamp (required) | The timestamp of the request in milliseconds. |
x-signature (required header) | Signature you have generated with your request payload and private key. |
Example Request
curl --request GET \\
--url <https://api.moonpay.com/v1/balances/customers/:externalCustomerId/balance?apiKey=pk_123×tamp=2934823748273> \\
--header 'accept: application/json'
--header 'x-signature: signature'
{
"balance": 500,
"currencyCode": "eur"
}
Using this endpoint, you can retrieve the transaction history
Parameter | Description |
---|---|
apiKey (required) | Your publishable API key. This is used to assign customers and transactions to your MoonPay account. |
externalCustomerID (required) | An identifier you would like to associate with the customer. This identifier will be present whenever we pass you customer data, allowing you to match our data with your own existing customer data. |
timestamp (required) | The timestamp of the request in milliseconds. |
limit | The limiter to amount of customer balance transactions you retrieve. |
offset | The value you can pass as the pagination offset. |
x-signature (required header) | Signature you have generated with your request payload and private key. |
curl --request GET \\
--url <https://api.moonpay.com/v1/balances/customers/:externalCustomerId/transactions?apiKey=pk_123×tamp=148378537485> \\
--header 'accept: application/json'
--header 'x-signature: signature'
{
transactions: [
{
id: '123',
amount: 1000,
currencyCode: 'USD',
type: 'deposit',
status: 'completed',
createdAt: new Date('2023-01-01T12:00:00Z'),
updatedAt: new Date('2023-01-02T15:30:00Z'),
},
{
id: '456',
amount: 500,
currencyCode: 'USD',
type: 'withdrawal',
status: 'completed',
createdAt: new Date('2023-01-02T15:30:00Z'),
updatedAt: new Date('2023-01-02T15:30:00Z'),
}
],
count: 2,
hasNext: false,
hasPrev: false
};
Step Six: Retrieve a users Balance transaction history
Using this endpoint you can retrieve single transaction
Parameter | Description |
---|---|
apiKey (required) | Your publishable API key. This is used to assign customers and transactions to your MoonPay account. |
balanceTransactionId (required) | An identifier we associate with a balance transaction. |
timestamp (required) | The timestamp of the request in milliseconds. |
x-signature (required header) | Signature you have generated with your request payload and private key. |
curl --request GET \\
--url <https://api.moonpay.com/v1/balances/transactions/:balanceTransactionId?apiKey=pk_123×tamp=437284718264736> \\
--header 'accept: application/json'
--header 'x-signature: signature'
{
id: '456',
amount: 500,
currencyCode: 'USD',
type: 'withdrawal',
status: 'completed',
createdAt: new Date('2023-01-02T15:30:00Z'),
updatedAt: new Date('2023-01-02T15:30:00Z')
}
Step Seven: Enable a 'Spend' with Balance experience.
In the current version of the MoonPay Embedded Balance product, all Buy Transactions happen within a MoonPay authenticated iFrame. As a prerequisite, you must have our On Ramp enabled here (instructions on how to do this are here https://moonpay.readme.io/docs/integrate-guide). You can also find instructions here on how to pass and prefill payment methods into On Ramp, and you should ensure as part of the paymentMethod
parameter you pass partner_balance
. If you are looking to display a quote to a user in your own interface, you can also call our getBuyQuote
endpoint and pass partner_balance
as your payment method to retrieve a quote.
Updated about 15 hours ago