iPay API Integration - Node.js (Express)
To integrate iPay's payment gateway into your Node.js-based forex CRM platform using Express, follow these steps to enable on-ramp cryptocurrency deposits.
1. Build the Payment URL
Construct a payment URL with required parameters to initiate the payment process.
// Build iPay payment URL (Node.js)
const { URLSearchParams } = require('url');
const apiKey = 'YOUR_API_KEY';
const depositId = '12345'; // From your CRM/database
const amount = 250; // Amount entered by client
const onRampProvider = 'provider1';
const defaultFiatCurrency = 'USD';
const params = new URLSearchParams({
apiKey,
customId: depositId,
onRampProvider,
defaultFiatAmount: amount.toString(),
defaultFiatCurrency
});
const baseUrl = 'https://us-central1-nfgdatabasedemo.cloudfunctions.net/app/api/invoice_external?';
const paymentUrl = baseUrl + params.toString();
console.log('Redirect user to:', paymentUrl);
// You might send this URL to your frontend or redirect the HTTP response.
After the customer completes the payment, they are sent to the redirect URL you registered with iPay. Do not credit the deposit on that page load — credit it only when the server-to-server callback below arrives.
2. Handle the Callback
Set up an Express route to handle the POST callback from iPay. Callbacks are sent for completed payments only, so there is no status field to check.
// Express route to handle iPay JSON callback
const express = require('express');
const app = express();
app.use(express.json()); // Parses JSON body
const SECRET_TOKEN = 'YOUR_SECRET_TOKEN'; // Optional secret token from iPay
app.post('/ipay-callback', (req, res) => {
// Verify the authorization header (if a secret token is configured)
if (SECRET_TOKEN && req.get('authorization') !== SECRET_TOKEN) {
return res.status(401).send('Invalid token');
}
const data = req.body || {};
if (data.customerID === undefined || data.transferedAmount === undefined) {
return res.status(400).send('Bad payload');
}
// Note the field spellings: transferedAmount (single r), transactionFeePrecent
const depositId = String(data.customerID); // your customId, returned as a string
const amountReceived = Number(data.transferedAmount); // net USDT delivered to your wallet
const txId = data.blockchainTxId;
// TODO: Update your CRM/database to mark depositId as completed with amountReceived.
// Make this idempotent: ignore the callback if depositId (or txId) was already credited.
console.log(`Deposit ${depositId} completed, amount: ${amountReceived} USDT (tx ${txId})`);
// Respond to acknowledge receipt
res.sendStatus(200);
});
// (Server listens on a port, etc.)
Explanation
- Building the URL: The
URLSearchParamsclass constructs the query string with parameters likeapiKeyandcustomId. ThepaymentUrlcan be sent to the frontend or used for redirection. - Handling the Callback: The Express route verifies the optional
authorizationheader, parses the JSON body, and credits the deposit identified bycustomerIDwithtransferedAmount. Respond with HTTP 200 to acknowledge. - Integration Notes: Verify that the callback endpoint is publicly reachable and can process iPay’s JSON payload — see Testing Your Payment Integration.