Web3 API (EVM)
Integrate Merso using Web3 for NFT purchases with tokens or cryptocurrencies.
Overview
This page shows you how to integrate Merso using Web3. This means that your players will pay for the NFT using tokens or cryptocurrencies.
Integration Overview
The Merso API provides three core endpoints for game integration:
-
→
/healthAPI health check -
→
/merso-user-approvalApprove ERC20 token spending -
→
/merso-buy-tokenPurchase NFT using Merso System
Web3 API Endpoints
1. Health Check
Endpoint: GET /health
Purpose: Verify API connectivity and status
Request:
curl -X GET https://api3.dev.merso.io/health
Response:
{
"status": "ok",
"timestamp": "2026-01-05T12:00:00.000Z"
}
JavaScript Example:
async function checkHealth() {
const response = await fetch('https://api3.dev.merso.io/health');
const data = await response.json();
console.log('API Status:', data.status);
}
2. User Approval
Endpoint: POST /merso-user-approval
Purpose: Approve Merso System to spend user's ERC20 tokens. You can choose between PNPL or Upfront approve.
Request:
curl -X POST https://api3.dev.merso.io/merso-user-approval \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-d '{
"userAddress": "0x...",
"userEmail": "player@example.com",
"tokenPrice": "1000000000000000000",
"collectionAddress": "0x...",
"paymentMode": "BNPL",
"chainId": 137,
"tokenAddress": "0x..."
}'
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
userAddress |
string | Yes | User's wallet address |
userEmail |
string | Yes | User's in-game email |
tokenPrice |
string | Yes | Amount to approve (in wei) |
collectionAddress |
string | Yes | NFT collection contract address |
paymentMode |
string | No | Payment mode: "BNPL" or "UPFRONT". Default: "BNPL" |
chainId |
int | No | EVM chain ID. Uses default from game registration if not provided |
tokenAddress |
string | No | ERC-20 token contract address. Uses default from game registration if not provided |
Response:
{
"success": true,
"txData": {
"to": "0x...",
"from": "0x...",
"data": "0x...",
"gasPrice": "50000000000",
"nonce": 42,
"value": "0"
}
}
JavaScript Example:
async function approveTokenSpending(userAddress, userEmail, tokenPrice, collectionAddress) {
try {
const response = await fetch('https://api3.dev.merso.io/merso-user-approval', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${jwtToken}`
},
body: JSON.stringify({
userAddress,
userEmail,
tokenPrice,
collectionAddress,
paymentMode: 'BNPL'
})
});
const approvalData = await response.json();
if (!approvalData.success) {
throw new Error('Approval API returned error');
}
// Execute approval transaction
const approvalTx = await signer.sendTransaction({
to: approvalData.txData.to,
from: approvalData.txData.from,
data: approvalData.txData.data,
gasPrice: approvalData.txData.gasPrice,
nonce: approvalData.txData.nonce,
value: approvalData.txData.value
});
await approvalTx.wait();
console.log('Approval confirmed:', approvalTx.hash);
} catch (error) {
console.error('Approval failed:', error);
}
}
3. Buy Token with Merso
Endpoint: POST /merso-buy-token
Purpose: Purchase NFT using Merso functionality. You can choose between PNPL or Upfront payment.
Request:
curl -X POST https://api3.dev.merso.io/merso-buy-token \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-d '{
"userAddress": "0x...",
"tokenId": "123",
"tokenPrice": "1000000000000000000",
"collectionAddress": "0x...",
"paymentMode": "BNPL",
"chainId": 137,
"tokenAddress": "0x..."
}'
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
userAddress |
string | Yes | User's wallet address |
tokenId |
string | Yes | NFT token ID to purchase |
tokenPrice |
string | Yes | Total price in wei |
collectionAddress |
string | Yes | NFT collection contract address |
paymentMode |
string | No | Payment mode: "BNPL" or "UPFRONT". Default: "BNPL" |
chainId |
int | No | EVM chain ID. Uses default from game registration if not provided |
tokenAddress |
string | No | ERC-20 token contract address. Uses default from game registration if not provided |
Response:
{
"success": true,
"txData": {
"to": "0x...",
"from": "0x...",
"data": "0x...",
"gasPrice": "50000000000",
"nonce": 43,
"value": "0"
}
}
JavaScript Example:
async function buyNFTWithMerso(userAddress, tokenId, tokenPrice, collectionAddress, paymentMode, tokenAddress, chainId) {
try {
const buyResponse = await fetch('https://api3.dev.merso.io/merso-buy-token', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${jwtToken}`
},
body: JSON.stringify({
userAddress,
tokenId,
tokenPrice,
collectionAddress,
paymentMode,
tokenAddress,
chainId
})
});
if (!buyResponse.ok) {
throw new Error('Buy API request failed');
}
const buyData = await buyResponse.json();
// Execute buy transaction
const buyTx = await signer.sendTransaction({
to: buyData.txData.to,
from: buyData.txData.from,
data: buyData.txData.data,
gasPrice: buyData.txData.gasPrice,
nonce: buyData.txData.nonce,
value: buyData.txData.value
});
// Wait for buy transaction to be mined
await buyTx.wait();
console.log('Buy transaction confirmed:', buyTx.hash);
} catch (error) {
console.error('NFT purchase failed:', error);
}
}
Integration Flow
Complete Purchase Flow
The complete flow involves two steps: first approve the token spending, then execute the purchase.
async function completePurchaseFlow(walletAddress, tokenId, tokenPrice, collectionAddress, paymentMode, tokenAddress, chainId) {
try {
// Step 1: Call API for approval transaction
const approvalResponse = await fetch('https://api3.dev.merso.io/merso-user-approval', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${jwtToken}`
},
body: JSON.stringify({
userAddress: walletAddress,
userEmail: userEmail,
tokenPrice: tokenPrice,
collectionAddress: collectionAddress,
paymentMode: paymentMode,
tokenAddress: tokenAddress,
chainId: chainId
})
});
const approvalData = await approvalResponse.json();
if (!approvalData.success) {
throw new Error('Approval API returned error');
}
// Execute approval transaction
const approvalTx = await signer.sendTransaction({
to: approvalData.txData.to,
from: approvalData.txData.from,
data: approvalData.txData.data,
gasPrice: approvalData.txData.gasPrice,
nonce: approvalData.txData.nonce,
value: approvalData.txData.value
});
// Wait for approval transaction to be mined
await approvalTx.wait();
console.log('Approval transaction confirmed:', approvalTx.hash);
// Step 2: Call API for buy transaction
const buyResponse = await fetch('https://api3.dev.merso.io/merso-buy-token', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${jwtToken}`
},
body: JSON.stringify({
userAddress: walletAddress,
tokenId: tokenId,
tokenPrice: tokenPrice,
collectionAddress: collectionAddress,
paymentMode: paymentMode,
tokenAddress: tokenAddress,
chainId: chainId
})
});
if (!buyResponse.ok) {
throw new Error('Buy API request failed');
}
const buyData = await buyResponse.json();
if (!buyData.success) {
throw new Error('Buy API returned error');
}
// Execute buy transaction
const buyTx = await signer.sendTransaction({
to: buyData.txData.to,
from: buyData.txData.from,
data: buyData.txData.data,
gasPrice: buyData.txData.gasPrice,
nonce: buyData.txData.nonce,
value: buyData.txData.value
});
// Wait for buy transaction to be mined
await buyTx.wait();
console.log('Buy transaction confirmed:', buyTx.hash);
} catch (err) {
console.error('Transaction failed:', err.reason || err.message || 'Unknown error');
}
}