Examples
Create Withdraw Example
Complete example of creating a withdraw/payout using One2Pays API.
Overview
This example shows how to:
- Create a withdraw to a bank account
- Handle the withdraw response
- Monitor withdraw status
Complete Example
import crypto from 'crypto';
const API_KEY = process.env.PAYMENT_API_KEY!;
const API_SECRET = process.env.PAYMENT_API_SECRET!;
// Helper function to create HMAC signature
function createSignature(
timestamp: string,
body: string,
secret: string
): string {
// Signature format: HMAC-SHA256(timestamp + "." + rawBody, secretKey)
const message = `${timestamp}.${body}`;
return crypto
.createHmac('sha256', secret)
.update(message)
.digest('hex');
}
// Create withdraw
export async function createWithdraw(
amount: string,
customerBankAccount: {
name: string;
number: string;
code: string;
},
referenceId: string
) {
const method = 'POST';
const path = '/api/v1/withdraws';
const body = JSON.stringify({
amount, // String like "1000.00"
currency: 'THB',
referenceId,
destinationType: 'bank_account',
customerBankAccountName: customerBankAccount.name,
customerBankAccountNumber: customerBankAccount.number,
customerBankCode: customerBankAccount.code,
description: `Payout for ${referenceId}`,
idempotencyKey: `${referenceId}-${Date.now()}`,
});
const timestamp = Date.now().toString(); // milliseconds
const signature = createSignature(timestamp, body, API_SECRET);
const response = await fetch(`https://api.example.com${path}`, {
method,
headers: {
'X-API-Key': API_KEY,
'X-Timestamp': timestamp,
'X-Signature': `sha256=${signature}`,
'Content-Type': 'application/json',
},
body,
});
const result = await response.json();
if (!result.success) {
throw new Error(result.error.message);
}
return result.data;
}
// Usage
async function payoutToVendor(
orderId: string,
vendorBankAccount: {
name: string;
number: string;
code: string;
}
) {
try {
const withdraw = await createWithdraw(
'500.00',
vendorBankAccount,
`payout-${orderId}`
);
console.log('Withdraw created:', withdraw.id);
console.log('Withdraw status:', withdraw.status);
// Monitor withdraw status via webhook or polling
return withdraw;
} catch (error) {
console.error('Withdraw creation failed:', error);
throw error;
}
}Error Handling
Always handle errors when creating withdraws:
try {
const withdraw = await createWithdraw(amount, customerBankAccount, referenceId);
if (withdraw.status === 'pending' || withdraw.status === 'processing') {
// Withdraw is being processed
console.log('Withdraw initiated successfully');
}
} catch (error) {
if (error.message.includes('INSUFFICIENT_BALANCE')) {
// Handle insufficient funds
console.error('Merchant account balance is insufficient');
} else if (error.message.includes('INVALID_BANK_CODE')) {
// Handle invalid bank code
console.error('Invalid bank code');
} else {
// Handle other errors
console.error('Withdraw creation failed:', error);
}
}Monitoring Withdraw Status
Monitor withdraw status via webhooks or polling:
// Via webhook (recommended)
async function handleWithdrawWebhook(event: any) {
if (event.type === 'withdraw.paid') {
console.log('Withdraw completed:', event.data.id);
// Update your system
} else if (event.type === 'withdraw.failed') {
console.log('Withdraw failed:', event.data.id);
// Handle failure
}
}
// Via polling
async function checkWithdrawStatus(withdrawId: string) {
const withdraw = await getWithdraw(withdrawId);
if (withdraw.status === 'paid') {
console.log('Withdraw completed');
} else if (withdraw.status === 'failed') {
console.log('Withdraw failed');
} else {
// Still processing, check again later
setTimeout(() => checkWithdrawStatus(withdrawId), 5000);
}
}