Node.js Examples
Complete Node.js examples for integrating with the LuxCore API usingaxios.
Installation
Copy
npm install axios
LuxCore Client Class
Copy
const axios = require('axios');
const crypto = require('crypto');
class LuxCoreClient {
static BASE_URL = 'https://api.lux-core.io/api/v1';
constructor(apiKey = process.env.LUXCORE_API_KEY) {
if (!apiKey) {
throw new Error('API key is required');
}
this.client = axios.create({
baseURL: LuxCoreClient.BASE_URL,
headers: {
'X-API-Key': apiKey,
'Content-Type': 'application/json'
}
});
// Add response interceptor for error handling
this.client.interceptors.response.use(
(response) => response.data,
(error) => {
const err = new LuxCoreError(
error.response?.data?.message || error.message,
error.response?.status,
error.response?.data?.error
);
throw err;
}
);
}
// Payments
async createPayment(data) {
return this.client.post('/payments', data);
}
async getPayment(paymentId) {
return this.client.get(`/payments/${paymentId}`);
}
async listPayments(filters = {}) {
return this.client.get('/payments', { params: filters });
}
async cancelPayment(paymentId) {
return this.client.post(`/payments/${paymentId}/cancel`);
}
// Balance
async getBalance(currency) {
const params = currency ? { currency } : {};
return this.client.get('/balance', { params });
}
async getAllBalances() {
return this.client.get('/balance/all');
}
// Webhooks
async createWebhook(data) {
return this.client.post('/webhooks', data);
}
async listWebhooks() {
return this.client.get('/webhooks');
}
async deleteWebhook(webhookId) {
return this.client.delete(`/webhooks/${webhookId}`);
}
// Static method for webhook verification
static verifyWebhookSignature(payload, signature, timestamp, secret) {
// Check timestamp (reject if older than 5 minutes)
const currentTime = Math.floor(Date.now() / 1000);
if (Math.abs(currentTime - timestamp) > 300) {
throw new Error('Webhook timestamp too old');
}
// Calculate expected signature
const payloadString = JSON.stringify(payload);
const payloadToSign = `${timestamp}.${payloadString}`;
const expectedSignature = 'sha256=' + crypto
.createHmac('sha256', secret)
.update(payloadToSign)
.digest('hex');
// Compare signatures (timing-safe)
if (!crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expectedSignature)
)) {
throw new Error('Invalid webhook signature');
}
return true;
}
}
class LuxCoreError extends Error {
constructor(message, statusCode, errorCode) {
super(message);
this.name = 'LuxCoreError';
this.statusCode = statusCode;
this.errorCode = errorCode;
}
}
module.exports = { LuxCoreClient, LuxCoreError };
Usage Examples
Create a Deposit Payment
Copy
const { LuxCoreClient, LuxCoreError } = require('./luxcore');
const client = new LuxCoreClient();
async function createDeposit() {
try {
const payment = await client.createPayment({
amount: 100000, // $1,000.00 MXN (in centavos)
currency: 'MXN',
method: 'spei',
type: 'deposit',
merchant_reference: `order_${Date.now()}`,
customer: {
name: 'Juan Perez',
email: 'juan@example.com',
phone: '+525551234567'
},
metadata: {
order_id: '12345',
source: 'web'
}
});
console.log('Payment created:', payment.transaction_id);
console.log('Status:', payment.status);
if (payment.instructions) {
console.log('Bank:', payment.instructions.bank_name);
console.log('CLABE:', payment.instructions.account_number);
console.log('Reference:', payment.instructions.reference);
}
return payment;
} catch (error) {
if (error instanceof LuxCoreError) {
console.error(`API Error (${error.statusCode}): ${error.message}`);
} else {
console.error('Unexpected error:', error);
}
}
}
createDeposit();
Create a Withdrawal (Payout)
Copy
async function createPayout() {
const payout = await client.createPayment({
amount: 50000,
currency: 'MXN',
method: 'spei',
type: 'withdrawal',
merchant_reference: `payout_${Date.now()}`,
customer: {
name: 'Finance Team',
email: 'finance@company.com'
},
payout: {
recipient_name: 'Maria Garcia',
bank_account: '012345678901234567',
bank_code: '002',
reference: 'PAYOUT-001'
}
});
console.log('Payout created:', payout.transaction_id);
return payout;
}
List Payments
Copy
async function listRecentPayments() {
const result = await client.listPayments({
status: 'completed',
limit: 20,
created_at_from: '2025-01-01T00:00:00Z'
});
console.log(`Found ${result.total} payments`);
for (const payment of result.data) {
console.log(`${payment.transaction_id}: ${payment.amount} ${payment.currency}`);
}
}
Webhook Handler (Express)
Copy
const express = require('express');
const { LuxCoreClient } = require('./luxcore');
const app = express();
app.use(express.json());
const WEBHOOK_SECRET = process.env.LUXCORE_WEBHOOK_SECRET;
app.post('/webhooks/luxcore', (req, res) => {
const signature = req.headers['x-webhook-signature'];
const timestamp = parseInt(req.headers['x-webhook-timestamp']);
const payload = req.body;
// Verify signature
try {
LuxCoreClient.verifyWebhookSignature(
payload,
signature,
timestamp,
WEBHOOK_SECRET
);
} catch (error) {
console.error('Webhook verification failed:', error.message);
return res.status(400).json({ error: error.message });
}
// Process event
const { event, payment } = payload;
console.log(`Received ${event} for payment ${payment.id}`);
switch (event) {
case 'payment.completed':
// Handle completed payment
console.log(`✅ Payment ${payment.id} completed!`);
// Update database, send confirmation email, etc.
break;
case 'payment.failed':
// Handle failed payment
console.log(`❌ Payment ${payment.id} failed: ${payment.failure_reason}`);
break;
case 'payout.completed':
// Handle completed payout
console.log(`✅ Payout ${payment.id} completed!`);
break;
default:
console.log(`Unhandled event: ${event}`);
}
res.status(200).json({ received: true });
});
app.listen(3000, () => {
console.log('Webhook server listening on port 3000');
});
TypeScript Version
Copy
import axios, { AxiosInstance } from 'axios';
import crypto from 'crypto';
interface PaymentRequest {
amount: number;
currency: string;
method: string;
type: 'deposit' | 'withdrawal' | 'deposit_pp' | 'withdrawal_pp';
merchant_reference: string;
customer: {
name: string;
email: string;
phone?: string;
};
payout?: {
recipient_name: string;
bank_account: string;
bank_code: string;
reference?: string;
};
metadata?: Record<string, unknown>;
}
interface Payment {
transaction_id: string;
status: string;
amount: number;
currency: string;
method: string;
type: string;
created_at: string;
instructions?: {
bank_name: string;
account_number: string;
reference: string;
beneficiary: string;
};
}
class LuxCoreClient {
private client: AxiosInstance;
private static BASE_URL = 'https://api.lux-core.io/api/v1';
constructor(apiKey: string = process.env.LUXCORE_API_KEY!) {
this.client = axios.create({
baseURL: LuxCoreClient.BASE_URL,
headers: {
'X-API-Key': apiKey,
'Content-Type': 'application/json'
}
});
}
async createPayment(data: PaymentRequest): Promise<Payment> {
const response = await this.client.post<Payment>('/payments', data);
return response.data;
}
async getPayment(paymentId: string): Promise<Payment> {
const response = await this.client.get<Payment>(`/payments/${paymentId}`);
return response.data;
}
static verifyWebhookSignature(
payload: object,
signature: string,
timestamp: number,
secret: string
): boolean {
const currentTime = Math.floor(Date.now() / 1000);
if (Math.abs(currentTime - timestamp) > 300) {
throw new Error('Webhook timestamp too old');
}
const payloadToSign = `${timestamp}.${JSON.stringify(payload)}`;
const expectedSignature = 'sha256=' + crypto
.createHmac('sha256', secret)
.update(payloadToSign)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expectedSignature)
);
}
}
export { LuxCoreClient, PaymentRequest, Payment };
Error Handling
Copy
const { LuxCoreClient, LuxCoreError } = require('./luxcore');
async function safeCreatePayment(data) {
const client = new LuxCoreClient();
try {
return await client.createPayment(data);
} catch (error) {
if (error instanceof LuxCoreError) {
switch (error.statusCode) {
case 401:
console.error('Invalid API key');
break;
case 400:
console.error('Validation error:', error.message);
break;
case 429:
console.error('Rate limited - implementing backoff');
await sleep(60000);
return safeCreatePayment(data); // Retry
case 500:
case 503:
console.error('Server error - retrying');
await sleep(5000);
return safeCreatePayment(data); // Retry
default:
console.error(`API error (${error.statusCode}): ${error.message}`);
}
}
throw error;
}
}
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
