UNPKG

@receeco/pos-agent

Version:

Receeco POS Integration Middleware Agent

146 lines 5.89 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.POSIntegrationService = void 0; const logger_1 = require("../utils/logger"); const logger = (0, logger_1.createLogger)(); class POSIntegrationService { constructor(receiptService, qrService, offlineQueue) { this.receiptService = receiptService; this.qrService = qrService; this.offlineQueue = offlineQueue; } async processTransaction(transactionData) { try { this.validateTransactionData(transactionData); const receiptToken = this.generateReceiptToken(); const shortCode = this.generateShortCode(); const receiptPayload = { token: receiptToken, short_code: shortCode, merchant_string_id: transactionData.merchantId, merchant_name: transactionData.merchantName, merchant_logo: transactionData.merchantLogo, accent_color: transactionData.accentColor, total_amount: transactionData.totalAmount, currency: transactionData.currency || "NGN", transaction_date: transactionData.timestamp || new Date().toISOString(), items: transactionData.items.map((item) => ({ name: item.name, quantity: item.quantity, unit_price: item.unitPrice, total_price: item.totalPrice, })), category: this.categorizeTransaction(transactionData), status: "completed", }; if (transactionData.paymentMethod) { receiptPayload.payment_method = transactionData.paymentMethod; } if (transactionData.location) { receiptPayload.location = transactionData.location; } receiptPayload.customer_email = null; receiptPayload.customer_phone = null; let receiptId; try { receiptId = await this.receiptService.createReceipt(receiptPayload); if (process.env.NODE_ENV === "development") { logger.info("Receipt saved to backend:", { receiptId }); } } catch (error) { logger.warn("Backend unavailable, queuing transaction:", error); await this.offlineQueue.queueTransaction(receiptPayload); receiptId = receiptToken; } const baseUrl = process.env.RECEECO_WEB_URL || "https://receeco.com"; const receiptUrl = `${baseUrl.replace(/\/$/, "")}/app/receipt/${receiptToken}`; const qrCodeData = await this.qrService.generateQRCode(receiptUrl, shortCode); return { receiptId: receiptToken, receiptUrl, qrCodeUrl: qrCodeData.dataUrl, qrCodeSvg: qrCodeData.svg, shortCode: qrCodeData.shortCode, deepLinkUrl: receiptUrl, status: "success", timestamp: new Date().toISOString(), }; } catch (error) { logger.error("Transaction processing failed:", error); throw error; } } async handleReceiptStatusUpdate(receiptId, status, timestamp) { logger.info("Handling receipt status update:", { receiptId, status, timestamp, }); } async getTransactionStatus(transactionId) { try { return await this.receiptService.getReceiptStatus(transactionId); } catch (error) { logger.error("Failed to get transaction status:", error); throw error; } } validateTransactionData(data) { if (!data.merchantId) { throw new Error("Merchant ID is required"); } if (!data.items || data.items.length === 0) { throw new Error("Transaction must have at least one item"); } if (!data.totalAmount || data.totalAmount <= 0) { throw new Error("Total amount must be greater than 0"); } for (const item of data.items) { if (!item.name || !item.quantity || !item.unitPrice || !item.totalPrice) { throw new Error("Invalid item data"); } } } generateReceiptToken() { const timestamp = Date.now().toString(36); const random = Math.random().toString(36).substring(2, 8); return `rcpt_${timestamp}_${random}`; } generateShortCode() { return Math.random().toString(36).substring(2, 8).toUpperCase(); } categorizeTransaction(data) { const merchantName = (data.merchantName || "").toLowerCase(); const itemNames = data.items .map((item) => item.name.toLowerCase()) .join(" "); if (merchantName.includes("supermarket") || merchantName.includes("grocery") || itemNames.includes("rice") || itemNames.includes("bread")) { return "Groceries"; } if (merchantName.includes("restaurant") || merchantName.includes("cafe") || itemNames.includes("meal") || itemNames.includes("drink")) { return "Restaurants"; } if (merchantName.includes("fuel") || merchantName.includes("petrol") || merchantName.includes("gas")) { return "Transport"; } if (merchantName.includes("pharmacy") || merchantName.includes("hospital") || merchantName.includes("clinic")) { return "Healthcare"; } return "Other"; } } exports.POSIntegrationService = POSIntegrationService; //# sourceMappingURL=pos-integration.js.map