UNPKG

@trowdev/juno-pix-bacen

Version:

Lib para gerar pagamentos com a API do BCB ou com a API do Juno

193 lines (156 loc) 6.13 kB
import computeCRC from "./crc"; /* BR Code Generation Manual Available at: https://www.bcb.gov.br/content/estabilidadefinanceira/forumpireunioes/AnexoI-PadroesParaIniciacaodoPix.pdf */ function addLeftZero(value: number): string | number { return value < 10 ? `0${value}` : value; } function formatText(value: string): string { var str = value.toUpperCase().replace("Ç", "C"); return str.normalize("NFD").replace(/[^A-Z0-9$%*+-\./:]/gi, " "); } type ParamsStatic = { merchantKey: string merchantName: string amount?: number merchantCity?: string merchantCep?: string description?: string identifier?: string isUnique?: boolean } export function staticPix({ merchantKey = "", merchantName = "", amount, merchantCity, merchantCep, description, identifier, isUnique }: ParamsStatic): string { // Get formatted variables const merchantNameF = formatText(merchantName); const merchantCityF = formatText(merchantCity || ""); const merchantCepF = formatText(merchantCep || ""); const descriptionF = formatText(description || ""); const identifierF = formatText(identifier || ""); const amountF = amount ? amount.toFixed(2).toString() : "0"; // Check for input problems if (merchantKey.length < 1 || merchantNameF.length < 1) { throw "merchantKey and merchantName are mandatory fields"; } if (merchantNameF.length > 25) { throw "merchantName has a max of 25 characters"; } if (merchantCityF.length > 15) { throw "merchantCity has a max of 15 characters"; } if (amountF.length > 13) { throw "Amount has a maximum of 13 characters"; } // Start crafting the code var brCode = []; brCode.push("000201"); // Payload Format Indicator if (isUnique) brCode.push("010212"); // BRCode can be used only once var extra = 22; if (descriptionF !== "") { extra += descriptionF.length + 4; } brCode.push(`26${merchantKey.length + extra}`); brCode.push("0014br.gov.bcb.pix"); // GUI brCode.push(`01${addLeftZero(merchantKey.length)}${merchantKey}`); // Pix Key if (descriptionF !== "") { brCode.push(`02${addLeftZero(descriptionF.length)}${descriptionF}`); // Description } brCode.push("52040000"); // Merchant Category Code (0000 = não informado) brCode.push("5303986"); // Transaction Currency (989 = R$) if (parseFloat(amountF) >= 0.01) { brCode.push(`54${addLeftZero(amountF.length)}${amountF}`); // R$ Amount } brCode.push("5802BR"); // Country Code brCode.push(`59${addLeftZero(merchantNameF.length)}${merchantNameF}`); // Merchant Name if (merchantCityF !== "") { brCode.push(`60${addLeftZero(merchantCityF.length)}${merchantCityF}`); // Merchant City } if (merchantCepF !== "") { brCode.push(`61${addLeftZero(merchantCepF.length)}${merchantCepF}`); // Merchant CEP } if (identifierF !== "") { brCode.push(`62${identifierF.length + 38}`) brCode.push(`05${addLeftZero(identifierF.length)}${identifierF}`) // Additional Data Field } brCode.push("6304"); // CRC16 var brCodeString = brCode.join(""); return `${brCodeString}${computeCRC(brCodeString)}`; } type ParamsDinamic = { merchantName: string merchantCity?: string merchantCep?: string amount: number location: string identifier?: string isUnique?: boolean } export function dinamicPix({ merchantName, merchantCity, merchantCep, amount, location, identifier, isUnique }: ParamsDinamic): string { // Get formatted variables const merchantNameF = formatText(merchantName); const merchantCityF = formatText(merchantCity || ""); const merchantCepF = formatText(merchantCep || ""); const amountF = amount ? amount.toFixed(2).toString() : "0"; const locationF = location.replace('https://', '') const identifierF = formatText(identifier || ""); // Check for input problems if (merchantNameF.length < 1 || locationF.length < 1 || amountF.length < 1) { throw "merchantName, amount and location are mandatory fields"; } if (merchantNameF.length > 25) { throw "merchantName has a max of 25 characters"; } if (merchantCityF.length > 15) { throw "merchantCity has a max of 15 characters"; } if (amountF.length > 13) { throw "Amount has a maximum of 13 characters"; } if (parseFloat(amountF) < 0.01) { throw "Amount needs to be at least 0.01"; } // Start crafting the code var brCode = []; brCode.push("000201"); // Payload Format Indicator if (isUnique) brCode.push("010212"); // BRCode can be used only once brCode.push(`26${locationF.length + 22}`) brCode.push("0014br.gov.bcb.pix") brCode.push(`25${addLeftZero(locationF.length)}${locationF}`) // Location brCode.push("52040000"); // Merchant Category Code (0000 = não informado) brCode.push("5303986"); // Transaction Currency (989 = R$) brCode.push(`54${addLeftZero(amountF.length)}${amountF}`); // R$ Amount brCode.push("5802BR"); // Country Code brCode.push(`59${addLeftZero(merchantNameF.length)}${merchantNameF}`); // Merchant Name if (merchantCityF !== "") { brCode.push(`60${addLeftZero(merchantCityF.length)}${merchantCityF}`); // Merchant City } if (merchantCepF !== "") { brCode.push(`61${addLeftZero(merchantCepF.length)}${merchantCepF}`); // Merchant CEP } if (identifierF !== "") { brCode.push(`62${identifierF.length + 38}`) brCode.push(`05${addLeftZero(identifierF.length)}${identifierF}`) } else { brCode.push("62070503***") // Additional Data Field } brCode.push("6304"); // CRC16 var brCodeString = brCode.join(""); return `${brCodeString}${computeCRC(brCodeString)}`; }