upn-with-qr-generator
Version:
A UPN + QR code generator for Slovenian banking system (2024 standard compliant) with environment-aware canvas support and isPNGGenerationAvailable method
91 lines (90 loc) • 4.56 kB
JavaScript
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.UPNGenerator = void 0;
// src/UPNGenerator.ts
const qrcode_1 = __importDefault(require("qrcode"));
class UPNGenerator {
constructor(data) {
this.data = data;
}
// Public getter for `data`
getData() {
return this.data;
}
generateUPNQRData() {
// Convert legacy fields for backward compatibility
const paymentDate = this.data.paymentDate || this.convertLegacyDate(this.data.dueDate);
const receiverReference = this.data.receiverReference || this.data.reference || '';
const fields = [
'UPNQR', // 1. Leading string (5)
this.formatField(this.data.payerIban || '', 19), // 2. Payer IBAN (19)
this.data.isDeposit ? 'X' : '', // 3. Deposit flag (1)
this.data.isWithdrawal ? 'X' : '', // 4. Withdrawal flag (1)
this.formatField(this.data.payerReference || '', 26), // 5. Payer reference (26)
this.formatField(this.data.payerName, 33), // 6. Payer name (33)
this.formatField(this.data.payerAddress, 33), // 7. Payer street address (33)
this.formatField(this.data.payerPost, 33), // 8. Payer city (33)
this.formatAmount(this.data.amount), // 9. Amount (11)
paymentDate, // 10. Payment date DD.MM.YYYY (10)
this.data.isUrgent ? 'X' : '', // 11. Urgent flag (1)
this.formatField(this.data.code, 4), // 12. Purpose code (4)
this.formatField(this.data.purpose, 42), // 13. Payment purpose (42)
this.data.paymentDeadline || '', // 14. Payment deadline DD.MM.YYYY (10)
this.formatField(this.data.receiverIban, 34), // 15. Receiver IBAN (34)
this.formatField(receiverReference, 26), // 16. Receiver reference (26)
this.formatField(this.data.receiverName, 33), // 17. Receiver name (33)
this.formatField(this.data.receiverAddress, 33), // 18. Receiver street address (33)
this.formatField(this.data.receiverPost, 33), // 19. Receiver city (33)
];
const qrData = fields.join('\n') + '\n';
// 20. Total length checksum (3) - length of fields 1-19 with separators
const totalLength = qrData.length;
const checksumField = totalLength.toString().padStart(3, '0');
return qrData + checksumField + '\n';
}
formatAmount(amount) {
return (amount * 100).toFixed(0).padStart(11, '0');
}
formatField(value, length) {
return value.padEnd(length, ' ');
}
convertLegacyDate(legacyDate) {
if (!legacyDate || legacyDate.length !== 8) {
return '';
}
const year = legacyDate.substring(0, 4);
const month = legacyDate.substring(4, 6);
const day = legacyDate.substring(6, 8);
return `${day}.${month}.${year}`;
}
generateQRCode() {
return __awaiter(this, void 0, void 0, function* () {
const qrData = this.generateUPNQRData();
// Generate QR code with ISO-8859-2 encoding as required by UPN QR specification
// Using Binary mode with ECC Level M and specific capacity settings
return yield qrcode_1.default.toBuffer(qrData, {
errorCorrectionLevel: 'M', // Error correction level M as per spec
version: 15, // QR Version 15 for capacity (411 chars max)
width: 250, // Increased size for better scanning
margin: 1, // Minimal margin
color: {
dark: '#000000',
light: '#FFFFFF'
}
});
});
}
}
exports.UPNGenerator = UPNGenerator;