@receeco/pos-agent
Version:
Receeco POS Integration Middleware Agent
146 lines • 5.89 kB
JavaScript
;
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