Comparing version 1.1.2 to 1.1.3
@@ -44,6 +44,6 @@ "use strict"; | ||
pix.setReceiverCity('Rio Preto'); | ||
pix.setKey('fcba8826-cbff-46e2-8c40-1b39896402a8'); | ||
pix.setDescription('Donation with defined amount - GPIX'); // opcional | ||
pix.setReceiverZipCode('15082131'); // opcional | ||
pix.setKey('fcba8826-cbff-46e2-8c40-1b39896402a8'); | ||
pix.setIdentificator('123'); // opcional | ||
pix.setDescription('Donation with defined amount - GPIX'); // opcional | ||
pix.setAmount(5.0); // opcional | ||
@@ -55,5 +55,5 @@ console.log('\nDonation with defined amount - GPIX >>>>\n', pix.getBRCode()); | ||
pix.setReceiverCity('Rio Preto'); | ||
pix.setKey('fcba8826-cbff-46e2-8c40-1b39896402a8'); | ||
pix.setKey('nubank@hiago.me'); | ||
pix.setDescription('Donation without defined amount - GPIX'); // optional | ||
console.log('Donation without defined amount - GPIX >>>>\n', pix.getBRCode()); | ||
console.log('\nDonation without defined amount - GPIX >>>>\n', pix.getBRCode()); | ||
// Example 03: BRCODE dinamic | ||
@@ -63,12 +63,5 @@ var dpix = pix_1.PIX.dinamic(); | ||
dpix.setReceiverCity('Rio Preto'); | ||
dpix.setLocation('url-location-psp'); | ||
dpix.setAmount(10.4); // some PSP are not recovering the amount through the charge. Then temporarily enter the amount to avoid problems. | ||
dpix.setLocation('qrcodes-pix.gerencianet.com.br/v2/7398eefa79c94c4ba5e22da93fe291ea'); | ||
// dpix.setAmount(10.4) // some PSP are not recovering the amount through the charge. Then temporarily enter the amount to avoid problems. | ||
console.log('\nBRCODE dinamic - GPIX >>>>\n', dpix.getBRCode()); | ||
// Gerando QRCode em base64 | ||
// Generating QRCode in base64 | ||
(function () { return __awaiter(void 0, void 0, void 0, function () { | ||
return __generator(this, function (_a) { | ||
return [2 /*return*/]; | ||
}); | ||
}); })(); | ||
// Saving QRCode to physical file | ||
@@ -80,3 +73,3 @@ // Salvando QRCode em arquivo físico | ||
case 0: | ||
pix.setDescription('Free Donation / QRCODE - GPIX'); // opcional | ||
pix.setDescription('Free Donation / QRCODE - GPIX'); // optional | ||
return [4 /*yield*/, pix.saveQRCodeFile('./qrcode.png')]; | ||
@@ -83,0 +76,0 @@ case 1: |
@@ -9,2 +9,3 @@ export interface IStatic { | ||
setKey(key: string): void; | ||
isUniqueTransaction(is_unique_transaction: boolean): void; | ||
getBRCode(): string; | ||
@@ -11,0 +12,0 @@ getQRCode(): Promise<string | null>; |
@@ -25,4 +25,6 @@ import { IDinamic } from "./idinamic"; | ||
isUniqueTransaction(is_unique_transaction: boolean): void; | ||
private _rightPad; | ||
private _normalizeText; | ||
private _generateAccountInformation; | ||
private _additionalDataField; | ||
private _getEMV; | ||
getBRCode(): string; | ||
@@ -29,0 +31,0 @@ getQRCode(): Promise<string | null>; |
@@ -68,2 +68,4 @@ "use strict"; | ||
PIX.prototype.setReceiverZipCode = function (zipCode) { | ||
if (zipCode.length != 8) | ||
throw 'A quantidade de caracteres para o código postal é 8'; | ||
this._zip_code = zipCode; | ||
@@ -77,5 +79,11 @@ }; | ||
PIX.prototype.setIdentificator = function (identificator) { | ||
if (identificator.length > 25) | ||
throw 'A quantidade máxima de caracteres para o identificador é 25'; | ||
if (identificator.match(/[^0-9|a-z]/gi)) | ||
throw 'Utilize apenas letras e números no identificador.'; | ||
this._identificator = identificator; | ||
}; | ||
PIX.prototype.setDescription = function (description) { | ||
if (description.length > 50) | ||
throw 'A quantidade máxima de caracteres para a descrição é 50'; | ||
this._description = description; | ||
@@ -96,95 +104,75 @@ }; | ||
}; | ||
PIX.prototype._rightPad = function (value) { | ||
return value < 10 ? "0" + value : value; | ||
}; | ||
PIX.prototype._normalizeText = function (value) { | ||
var str = value.toUpperCase().replace('Ç', 'C'); | ||
return str['normalize']("NFD").replace(/[^A-Z0-9$%*+-\./:]/gi, ' '); | ||
return value.normalize('NFD').replace(/[\u0300-\u036f]/g, "").replace(/[^A-Z\[\]0-9$@%*+-\./:]/gi, ' '); | ||
}; | ||
PIX.prototype.getBRCode = function () { | ||
var lines = []; | ||
//#region Payload Format Indicator | ||
lines.push("0002 01"); | ||
//#endregion | ||
// caso seja transação única | ||
if (this._is_unique_transaction) | ||
lines.push('0102 12'); | ||
//#region Merchant Account Information - PIX | ||
var description = this._normalizeText(this._description || ''); | ||
var extra = 14 + 8; | ||
if (description) { | ||
extra += 4 + description.length; | ||
} | ||
PIX.prototype._generateAccountInformation = function () { | ||
var payload = []; | ||
payload.push(this._getEMV('00', 'br.gov.bcb.pix')); | ||
if (this._key) { | ||
var contentKey = this._normalizeText(this._key); | ||
lines.push("26" + (contentKey.length + extra)); | ||
lines.push("\t0014 br.gov.bcb.pix"); | ||
lines.push("\t01" + this._rightPad(contentKey.length) + " " + contentKey); | ||
payload.push(this._getEMV('01', this._normalizeText(this._key))); | ||
} | ||
else if (this._location) { | ||
var location_1 = this._location; | ||
lines.push("26" + (location_1.length + extra)); | ||
lines.push("\t0014 br.gov.bcb.pix"); | ||
lines.push("\t25" + this._rightPad(location_1.length) + " " + location_1); | ||
if (this._location) { | ||
payload.push(this._getEMV('25', this._normalizeText(this._location))); | ||
} | ||
if (this._description) { | ||
payload.push(this._getEMV('02', this._normalizeText(this._description))); | ||
} | ||
return payload.join(''); | ||
}; | ||
PIX.prototype._additionalDataField = function () { | ||
if (this._identificator) { | ||
var identificator = this._normalizeText(this._identificator); | ||
var reference_label = this._getEMV('05', identificator); | ||
// não funciona no inter/itau. | ||
// let gui = this._getEMV('00', 'br.gov.bcb.brcode') | ||
// let version = this._getEMV('01', '1.0.0') | ||
// let payment_system_specific_template = this._getEMV('50', gui + version) | ||
return this._getEMV('62', reference_label); | ||
} | ||
else { | ||
return this._getEMV('62', this._getEMV('05', '***')); | ||
} | ||
}; | ||
PIX.prototype._getEMV = function (id, string) { | ||
var len = string.length.toString().padStart(2, '0'); | ||
return "" + id + len + string; | ||
}; | ||
PIX.prototype.getBRCode = function () { | ||
var lines = []; | ||
// Payload Format Indicator | ||
lines.push(this._getEMV('00', '01')); | ||
// Is Unique Transaction? | ||
lines.push(this._getEMV('01', this._is_unique_transaction ? '12' : '11')); | ||
// Merchant Account Information - Pix | ||
if (!this._key && !this._location) { | ||
throw 'É necessário informar uma URL ou então uma chave pix.'; | ||
} | ||
// descricao | ||
if (this._description) { | ||
lines.push("\t02" + this._rightPad(description.length) + " " + description); | ||
} | ||
//#endregion | ||
//#region Merchant Category Code | ||
lines.push("5204 0000"); | ||
//#endregion | ||
//#region Transaction Currency | ||
lines.push("5303 986"); // 989 = R$ | ||
//#endregion | ||
//#region Transaction Amount | ||
lines.push(this._getEMV('26', this._generateAccountInformation())); | ||
// Merchant Category Code | ||
lines.push(this._getEMV('52', '0000')); | ||
// Transaction Currency | ||
lines.push(this._getEMV('53', '986')); | ||
//Transaction Amount | ||
if (this._amout) { | ||
var valor = this._normalizeText(this._amout.toFixed(2).toString()); | ||
if (this._amout > 0) | ||
lines.push("54" + this._rightPad(valor.length) + " " + valor); | ||
lines.push(this._getEMV('54', this._amout.toFixed(2))); | ||
} | ||
//#endregion | ||
//#region Country Code | ||
/** @length 02 */ | ||
lines.push("5802 BR"); | ||
//#endregion | ||
//#region Merchant Name | ||
// Country Code | ||
lines.push(this._getEMV('58', 'BR')); | ||
// Merchant Name | ||
var receiver_name = this._normalizeText(this._receiver_name); | ||
lines.push("59" + this._rightPad(receiver_name.length) + " " + receiver_name); | ||
//#endregion | ||
//#region Merchant City | ||
lines.push(this._getEMV('59', receiver_name)); | ||
// Merchant City | ||
var receiver_city = this._normalizeText(this._receiver_city); | ||
lines.push("60" + this._rightPad(receiver_city.length) + " " + receiver_city); | ||
//#endregion | ||
//#region Postal Code | ||
lines.push(this._getEMV('60', receiver_city)); | ||
// Postal Code | ||
if (this._zip_code) { | ||
var zip_code = this._normalizeText(this._zip_code); | ||
lines.push("61" + this._rightPad(zip_code.length) + " " + zip_code); | ||
lines.push(this._getEMV('61', zip_code)); | ||
} | ||
//#endregion | ||
//#region Additional Data Field | ||
if (this._identificator) { | ||
var transaction_identificator = this._normalizeText(this._identificator); | ||
lines.push("62" + (transaction_identificator.length + 38)); | ||
lines.push("\t05" + this._rightPad(transaction_identificator.length) + " " + transaction_identificator); | ||
lines.push("\t5030"); | ||
lines.push("\t\t0017 br.gov.bcb.brcode"); | ||
lines.push("\t\t0105 1.0.0"); | ||
} | ||
//#endregion | ||
//#region Additional Data Field | ||
if (this._location) { | ||
lines.push("6207"); | ||
lines.push("\t0503 ***"); | ||
} | ||
//#endregion | ||
// Additional Data Field | ||
lines.push(this._additionalDataField()); | ||
lines.push("6304"); | ||
// fix: nome recebedor | ||
lines = lines.map(function (item) { return item.replace(' ', ''); }); | ||
var finalString = lines.join('').replace(/\t/gi, ''); | ||
return finalString + crc_1.CRC.computeCRC(finalString); | ||
var payloadString = lines.join(''); | ||
return payloadString + crc_1.CRC.computeCRC(payloadString); | ||
}; | ||
@@ -191,0 +179,0 @@ PIX.prototype.getQRCode = function () { |
@@ -7,6 +7,6 @@ import { PIX } from "./lib/pix"; | ||
pix.setReceiverCity('Rio Preto') | ||
pix.setKey('fcba8826-cbff-46e2-8c40-1b39896402a8') | ||
pix.setDescription('Donation with defined amount - GPIX') // opcional | ||
pix.setReceiverZipCode('15082131') // opcional | ||
pix.setKey('fcba8826-cbff-46e2-8c40-1b39896402a8') | ||
pix.setIdentificator('123') // opcional | ||
pix.setDescription('Donation with defined amount - GPIX') // opcional | ||
pix.setAmount(5.0) // opcional | ||
@@ -20,8 +20,7 @@ | ||
pix.setReceiverCity('Rio Preto') | ||
pix.setKey('fcba8826-cbff-46e2-8c40-1b39896402a8') | ||
pix.setKey('nubank@hiago.me') | ||
pix.setDescription('Donation without defined amount - GPIX') // optional | ||
console.log('Donation without defined amount - GPIX >>>>\n', pix.getBRCode()) | ||
console.log('\nDonation without defined amount - GPIX >>>>\n', pix.getBRCode()) | ||
// Example 03: BRCODE dinamic | ||
@@ -35,11 +34,2 @@ let dpix = PIX.dinamic(); | ||
// Gerando QRCode em base64 | ||
// Generating QRCode in base64 | ||
(async () => { | ||
//console.log('QRCODE Static >>> ', await pix.getQRCode()) | ||
//console.log('QRCODE Dinamic >>> ', await dpix.getQRCode()) | ||
})(); | ||
// Saving QRCode to physical file | ||
@@ -49,5 +39,4 @@ // Salvando QRCode em arquivo físico | ||
pix.setDescription('Free Donation / QRCODE - GPIX') // opcional | ||
pix.setDescription('Free Donation / QRCODE - GPIX') // optional | ||
if(await pix.saveQRCodeFile('./qrcode.png')) { | ||
@@ -54,0 +43,0 @@ console.log('success in saving static QR-code') |
@@ -10,2 +10,3 @@ export interface IStatic { | ||
setKey(key: string): void; | ||
isUniqueTransaction(is_unique_transaction: boolean): void; | ||
@@ -12,0 +13,0 @@ getBRCode(): string; |
184
lib/pix.ts
import { CRC } from "./crc/crc"; | ||
import { IDinamic } from "./idinamic"; | ||
import { IStatic } from "./istatic"; | ||
import * as qrcode from "qrcode" | ||
import * as fs from "fs" | ||
import * as qrcode from "qrcode"; | ||
import * as fs from "fs"; | ||
@@ -19,3 +19,3 @@ export class PIX implements IDinamic, IStatic { | ||
private constructor() {} | ||
private constructor() { } | ||
@@ -39,2 +39,6 @@ public static static(): IStatic { | ||
setReceiverZipCode(zipCode: string) { | ||
if (zipCode.length != 8) | ||
throw 'A quantidade de caracteres para o código postal é 8' | ||
this._zip_code = zipCode | ||
@@ -51,2 +55,7 @@ } | ||
setIdentificator(identificator: string) { | ||
if (identificator.length > 25) | ||
throw 'A quantidade máxima de caracteres para o identificador é 25' | ||
if (identificator.match(/[^0-9|a-z]/gi)) | ||
throw 'Utilize apenas letras e números no identificador.' | ||
this._identificator = identificator | ||
@@ -56,2 +65,6 @@ } | ||
setDescription(description: string) { | ||
if (description.length > 50) | ||
throw 'A quantidade máxima de caracteres para a descrição é 50' | ||
this._description = description | ||
@@ -80,114 +93,53 @@ } | ||
private _rightPad(value: number) { | ||
return value < 10 ? `0${value}` : value; | ||
} | ||
private _normalizeText(value: string) { | ||
let str = value.toUpperCase().replace('Ç','C') as any | ||
return str['normalize']("NFD").replace(/[^A-Z0-9$%*+-\./:]/gi, ' ') | ||
} | ||
getBRCode() { | ||
let lines = [] | ||
//#region Payload Format Indicator | ||
lines.push(`0002 01`) | ||
//#endregion | ||
// Payload Format Indicator | ||
lines.push(this._getEMV('00', '01')) | ||
// caso seja transação única | ||
if (this._is_unique_transaction) | ||
lines.push('0102 12') | ||
// Is Unique Transaction? | ||
lines.push(this._getEMV('01', this._is_unique_transaction ? '12' : '11')) | ||
//#region Merchant Account Information - PIX | ||
let description = this._normalizeText(this._description || '') | ||
let extra = 14 + 8; | ||
if(description) { | ||
extra += 4 + description.length | ||
} | ||
if (this._key) { | ||
let contentKey = this._normalizeText(this._key) | ||
lines.push(`26${contentKey.length + extra}`) | ||
lines.push(`\t0014 br.gov.bcb.pix`) | ||
lines.push(`\t01${this._rightPad(contentKey.length)} ${contentKey}`) | ||
} else if(this._location) { | ||
let location = this._location | ||
lines.push(`26${location.length + extra}`) | ||
lines.push(`\t0014 br.gov.bcb.pix`) | ||
lines.push(`\t25${this._rightPad(location.length)} ${location}`) | ||
} else { | ||
// Merchant Account Information - Pix | ||
if (!this._key && !this._location) { | ||
throw 'É necessário informar uma URL ou então uma chave pix.' | ||
} | ||
lines.push(this._getEMV('26', this._generateAccountInformation())); | ||
// descricao | ||
if(this._description) { | ||
lines.push(`\t02${this._rightPad(description.length)} ${description}`) | ||
} | ||
// Merchant Category Code | ||
lines.push(this._getEMV('52', '0000')); | ||
//#endregion | ||
// Transaction Currency | ||
lines.push(this._getEMV('53', '986')); | ||
//#region Merchant Category Code | ||
lines.push(`5204 0000`) | ||
//#endregion | ||
//#region Transaction Currency | ||
lines.push(`5303 986`) // 989 = R$ | ||
//#endregion | ||
//#region Transaction Amount | ||
//Transaction Amount | ||
if (this._amout) { | ||
let valor = this._normalizeText(this._amout.toFixed(2).toString()) | ||
if (this._amout > 0) | ||
lines.push(`54${this._rightPad(valor.length)} ${valor}`) | ||
lines.push(this._getEMV('54', this._amout.toFixed(2))) | ||
} | ||
//#endregion | ||
//#region Country Code | ||
/** @length 02 */ | ||
lines.push(`5802 BR`) | ||
//#endregion | ||
// Country Code | ||
lines.push(this._getEMV('58', 'BR')) | ||
//#region Merchant Name | ||
// Merchant Name | ||
let receiver_name = this._normalizeText(this._receiver_name) | ||
lines.push(`59${this._rightPad(receiver_name.length)} ${receiver_name}`) | ||
//#endregion | ||
lines.push(this._getEMV('59', receiver_name)) | ||
//#region Merchant City | ||
// Merchant City | ||
let receiver_city = this._normalizeText(this._receiver_city) | ||
lines.push(`60${this._rightPad(receiver_city.length)} ${receiver_city}`) | ||
//#endregion | ||
lines.push(this._getEMV('60', receiver_city)) | ||
//#region Postal Code | ||
// Postal Code | ||
if (this._zip_code) { | ||
let zip_code = this._normalizeText(this._zip_code) | ||
lines.push(`61${this._rightPad(zip_code.length)} ${zip_code}`) | ||
lines.push(this._getEMV('61', zip_code)) | ||
} | ||
//#endregion | ||
//#region Additional Data Field | ||
if (this._identificator) { | ||
let transaction_identificator = this._normalizeText(this._identificator) | ||
lines.push(`62${transaction_identificator.length + 38}`) | ||
lines.push(`\t05${this._rightPad(transaction_identificator.length)} ${transaction_identificator}`) | ||
lines.push(`\t5030`) | ||
lines.push(`\t\t0017 br.gov.bcb.brcode`) | ||
lines.push(`\t\t0105 1.0.0`) | ||
} | ||
//#endregion | ||
// Additional Data Field | ||
lines.push(this._additionalDataField()) | ||
//#region Additional Data Field | ||
if (this._location) { | ||
lines.push(`6207`) | ||
lines.push(`\t0503 ***`) | ||
} | ||
//#endregion | ||
lines.push(`6304`) | ||
// fix: nome recebedor | ||
lines = lines.map(item => item.replace(' ', '')); | ||
let finalString = lines.join('').replace(/\t/gi, '') | ||
return finalString + CRC.computeCRC(finalString) | ||
const payloadString = lines.join(''); | ||
return payloadString + CRC.computeCRC(payloadString) | ||
} | ||
@@ -204,10 +156,10 @@ | ||
async saveQRCodeFile(out: string) { | ||
return await new Promise( async (res, rej) => { | ||
return await new Promise(async (res, rej) => { | ||
let base64 = await this.getQRCode() | ||
if(base64 == null) | ||
if (base64 == null) | ||
return rej(null); | ||
fs.writeFile(out, base64.replace(/^data:image\/png;base64,/, ""), 'base64', function (err) { | ||
if(err) rej(null) | ||
fs.writeFile(out, base64.replace(/^data:image\/png;base64,/, ""), 'base64', function (err) { | ||
if (err) rej(null) | ||
else res(true) | ||
@@ -219,2 +171,48 @@ }) | ||
private _normalizeText(value: string) { | ||
return value.normalize('NFD').replace(/[\u0300-\u036f]/g, "").replace(/[^A-Z\[\]0-9$@%*+-\./:]/gi, ' ') | ||
} | ||
private _generateAccountInformation(): string { | ||
const payload = []; | ||
payload.push(this._getEMV('00', 'br.gov.bcb.pix')); | ||
if (this._key) { | ||
payload.push(this._getEMV('01', this._normalizeText(this._key))); | ||
} | ||
if (this._location) { | ||
payload.push(this._getEMV('25', this._normalizeText(this._location))); | ||
} | ||
if (this._description) { | ||
payload.push(this._getEMV('02', this._normalizeText(this._description))); | ||
} | ||
return payload.join(''); | ||
} | ||
private _additionalDataField() { | ||
if (this._identificator) { | ||
let identificator = this._normalizeText(this._identificator) | ||
let reference_label = this._getEMV('05', identificator) | ||
// não funciona no inter/itau. | ||
// let gui = this._getEMV('00', 'br.gov.bcb.brcode') | ||
// let version = this._getEMV('01', '1.0.0') | ||
// let payment_system_specific_template = this._getEMV('50', gui + version) | ||
return this._getEMV('62', reference_label); | ||
} else { | ||
return this._getEMV('62', this._getEMV('05', '***')); | ||
} | ||
} | ||
private _getEMV(id: string, string: string) { | ||
const len = string.length.toString().padStart(2, '0'); | ||
return `${id}${len}${string}`; | ||
} | ||
} |
{ | ||
"name": "gpix", | ||
"version": "1.1.2", | ||
"version": "1.1.3", | ||
"description": "Library written in nodejs to generate PIX br-code and qr-code.", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
@@ -27,2 +27,3 @@ # GPIX | ||
pix.setDescription('Donation with defined amount - GPIX') // optional | ||
pix.isUniqueTransaction(true) // optional | ||
pix.setAmount(5.0) // optional | ||
@@ -36,3 +37,3 @@ | ||
pix.setReceiverCity('Rio Preto') | ||
pix.setKey('fcba8826-cbff-46e2-8c40-1b39896402a8') | ||
pix.setKey('nubank@hiago.me') | ||
pix.setDescription('Donation without defined amount - GPIX') // optional | ||
@@ -39,0 +40,0 @@ |
{ | ||
"sourceMap": true, | ||
"exclude": [ | ||
"node_modules" | ||
"node_modules", | ||
"dist" | ||
], | ||
@@ -6,0 +7,0 @@ "compilerOptions": { |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
81
43291
1162