JavaScript SDK
The official EPaySe JavaScript SDK is under development. Use the REST API directly with fetch or axios in the meantime.
SDK Under Development
@epayse/sdk) will be available via npm soon. The direct API examples below work with both Node.js and browser environments. JavaScript Integration
Native Fetch
Use the built-in Fetch API for server-side calls. No external HTTP libraries required.
Crypto Module
Node.js crypto module handles HMAC-SHA256 signatures and timing-safe comparison natively.
Full Stack
Server-side for API calls and HMAC signing, client-side for checkout redirects.
Create a Transaction (Node.js)
Create a payment transaction using Node.js with the native crypto and fetch APIs:
const crypto = require('crypto');
const API_KEY = 'your_api_key';
const SECRET_KEY = 'your_secret_key';
const BASE_URL = 'https://api.epayse.com/api/v1';
async function createTransaction(amount, currency, orderId) {
const timestamp = Math.floor(Date.now() / 1000).toString();
const nonce = crypto.randomBytes(16).toString('hex');
const payload = JSON.stringify({
amount,
currency,
orderId,
description: `Payment for ${orderId}`,
returnUrl: 'https://yoursite.com/payment/callback',
cancelUrl: 'https://yoursite.com/payment/cancel',
});
// Generate HMAC-SHA256 signature
const signatureString = timestamp + nonce + payload;
const signature = crypto
.createHmac('sha256', SECRET_KEY)
.update(signatureString)
.digest('hex');
const response = await fetch(`${BASE_URL}/transaction/create`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Api-Key-Id': API_KEY,
'X-Signature': signature,
'X-Timestamp': timestamp,
'X-Nonce': nonce,
},
body: payload,
});
const data = await response.json();
if (data.status === 'SUCCESS') {
return data.data.checkout_url;
}
throw new Error(data.message || 'Transaction creation failed');
}
// Usage
const checkoutUrl = await createTransaction(100.00, 'USD', 'ORD-001');
console.log('Redirect to:', checkoutUrl);Create a Refund
Issue full or partial refunds using the same HMAC authentication pattern:
async function createRefund(transactionId, amount, reason = '') {
const timestamp = Math.floor(Date.now() / 1000).toString();
const nonce = crypto.randomBytes(16).toString('hex');
const payload = JSON.stringify({
transactionId,
refundAmount: amount,
reason,
});
const signature = crypto
.createHmac('sha256', SECRET_KEY)
.update(timestamp + nonce + payload)
.digest('hex');
const response = await fetch(`${BASE_URL}/refund/create`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Api-Key-Id': API_KEY,
'X-Signature': signature,
'X-Timestamp': timestamp,
'X-Nonce': nonce,
},
body: payload,
});
return response.json();
}
// Full refund
await createRefund('01kbkzs3pdcdkjvsq2xb2j0ej3', 100.00, 'Customer request');
// Partial refund
await createRefund('01kbkzs3pdcdkjvsq2xb2j0ej3', 25.00, 'Partial refund');Verify Webhook Signature (Express.js)
Validate incoming webhook signatures using timing-safe comparison to prevent replay attacks:
const crypto = require('crypto');
function verifyWebhookSignature(payload, headers, secretKey) {
const signature = headers['x-signature'] || '';
const timestamp = headers['x-timestamp'] || '';
const nonce = headers['x-nonce'] || '';
// Reject if timestamp is older than 5 minutes
const age = Math.abs(Math.floor(Date.now() / 1000) - parseInt(timestamp));
if (age > 300) {
return false;
}
const expected = crypto
.createHmac('sha256', secretKey)
.update(timestamp + nonce + payload)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(expected),
Buffer.from(signature)
);
}
// Express.js webhook handler
app.post('/webhooks/epayse', express.raw({ type: 'application/json' }), (req, res) => {
const payload = req.body.toString();
if (!verifyWebhookSignature(payload, req.headers, SECRET_KEY)) {
return res.status(401).json({ error: 'Invalid signature' });
}
const event = JSON.parse(payload);
switch (event.event) {
case 'transaction.success':
// Handle successful payment
break;
case 'refund.completed':
// Handle completed refund
break;
}
res.json({ received: true });
});Browser Checkout Flow
On the client side, initiate payment by calling your backend API and redirecting to the EPaySe checkout page:
<!-- Include in your checkout page -->
<script>
async function initiatePayment(amount, orderId) {
try {
const response = await fetch('/api/create-payment', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ amount, orderId }),
});
const { checkoutUrl } = await response.json();
// Redirect to EPaySe hosted checkout
window.location.href = checkoutUrl;
} catch (error) {
console.error('Payment failed:', error);
alert('Unable to process payment. Please try again.');
}
}
</script>
<button onclick="initiatePayment(99.99, 'ORD-001')">
Pay $99.99
</button>Security Note: Never expose your API secret key in browser-side code. All HMAC signing must happen on your server. The browser should only call your own backend API endpoint.
Related Resources
Explore the full API documentation for detailed endpoint specifications.
