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>

320 lines (285 loc) 10.1 kB
const axios = require('axios'); /** * YallaPay Ödeme Entegrasyonu * * Başlamadan önce: * 1. YallaPay hesabı oluşturun * 2. Merchant Dashboard'dan private key alın * 3. Webhook URL'inizi ayarlayın */ class YallaPayService { constructor(config) { this.config = config || {}; const requiredFields = ['privateKey', 'currency']; for (let field of requiredFields) { if (!config[field]) throw new Error(`Missing required field: ${field}`); } this.privateKey = config.privateKey; this.currency = config.currency; this.baseUrl = config.baseUrl || 'https://yallapay.net/api'; this.webhookSecret = config.webhookSecret || ''; this.debug = config.debug || false; } /** * Ödeme bağlantısı oluşturur * * @param {Object} paymentDetails - Ödeme detayları * @returns {Promise<Object>} Ödeme sonucu */ async createPayment(paymentDetails) { try { // Zorunlu alanları kontrol et let requiredData = ['amount', 'purpose', 'external_id']; for (let data of requiredData) { if (!paymentDetails[data]) throw new Error(`Missing required data: ${data}`); } // Form verilerini hazırla const formData = new FormData(); formData.append('private_key', this.privateKey); formData.append('currency', paymentDetails.currency || this.currency); formData.append('amount', paymentDetails.amount); formData.append('purpose', paymentDetails.purpose); formData.append('external_id', paymentDetails.external_id); // İsteğe bağlı parametreler if (paymentDetails.is_fallback) { formData.append('is_fallback', paymentDetails.is_fallback); if (paymentDetails.is_fallback === '1' && paymentDetails.fallback_url) { formData.append('fallback_url', paymentDetails.fallback_url); } } if (paymentDetails.store_id) { formData.append('store_id', paymentDetails.store_id); } // Debug modunda istek detaylarını göster if (this.debug) { console.log('YallaPay ödeme isteği hazırlanıyor:', Object.fromEntries(formData)); } // API isteği gönder const response = await axios({ method: 'POST', url: `${this.baseUrl}/request`, headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' }, data: Object.fromEntries(formData) }); const responseData = response.data; // Debug modunda yanıt detaylarını göster if (this.debug) { console.log('YallaPay API yanıtı:', responseData); } // Hata kontrolü if (responseData.status !== "success") { throw new Error(`YallaPay API error: ${responseData.message || 'Unknown error'}`); } // QR kod oluştur (isteğe bağlı) let qrCode = null; if (paymentDetails.generateQr && responseData.data.checkout_url) { qrCode = await this.generateQrCode(responseData.data.checkout_url); } // Başarılı yanıt return { status: 'success', data: { transactionId: responseData.data.transaction_id, url: responseData.data.checkout_url, fallbackUrl: responseData.data.fallback_url || null, id: responseData.data.transaction_id, qr: qrCode } }; } catch (error) { if (this.debug) { console.error('YallaPay API hatası:', error); } if (error.response) { console.error('Hata detayları:', { statusCode: error.response.status, statusText: error.response.statusText, data: error.response.data }); throw new Error(`YallaPay API error (${error.response.status}): ${JSON.stringify(error.response.data)}`); } else if (error.request) { console.error('Yanıt alınamadı:', error.request); throw new Error('No response received from YallaPay API'); } else { throw new Error(`Error in YallaPay payment creation: ${error.message}`); } } } /** * İşlem durumunu doğrular * * @param {string} transactionId - YallaPay işlem ID'si * @returns {Promise<Object>} İşlem durumu */ async verifyTransaction(transactionId) { try { if (!transactionId) { throw new Error("Transaction ID is required"); } // Form verilerini hazırla const formData = new FormData(); formData.append('private_key', this.privateKey); formData.append('trx_id', transactionId); // API isteği gönder const response = await axios({ method: 'POST', url: `${this.baseUrl}/transaction/verify`, headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' }, data: Object.fromEntries(formData) }); const responseData = response.data; // Debug modunda yanıt detaylarını göster if (this.debug) { console.log('YallaPay doğrulama yanıtı:', responseData); } // Hata kontrolü if (responseData.status !== "success") { throw new Error(`YallaPay verification error: ${responseData.message || 'Unknown error'}`); } // İşlem durumunu belirle let status = this.mapTransactionStatus(responseData.data.status); return { status: status, transaction: { id: responseData.data.transaction_id, external_id: responseData.data.external_id, amount: responseData.data.amount, net_amount: responseData.data.net_amount, currency: responseData.data.currency, payment_method: responseData.data.payment_method, payment_date: responseData.data.payment_date, status_code: responseData.data.status, status: status } }; } catch (error) { if (this.debug) { console.error('YallaPay doğrulama hatası:', error); } throw new Error(`Error in YallaPay transaction verification: ${error.message}`); } } /** * Webhook callback'ini işler * * @param {Object} webhookData - Webhook verileri * @returns {Promise<Object>} İşlem sonucu */ async handleWebhook(webhookData) { try { // Debug modunda webhook verilerini göster if (this.debug) { console.log('YallaPay webhook verileri:', webhookData); } // Webhook verilerini doğrula if (!webhookData.transaction_id || !webhookData.webhook_secret) { throw new Error("Missing required fields in webhook data"); } // Webhook secret'ı doğrula if (this.webhookSecret && webhookData.webhook_secret !== this.webhookSecret) { throw new Error("Invalid webhook secret"); } // İşlem durumunu belirle let status = this.mapTransactionStatus(webhookData.status); // İşlem durumuna göre yanıt döndür return { status: status, orderId: webhookData.external_id, merchant_oid: webhookData.transaction_id, amount: webhookData.amount, net_amount: webhookData.net_amount, currency: webhookData.currency, paymentType: webhookData.payment_method, payment_date: webhookData.payment_date }; } catch (error) { if (this.debug) { console.error('YallaPay webhook işleme hatası:', error); } throw new Error(`Error in YallaPay webhook handling: ${error.message}`); } } /** * YallaPay durum kodunu anlaşılır ifadelere dönüştürür * * @param {number} statusCode - YallaPay durum kodu * @returns {string} Durum açıklaması */ mapTransactionStatus(statusCode) { const statusMap = { 0: 'failed', 1: 'success', 3: 'refunded', 4: 'disputed', 5: 'initiated' }; return statusMap[statusCode] || 'unknown'; } /** * Ödeme bağlantısı için QR kod oluşturur * * @param {string} paymentUrl - Ödeme URL'i * @returns {Promise<string|null>} Base64 formatında QR kod */ async generateQrCode(paymentUrl) { try { const response = await axios.get('https://api.qrserver.com/v1/create-qr-code/', { params: { size: '300x300', data: paymentUrl }, responseType: 'arraybuffer' }); const base64Image = Buffer.from(response.data, 'binary').toString('base64'); return `data:image/png;base64,${base64Image}`; } catch (error) { console.error('QR kod oluşturma hatası:', error); return null; } } /** * Handle callback/notification * @param {Object} callbackData - Callback data * @returns {Promise<Object>} - Callback result */ async handleCallback(callbackData) { try { // Use existing handleWebhook method for consistency const result = await this.handleWebhook(callbackData); // Map to standard format if (result.status === 'success') { return { success: true, transactionId: result.merchant_oid, status: 'completed', amount: parseFloat(result.amount), currency: result.currency, rawData: callbackData }; } else if (result.status === 'failed') { return { success: false, status: 'failed', transactionId: result.merchant_oid, rawData: callbackData }; } else { return { success: false, status: 'pending', transactionId: result.merchant_oid, rawData: callbackData }; } } catch (error) { throw new Error(`YallaPay callback handling failed: ${error.message}`); } } } module.exports = YallaPayService;