Web3 API
This page shows you how to integrate Merso using Web3. This means that your players with pay the NFT using tokens or cryptocurrencies.
🎯 Integration Overview
The Merso BNPL API provides three core endpoints for game integration:
/health- API health check/merso-user-approval- Approve ERC20 token spending/merso-buy-token- Purchase NFT using Merso BNPL
📋 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:
{
"success": true,
"message": "Hello World, Merso BNPL Backend",
}JavaScript Example:
async function checkAPIHealth() {
try {
const response = await fetch(`https://api3.dev.merso.io/health`, {
method: 'GET',
headers: headers
});
const data = await response.json();
console.log('API Status:', data.status);
return data;
} catch (error) {
console.error('Health check failed:', error);
}
}2. User Approval
Endpoint: POST /merso-user-approval
Purpose: Approve Merso BNPL to spend user's ERC20 tokens
Request :
curl -X POST "https://api3.dev.merso.io/merso-user-approval" \
-H "Authorization: Bearer <your_token>" \
-H "Content-Type: application/json" \
-d '{
"userAddress": "VALID_USER_ADDRESS",
"userEmail": "user@email.com",
"tokenPrice": "PRICE_IN_WEI",
"collectionAddress": "YOUR_GAME_ERC721_ADDRESS"
}'Parameters:
userAddress(string): User's wallet addressuserEmail(string): User's in-game emailamount(string): Amount to approve (in wei)
Response:
{
"success": true,
"txData": {
"to": "YOUR_GAME_ERC20_ADDRESS",
"from": "VALID_USER_ADDRESS",
"data": "0xa9059cbb000000000000000000000000...",
"gasPrice": "20000000000",
"nonce": 5,
"value": "0"
},
}JavaScript Example:
async function approveTokens(userAddress, userEmail, tokenPrice, collectionAddress) {
try {
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: userAddress,
userEmail: userEmail,
tokenPrice: tokenPrice,
collectionAddress: collectionAddress
}),
}
);
if (!approvalResponse.ok) {
throw new Error("Approval API request failed");
}
const approvalData: ApiResponse = await approvalResponse.json();
// 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();
} catch (error) {
console.error('Approval failed:', error);
throw error;
}
}3. Buy Token with Merso
Endpoint: POST /merso-buy-token
Purpose: Purchase NFT using BNPL functionality
Request:
curl -X POST "https://api3.dev.merso.io/merso-buy-token" \
-H "Authorization: Bearer <your_token>" \
-H "Content-Type: application/json" \
-d '{
"userAddress": "VALID_USER_ADDRESS",
"tokenId": "1",
"tokenPrice": "PRICE_IN_WEI",
"collectionAddress": "YOUR_GAME_ERC721_ADDRESS"
}'Parameters:
userAddress(string): User's wallet addresstokenId(string): NFT token ID to purchasetokenPrice(string): Total price in weicollectionAddress(string): NFT collection contract address
Response:
{
"success": true,
"txData": {
"to": "YOUR_BNPL_ADDRESS",
"from": "VALID_USER_ADDRESS",
"data": "0x...",
"gasPrice": "20000000000",
"nonce": 6,
"value": "0"
},
}JavaScript Example:
async function buyNFTWithMerso(userAddress, tokenId, tokenPrice, collectionAddress) {
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: userAddres,
tokenId: tokenId,
tokenPrice: tokenPrice,
collectionAddress: collectionAddress
})
});
if (!buyResponse.ok) {
throw new Error("Buy API request failed");
}
const buyData: ApiResponse = 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();
} catch (error) {
console.error('NFT purchase failed:', error);
throw error;
}
}🔄 Integration Flow
Complete Purchase Flow
const handleBuy = async (tokenId: number, userEmail: string, price: string) => {
if (!window.ethereum || !walletAddress) return;
setIsLoading(true);
setError("");
try {
const provider = new ethers.BrowserProvider(window.ethereum as any);
const signer = await provider.getSigner();
const tokenPrice = ethers.parseEther(price).toString();
// Step 1: Call your 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: YOUR_ERC721_ADDRESS,
}),
}
);
if (!approvalResponse.ok) {
throw new Error("Approval API request failed");
}
const approvalData: ApiResponse = 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 your 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: MOCK_ERC721_ADDRESS,
}),
}
);
if (!buyResponse.ok) {
throw new Error("Buy API request failed");
}
const buyData: ApiResponse = 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: any) {
setError(
"Transaction failed: " +
(err?.reason || err?.message || "Unknown error")
);
console.error(err);
}
setIsLoading(false);
};🪄 Optional endpoints
Endpoint: GET /user-loans
Purpose: Retrieves loan information for a specific user
Request:
curl -X GET "https://api3.dev.merso.io/user-loans?userEmail=USER_EMAIL" \
-H "Authorization: Bearer <your_token>"Parameters:
userId(string): User's ID
Response:
{
"loans": [
{
"id": "67829bea-00ef-45eb-bc23-0d6798e048f5",
"user_id": "USER_ID",
"collection_id": "19d210ae-5836-4cf0-ad7a-8d8a6b0f08b3",
"nft_id": "nftCromo2",
"initial_payment_usd": 250,
"splits_left_no": 4,
"price_usd": 500,
"paid_status": 1,
"game_id": "e6d8a143-3d70-45e2-9e4c-75ff7805e0fd",
"initial_splits_payments": 2,
"initial_payment_token": 2500000000000000000,
"price_token": 5000000000000000000,
"wallet_address": "0x1234567890ABCDEF1234567890ABCDEF12345678",
"created_at": "2025-07-28T08:02:57.744Z",
"paid_date": "2025-07-29T05:00:54.838Z"
}
]
}Example Usage
Here's an example of how you can call the GET /user-loans endpoint using JavaScript:
const fetchUserLoans = async (userId, jwtToken) => {
try {
const response = await fetch(`https://api3.dev.merso.io/user-loans?userEmail=${userEmail}`, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${jwtToken}`
}
});
if (!response.ok) {
throw new Error(`Error: ${response.statusText}`);
}
const data = await response.json();
console.log('User Loans:', data);
return data;
} catch (error) {
console.error('Failed to fetch user loans:', error);
throw error;
}
};
// Example usage
const userEmail = 'USER_EMAIL';
const jwtToken = 'YOUR_JWT_TOKEN';
fetchUserLoans(userId, jwtToken)
.then(loans => {
console.log('Loans data:', loans);
})
.catch(error => {
console.error('Failed to get loans:', error);
});Last updated