UNPKG

uz-pay-sdk

Version:

🚀 Universal Payment SDK for Uzbekistan - Integrate Payme, Click, UzCard, Humo & Apelsin with one simple API. Battle-tested, production-ready, 95% faster integration.

187 lines • 7.46 kB
"use strict"; var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.WebhookService = void 0; const common_1 = require("@nestjs/common"); const logger_config_1 = require("../logger/logger.config"); const crypto = require("crypto"); let WebhookService = class WebhookService { constructor() { this.webhookEvents = []; // In production, use database } async processWebhook(webhookData) { const eventId = this.generateEventId(); const event = { id: eventId, type: `payment.${webhookData.status}`, data: webhookData, timestamp: webhookData.timestamp, processed: false, }; // Save webhook event (in production, save to database) this.webhookEvents.push(event); logger_config_1.logger.info('Webhook event created', { eventId, provider: webhookData.provider, transactionId: webhookData.transactionId, orderId: webhookData.orderId, status: webhookData.status, }); logger_config_1.paymentLogger.info('WEBHOOK_RECEIVED', { eventId, provider: webhookData.provider, transactionId: webhookData.transactionId, orderId: webhookData.orderId, status: webhookData.status, amount: webhookData.amount, }); // Process the webhook await this.handleWebhookEvent(event); } async handleWebhookEvent(event) { try { // Business logic based on webhook type switch (event.type) { case 'payment.success': await this.handleSuccessfulPayment(event.data); break; case 'payment.failed': await this.handleFailedPayment(event.data); break; case 'payment.cancelled': await this.handleCancelledPayment(event.data); break; case 'payment.pending': await this.handlePendingPayment(event.data); break; } // Mark as processed event.processed = true; logger_config_1.paymentLogger.info('WEBHOOK_PROCESSED', { eventId: event.id, type: event.type, provider: event.data.provider, transactionId: event.data.transactionId, }); } catch (error) { logger_config_1.logger.error('Webhook processing failed', { eventId: event.id, error: error.message, stack: error.stack, }); logger_config_1.paymentLogger.error('WEBHOOK_PROCESSING_ERROR', { eventId: event.id, error: error.message, provider: event.data.provider, transactionId: event.data.transactionId, }); throw error; } } async handleSuccessfulPayment(data) { logger_config_1.logger.info('Processing successful payment', { provider: data.provider, transactionId: data.transactionId, orderId: data.orderId, amount: data.amount, }); // TODO: Update order status in database // TODO: Send confirmation email/SMS // TODO: Trigger fulfillment process // TODO: Update analytics } async handleFailedPayment(data) { logger_config_1.logger.info('Processing failed payment', { provider: data.provider, transactionId: data.transactionId, orderId: data.orderId, }); // TODO: Update order status // TODO: Send failure notification // TODO: Log for reconciliation } async handleCancelledPayment(data) { logger_config_1.logger.info('Processing cancelled payment', { provider: data.provider, transactionId: data.transactionId, orderId: data.orderId, }); // TODO: Update order status // TODO: Release reserved inventory // TODO: Send cancellation notification } async handlePendingPayment(data) { logger_config_1.logger.info('Processing pending payment', { provider: data.provider, transactionId: data.transactionId, orderId: data.orderId, }); // TODO: Set timeout for payment confirmation // TODO: Schedule status check job } // Signature validation methods validatePaymeSignature(payload, signature) { try { // Payme signature validation logic const secretKey = process.env.PAYME_SECRET_KEY || 'default-secret'; const expectedSignature = crypto .createHmac('sha256', secretKey) .update(JSON.stringify(payload)) .digest('hex'); return signature === expectedSignature; } catch (error) { logger_config_1.logger.error('Payme signature validation failed', { error: error.message, }); return false; } } validateClickSignature(payload, signature) { try { // Click signature validation logic const secretKey = process.env.CLICK_SECRET_KEY || 'default-secret'; const expectedSignature = crypto .createHash('md5') .update(`${payload.click_trans_id}${payload.service_id}${secretKey}${payload.merchant_trans_id}${payload.amount}${payload.action}${payload.sign_time}`) .digest('hex'); return signature === expectedSignature; } catch (error) { logger_config_1.logger.error('Click signature validation failed', { error: error.message, }); return false; } } // Utility methods generateEventId() { return `webhook_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`; } // Query methods for monitoring getWebhookEvents(limit = 50) { return this.webhookEvents .sort((a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime()) .slice(0, limit); } getUnprocessedEvents() { return this.webhookEvents.filter((event) => !event.processed); } getEventsByProvider(provider) { return this.webhookEvents.filter((event) => event.data.provider === provider); } getEventsByOrderId(orderId) { return this.webhookEvents.filter((event) => event.data.orderId === orderId); } }; exports.WebhookService = WebhookService; exports.WebhookService = WebhookService = __decorate([ (0, common_1.Injectable)() ], WebhookService); //# sourceMappingURL=webhook.service.js.map