UNPKG

pix-utils

Version:

Set of tools to parse, generate and validate payments of Brazil Instant Payment System (Pix)

93 lines 9.31 kB
import { computeCRC } from './crc'; import { PixElementType } from './types/pixElements'; import { EmvAdditionalDataSchema, EmvMaiSchema, EmvSchema, TagsWithSubTags, } from './types/pixEmvSchema'; import { normalizeCity, normalizeName } from './utils/textParser'; import zeroPad from './utils/zeroPad'; function generateEmvElement(elementId, value) { if (!value) return ''; const parsedElementId = zeroPad(elementId, 2); const parsedLength = zeroPad(value.length, 2); return `${parsedElementId}${parsedLength}${value}`; } function generateMAI(elements) { if (elements.type === PixElementType.STATIC) { return [ generateEmvElement(EmvMaiSchema.TAG_MAI_GUI, EmvMaiSchema.BC_GUI), generateEmvElement(EmvMaiSchema.TAG_MAI_PIXKEY, elements.pixKey), generateEmvElement(EmvMaiSchema.TAG_MAI_INFO_ADD, elements.infoAdicional), generateEmvElement(EmvMaiSchema.TAG_MAI_FSS, elements.fss), ].join(''); } else if (elements.type === PixElementType.DYNAMIC) { return [ generateEmvElement(EmvMaiSchema.TAG_MAI_GUI, EmvMaiSchema.BC_GUI), generateEmvElement(EmvMaiSchema.TAG_MAI_URL, elements.url), ].join(''); } return undefined; } function generateAdditionalData(txid) { return generateEmvElement(EmvAdditionalDataSchema.TAG_TXID, txid || '***'); } export function createEmv(elements) { if (![PixElementType.STATIC, PixElementType.DYNAMIC].includes(elements.type)) return 'INVALID'; const emvElements = [ generateEmvElement(EmvSchema.TAG_INIT, '01'), generateEmvElement(EmvSchema.TAG_ONETIME, elements.oneTime ? '12' : ''), generateEmvElement(EmvSchema.TAG_MAI, generateMAI(elements)), generateEmvElement(EmvSchema.TAG_MCC, elements.merchantCategoryCode), generateEmvElement(EmvSchema.TAG_TRANSACTION_CURRENCY, elements.transactionCurrency), elements.type === PixElementType.STATIC ? generateEmvElement(EmvSchema.TAG_TRANSACTION_AMOUNT, elements.transactionAmount > 0 ? elements.transactionAmount.toFixed(2) : '') : '', generateEmvElement(EmvSchema.TAG_COUNTRY_CODE, elements.countryCode), generateEmvElement(EmvSchema.TAG_MERCHANT_NAME, normalizeName(elements.merchantName)), generateEmvElement(EmvSchema.TAG_MERCHANT_CITY, normalizeCity(elements.merchantCity)), generateEmvElement(EmvSchema.TAG_ADDITIONAL_DATA, generateAdditionalData(elements.type === PixElementType.STATIC ? elements.txid : '')), generateEmvElement(EmvSchema.TAG_CRC, '0000'), ]; const generatedEmv = emvElements.join(''); return generatedEmv.replace(/\w{4}$/, computeCRC(generatedEmv)); } export function parseEmv({ emvCode, currentIndex = 0, currentData = {}, }) { const tag = +emvCode.substring(currentIndex, currentIndex + 2); const length = Number(emvCode.substring(currentIndex + 2, currentIndex + 4)); const value = emvCode.substring(currentIndex + 4, currentIndex + 4 + length); if (!length || !value.length || length !== value.length) { return { isValid: false, rawTags: currentData, }; } const newData = { ...currentData, [tag]: { tag: tag, length: length, value: value, ...(Object.values(TagsWithSubTags).includes(tag) ? { subTags: parseEmv({ emvCode: value }) } : {}), }, }; if (currentIndex + 4 + length === emvCode.length) { return { isValid: true, rawTags: newData, getTag: (tag) => newData?.[Number(tag)]?.value, getSubTag: (tag, mainTag) => newData?.[Number(mainTag)]?.subTags?.getTag(Number(tag)), }; } else { return parseEmv({ emvCode, currentIndex: currentIndex + 4 + length, currentData: newData, }); } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZW12SGFuZGxlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9lbXZIYW5kbGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxPQUFPLENBQUM7QUFDbkMsT0FBTyxFQUFlLGNBQWMsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQ2xFLE9BQU8sRUFDTCx1QkFBdUIsRUFDdkIsWUFBWSxFQUNaLFNBQVMsRUFFVCxlQUFlLEdBQ2hCLE1BQU0sc0JBQXNCLENBQUM7QUFDOUIsT0FBTyxFQUFFLGFBQWEsRUFBRSxhQUFhLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUNsRSxPQUFPLE9BQU8sTUFBTSxpQkFBaUIsQ0FBQztBQUV0QyxTQUFTLGtCQUFrQixDQUFDLFNBQWlCLEVBQUUsS0FBYTtJQUMxRCxJQUFJLENBQUMsS0FBSztRQUFFLE9BQU8sRUFBRSxDQUFDO0lBQ3RCLE1BQU0sZUFBZSxHQUFHLE9BQU8sQ0FBQyxTQUFTLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDOUMsTUFBTSxZQUFZLEdBQUcsT0FBTyxDQUFDLEtBQUssQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDOUMsT0FBTyxHQUFHLGVBQWUsR0FBRyxZQUFZLEdBQUcsS0FBSyxFQUFFLENBQUM7QUFDckQsQ0FBQztBQUVELFNBQVMsV0FBVyxDQUFDLFFBQXFCO0lBQ3hDLElBQUksUUFBUSxDQUFDLElBQUksS0FBSyxjQUFjLENBQUMsTUFBTSxFQUFFO1FBQzNDLE9BQU87WUFDTCxrQkFBa0IsQ0FBQyxZQUFZLENBQUMsV0FBVyxFQUFFLFlBQVksQ0FBQyxNQUFNLENBQUM7WUFDakUsa0JBQWtCLENBQUMsWUFBWSxDQUFDLGNBQWMsRUFBRSxRQUFRLENBQUMsTUFBTSxDQUFDO1lBQ2hFLGtCQUFrQixDQUFDLFlBQVksQ0FBQyxnQkFBZ0IsRUFBRSxRQUFRLENBQUMsYUFBYSxDQUFDO1lBQ3pFLGtCQUFrQixD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