import qrcode from "qrcode"; import type { QRCodeToDataURLOptions } from "qrcode"; import { crc16ccitt } from "crc"; interface PixParams { pixKey: string; merchantCity?: string; merchantName?: string; value?: number; transactionId?: string; message?: string; cep?: string; currency?: number; countryCode?: string; } const pix = ({ pixKey, merchantCity = "city", merchantName = "name", value, message, cep, transactionId = "***", currency = 986, countryCode = "BR", }: PixParams) => { const payloadKeyString = generatePixKey(pixKey, message); const payload: string[] = [ formatEMV("00", "01"), //Payload Format Indicator formatEMV("26", payloadKeyString), // Merchant Account Information formatEMV("52", "0000"), //Merchant Category Code formatEMV("53", String(currency)), // Transaction Currency ]; if (String(value) === "0") { value = undefined; } if (value) { payload.push(formatEMV("54", value.toFixed(2))); } payload.push(formatEMV("58", countryCode.toUpperCase())); // Country Code payload.push(formatEMV("59", merchantName)); // Merchant Name payload.push(formatEMV("60", merchantCity)); // Merchant City if (cep) { payload.push(formatEMV("61", cep)); // Postal Code } payload.push(formatEMV("62", formatEMV("05", transactionId))); // Additional Data Field Template payload.push("6304"); const stringPayload = payload.join(""); const crcResult = crc16ccitt(stringPayload) .toString(16) .toUpperCase() .padStart(4, "0"); const payloadPIX = `${stringPayload}${crcResult}`; return { payload: (): string => payloadPIX, base64QrCode: (options?: QRCodeToDataURLOptions): Promise => qrcode.toDataURL(payloadPIX, options), }; }; const generatePixKey = (pixKey: string, message?: string): string => { const payload: string[] = [ formatEMV("00", "BR.GOV.BCB.PIX"), formatEMV("01", pixKey), ]; if (message) { payload.push(formatEMV("02", message)); } return payload.join(""); }; const formatEMV = (id: string, param: string): string => { const len = param.length.toString().padStart(2, "0"); return `${id}${len}${param}`; }; export { type PixParams, pix };