UNPKG

quickpos

Version:

<div align="center"> <h1>💳 QuickPos 🚀</h1> <p><strong>A powerful, multi-gateway payment integration module for Node.js</strong></p> <p>Seamlessly integrate with 50+ payment providers worldwide</p>

212 lines (182 loc) • 7.31 kB
const axios = require('axios'); const crypto = require('crypto'); class PayID19Client { constructor(config) { const requiredFields = ['apiKey', 'secretKey']; for (let field of requiredFields) { if (!config[field]) throw new Error(`Missing required field: ${field}`); } this.apiKey = config.apiKey; this.secretKey = config.secretKey; this.URL = 'https://payid19.com/api/v1'; this.client = axios.create({ baseURL: this.URL, headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${this.apiKey}` } }); this.client.interceptors.response.use(response => { return response; }, error => { if (error.response) { throw new Error(`PayID19 API error: ${error.response.data.message || error.message}`); } throw new Error(`PayID19 API error: ${error.message}`); }); } generateSignature(data) { const sortedData = Object.keys(data) .sort() .map(key => `${key}=${data[key]}`) .join('&'); return crypto .createHmac('sha256', this.secretKey) .update(sortedData) .digest('hex'); } async createPayment(options) { try { const orderId = options.orderId || `ORDER-${Date.now()}`; const requestData = { merchant_order_id: orderId, amount: parseFloat(options.amount), currency: options.currency || 'IDR', customer_name: options.customerName || options.name || 'Customer', customer_email: options.customerEmail || options.email, customer_phone: options.customerPhone || options.phone || '', callback_url: options.callbackUrl || options.callback_link, return_url: options.returnUrl || options.callback_link, description: options.description || options.name || 'Payment', payment_method: options.paymentMethod || 'all' }; // Generate signature const signature = this.generateSignature(requestData); requestData.signature = signature; const response = await this.client.post('/payment/create', requestData); if (response.data.status === 'success') { return { status: 'success', data: { paymentId: response.data.data.payment_id, url: response.data.data.payment_url, orderId: orderId, qrCode: response.data.data.qr_code, expiredAt: response.data.data.expired_at } }; } else { throw new Error(response.data.message || 'Payment creation failed'); } } catch (error) { throw new Error(`Payment creation error: ${error.message}`); } } async getPaymentStatus(paymentId) { try { const response = await this.client.get(`/payment/status/${paymentId}`); if (response.data.status === 'success') { return response.data.data; } else { throw new Error(response.data.message || 'Failed to get payment status'); } } catch (error) { throw new Error(`Payment status error: ${error.message}`); } } async handleCallback(callbackData) { try { const verification = await this.verifyCallback(callbackData); if (!verification.status) { throw new Error(verification.error.message); } const data = verification.data; // Status mapping const statusMapping = { 'paid': 'success', 'pending': 'pending', 'expired': 'expired', 'failed': 'failed', 'cancelled': 'cancelled' }; return { status: statusMapping[data.payment_status] || 'unknown', paymentId: data.payment_id, orderId: data.merchant_order_id, amount: parseFloat(data.amount), currency: data.currency, paymentMethod: data.payment_method, paymentStatus: data.payment_status, paidAt: data.paid_at, fee: parseFloat(data.fee || 0), netAmount: parseFloat(data.net_amount || data.amount) }; } catch (error) { throw new Error(`Error in PayID19 callback handling: ${error.message}`); } } async verifyCallback(data) { try { const receivedSignature = data.signature; delete data.signature; const expectedSignature = this.generateSignature(data); if (receivedSignature !== expectedSignature) { return { status: false, error: { code: 401, message: 'Invalid signature' } }; } if (data.payment_status === 'failed' || data.payment_status === 'cancelled') { return { status: false, error: { code: 400, message: `Payment ${data.payment_status}` } }; } // Restore signature for callback response data.signature = receivedSignature; return { status: true, data: data }; } catch (error) { return { status: false, error: { code: 500, message: error.message } }; } } async getBalance() { try { const response = await this.client.get('/merchant/balance'); if (response.data.status === 'success') { return response.data.data; } else { throw new Error(response.data.message || 'Failed to get balance'); } } catch (error) { throw new Error(`Balance error: ${error.message}`); } } async getPaymentMethods() { try { const response = await this.client.get('/payment/methods'); if (response.data.status === 'success') { return response.data.data; } else { throw new Error(response.data.message || 'Failed to get payment methods'); } } catch (error) { throw new Error(`Payment methods error: ${error.message}`); } } } module.exports = PayID19Client;