Last active
July 7, 2024 06:46
-
-
Save mynamebvh/1eeecbcd1d964dd7a4037373ddec23bb to your computer and use it in GitHub Desktop.
Generate QR Banking
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const VietQR = require("./vietQR"); | |
const vietQR = new VietQR(); | |
vietQR | |
.setBeneficiaryOrganization("970423", "mynamebvh") | |
.setTransactionAmount("50000") | |
.setAdditionalDataFieldTemplate("test"); | |
console.log(vietQR.build()); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class VietQR { | |
constructor() { | |
this.payloadFormatIndicator = "000201"; | |
this.pointOfInitiationMethod = "010212"; | |
this.consumerAccountInformation = ""; | |
this.guid = "0010A000000727"; | |
this.serviceCode = "0208QRIBFTTA"; | |
this.transactionCurrency = "5303704"; | |
this.transactionAmount = ""; | |
this.countryCode = "5802VN"; | |
this.additionalDataFieldTemplate = ""; | |
this.crc = ""; | |
} | |
convertLength(str) { | |
const num = parseInt(str); | |
return num < 10 ? `0${num}` : num; | |
} | |
setTransactionAmount(money) { | |
const length = this.convertLength(money.length); | |
this.transactionAmount = `54${length}${money}`; | |
return this; | |
} | |
setBeneficiaryOrganization(acquierID, consumerID) { | |
const acquierLength = this.convertLength(acquierID.length); | |
const acquier = `00${acquierLength}${acquierID}`; | |
const consumerLength = this.convertLength(consumerID.length); | |
const consumer = `01${consumerLength}${consumerID}`; | |
const beneficiaryOrganizationLength = this.convertLength( | |
`${acquier}${consumer}`.length | |
); | |
const consumerAccountInformationLength = this.convertLength(beneficiaryOrganizationLength + 30); | |
this.consumerAccountInformation = `38${consumerAccountInformationLength}${this.guid}01${beneficiaryOrganizationLength}${acquier}${consumer}0208QRIBFTTA`; | |
return this; | |
} | |
setAdditionalDataFieldTemplate(content) { | |
const contentLength = this.convertLength(content.length); | |
const additionalDataFieldTemplateLength = this.convertLength(content.length + 4); | |
this.additionalDataFieldTemplate = `62${additionalDataFieldTemplateLength}08${contentLength}${content}`; | |
return this; | |
} | |
calcCRC(str) { | |
const crcTable = [ | |
0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, 0x8108, | |
0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef, 0x1231, 0x0210, | |
0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6, 0x9339, 0x8318, 0xb37b, | |
0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de, 0x2462, 0x3443, 0x0420, 0x1401, | |
0x64e6, 0x74c7, 0x44a4, 0x5485, 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, | |
0xf5cf, 0xc5ac, 0xd58d, 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, | |
0x5695, 0x46b4, 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, | |
0xc7bc, 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823, | |
0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b, 0x5af5, | |
0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12, 0xdbfd, 0xcbdc, | |
0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a, 0x6ca6, 0x7c87, 0x4ce4, | |
0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41, 0xedae, 0xfd8f, 0xcdec, 0xddcd, | |
0xad2a, 0xbd0b, 0x8d68, 0x9d49, 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, | |
0x2e32, 0x1e51, 0x0e70, 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, | |
0x9f59, 0x8f78, 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, | |
0xe16f, 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067, | |
0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e, 0x02b1, | |
0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256, 0xb5ea, 0xa5cb, | |
0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d, 0x34e2, 0x24c3, 0x14a0, | |
0x0481, 0x7466, 0x6447, 0x5424, 0x4405, 0xa7db, 0xb7fa, 0x8799, 0x97b8, | |
0xe75f, 0xf77e, 0xc71d, 0xd73c, 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, | |
0x7676, 0x4615, 0x5634, 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, | |
0xb98a, 0xa9ab, 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, | |
0x28a3, 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a, | |
0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92, 0xfd2e, | |
0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9, 0x7c26, 0x6c07, | |
0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1, 0xef1f, 0xff3e, 0xcf5d, | |
0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8, 0x6e17, 0x7e36, 0x4e55, 0x5e74, | |
0x2e93, 0x3eb2, 0x0ed1, 0x1ef0, | |
]; | |
var crc = 0xffff; | |
var j, i; | |
for (i = 0; i < str.length; i++) { | |
let c = str.charCodeAt(i); | |
if (c > 255) { | |
throw new RangeError(); | |
} | |
j = (c ^ (crc >> 8)) & 0xff; | |
crc = crcTable[j] ^ (crc << 8); | |
} | |
return (crc ^ 0) & 0xffff; | |
} | |
build() { | |
const contentQR = `${this.payloadFormatIndicator}${this.pointOfInitiationMethod}${this.consumerAccountInformation}${this.transactionCurrency}${this.transactionAmount}${this.countryCode}${this.additionalDataFieldTemplate}6304`; | |
const crc = this.calcCRC(contentQR).toString(16).toUpperCase(); | |
return `${contentQR}${crc}`; | |
} | |
} | |
module.exports = VietQR; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment