vietqrjs

1.1.3 • Public • Published

VietQR JS

VietQR Logo      Napas 247 logo

Overview

This library be implemented follow the VietQR specified document from NAPAS on vietqr.net

Vietqrjs library supports some features:

  • Create QR string|code from data: account number, account name, bank ID, bank name, transaction amount, description ...
  • Decrypt an QR string (string read from QR code image) to get information for payment.(from v1.1.0)

Vietqrjs supports 4 service types:

  • Cash withdraw service (QRCASH)
  • Products payment service (QRPUSH)
  • transfer by account number (QRIBFTTA)
  • transfer by card number (QRIBFTTC)

Note:

In document from Napas, each service code type required some properties in Additional Data field. But in this library, all properties in Additional Data field is optional and not validate it with service code type. You can write validate in your source-code if you need.

Buy me a coffee

If you feel my lib is useful, buy me a coffee, thanks! MoMo Wallet transfer QR code:

Change Logs:

v1.1.3

  • Update donation information :)

v1.1.2

  • Add the 2nd parameter for VietQrV1Decryptor decrypt function to support return lean|full decrypted QR data object
  • Set the setmerchantCategoryCode and getQrCodeString function in VietQRV1Builder class is deprecated, instead by setMerchantCategoryCode and getQrString function
  • Update function generateQR of VietQRV1Builder class
  • Update docs on README

v1.1.1

  • Fixed some bugs related to function check valid CRC code of QR string in Decryptor class

v1.1.0

  • Add VietQrV1Decryptor to support decrypt QR string to get Merchant/Consumer information.
  • Update Unit tests for VietQRV1Builder and VietQrV1Decryptor functions

v1.0.2

  • Add new service codes: QRPUSH and QRCASH

Installation

npm i --save vietqrjs

Interfaces

interface IVietQrDataV1

interface IVietQrDataV1 {
  version: VietQrVersion; // ID 00
  initMethod: VietQrInitiateMethod; // ID 01
  merchantAccInfo: IMerchantAccountInfo; // ID = 38
  merchantCategoryCode?: MerchantCategoryCode | string | null | undefined; // ID 52
  txnCurrency: number; // ID 53
  txnAmount?: string; // ID 54
  tipConvenienceIndicator?: TipOrConvenienceIndicatorType | string | null | undefined; // ID 55
  convenienceFeeFixed?: StringOrNot; // ID 56
  convenienceFeePercentage?: StringOrNot; // ID 57
  countryCode: string; // ID 58
  merchantName?: StringOrNot; // ID 59
  merchantCity?: StringOrNot; // ID 60
  postalCode?: StringOrNot; // ID 61
  additionalData?: IAdditionalData | null | undefined; // ID 62
  languageTemplate?: ILanguageTemplate | null | undefined; // ID 64
  crcCode: string; // ID 63
}

interface IBasicVietQrData

interface IBasicVietQrData {
  acquierId: BankBIN; // ID DVCNTT
  merchantId: string; // Tài khoản/Số thẻ thụ hưởng
  serviceCode?: ServiceCode;
  amount?: number;
  txnDescription?: string;
}

interface IMerchantAccountInfo

interface IMerchantAccountInfo {
  guid?: GUID | string; // ID 38 - 00 (Required Field)
  beneficiaryOrg: IBeneficiaryOrganiation; // ID 38 - 01 (Required Field)
  serviceCode?: ServiceCode; // ID 38 - 02 (Conditional Field)
}

interface IBeneficiaryOrganiation

interface IBeneficiaryOrganiation {
  acquierId: BankBIN | string; // ID 38 - 01 - 00 (Required Field)
  merchantId: string; // ID 38 - 01 - 01 (Required Field)
}

interface IAdditionalData

interface IAdditionalData {
  billNumber?: StringOrNot; // ID 62 - 01 (Conditional Field)
  mobileNumber?: StringOrNot; // ID 62 - 02 (Conditional Field)
  storeLabel?: StringOrNot; // ID 62 - 03 (Optional Field)
  loyaltyNumber?: StringOrNot; // ID 62 - 04 (Optional Field)
  referenceLabel?: StringOrNot; // ID 62 - 05 (Conditional Field)
  customerLabel?: StringOrNot; // ID 62 - 06 (Conditional Field)
  terminalLabel?: StringOrNot; // ID 62 - 07 (Optional Field)
  purposeOfTxn?: StringOrNot; // ID 62 - 08 (Conditional Field)
  additionalConsumerDataReq?: StringOrNot; // ID 62 - 09 (Optional Field)
}

interface ILanguageTemplate

interface ILanguageTemplate {
  preference: string; // ID 64 - 00 (Required Field)
  merchantName: string; // ID 64 - 01 (Required Field)
  merchantCity?: StringOrNot; // ID 64 - 02 (Optional Field)
}

interface IDecryptedQrDataOptions

interface IDecryptedQrDataOptions {
  /**
   * Remove all decrypted data object fields is optional and have value is empty or undefined
   * @default true
   */
  lean?: boolean;
}

interface

interface IGenerateQROptions {
  logo?: string; // path to image file or base64 image string, if null will be render vietQR logo
  margin?: number; // margin of QR code and image frame. default is 4
  width?: number; // width of canvas object to draw QR code // default is 250
  bgColor?: string; // background color of QR code - default is '#ffffff'
  color?: string; // color of QR code - default is '#000000'
  errorCorrectionLevel?: 'L' | 'M' | 'Q' | 'H'; // default is 'H'
}

Usage

VietQRV1Builder

Functions:

  • quickBuild(data; IBasicVietQrData): VietQRV1Builder; // quick build QR string from minimum required VietQR data
  • getQrString(): string; // Get the result of quickbuild or build function from builder
  • build(): VietQRV1Builder; // build the QR string after set some VietQR data
  • refresh(): VietQRV1Builder; // Refresh VietQR data of builder to initialization
  • getQrCodeString(): string; // (deprecated) // Get the result of quickbuild or build function from builder
  • generateQR(options?: IGenerateQROptions): string; // generate base64 QR image
  • setMerchantAccountInfo(data: IMerchantAccountInfo): VietQRV1Builder;
  • setMerchantName(merchantName: string): VietQRV1Builder;
  • setMerchantCity(merchantCity: string): VietQRV1Builder;
  • setTxnCurrency(currencyCode: number): VietQRV1Builder;
  • setTxnCountry(countryCode: string): VietQRV1Builder;
  • setMerchantCategoryCode(mcc: string): VietQRV1Builder;
  • setAdditionalData(data: IAdditionalData): VietQRV1Builder;
  • setLanguageTemplate(template: ILanguageTemplate): VietQRV1Builder;
  • setTxnDescription(description: string): VietQRV1Builder;
  • setTxnAmount(amount: number): VietQRV1Builder;
  • setPostalCode(postalCode: string): VietQRV1Builder;

Quick generate QR string

Example:

import {VietQRV1Builder, BankBIN, ServiceCode} from 'vietqrjs';
const builder = new VietQRV1Builder();
const qrDataString = builder.quickBuild({ // IBasicVietQrData
    acquierId: BankBIN.VIETINBANK, // ID DVCNTT
    merchantId: '', // Account number
    serviceCode: ServiceCode.BY_ACCOUNT_NUMBER,
  }).getQrString();

Build an QR string to render static QR code with account number

Example:

import {VietQRV1Builder, BankBIN, ServiceCode} from 'vietqrjs';
const builder = new VietQRV1Builder();
const qrDataStr = builder.setMerchantAccountInfo({
  // IMerchantAccountInfo
    beneficiaryOrg: { // IBeneficiaryOrganiation
      acquierId: BankBIN.VIETCOMBANK,
      merchantId: '03123445xxx', // account number
    },
    serviceCode: ServiceCode.BY_ACCOUNT_NUMBER,
  })
  .build()
  .getQrString();

Build an QR string to render static QR code with card number

Example:

import {VietQRV1Builder, BankBIN, ServiceCode} from 'vietqrjs';
const builder = new VietQRV1Builder();
const qrString = builder.setMerchantAccountInfo({
    beneficiaryOrg: {
      acquierId: BankBIN.ACB,
      merchantId: '040812344454xxx', // card number
    },
    serviceCode: ServiceCode.BY_CARD_NUMBER,
  })
  .build()
  .getQrString();

Build an QR string to render QR code to cash withdrawl

Example:

import {VietQRV1Builder, BankBIN, ServiceCode} from 'vietqrjs';
const vietqr = new VietQRV1Builder();
const qrString = vietqr.setMerchantAccountInfo({
    beneficiaryOrg: {
      acquierId: BankBIN.ACB,
      merchantId: '12345678', // ATM ID
    },
    serviceCode: ServiceCode.BY_CASH_WITHDRAWL_SERVICE,
  })
  .setMerchantName('NGUYEN VAN A')
  .setMerchantCity('HA NOI')
  .setTxnCurrency()
  .setTxnCountry()
  .setMerchantCategoryCode(MerchantCategoryCode.FINANCIAL_INSTITUTIONS_WITH_CASH_DISBURSEMENTS)
  .setAdditionalData({
    referenceLabel: '201901091557142283847',
    terminalLabel: '00001111',
  }).build()
  .getQrString(); 
console.log(qrString);
// expect
// 00020101021138500010A000000727012200069704160108123456780206QRCASH5204601153037045802VN5912NGUYEN VAN A6006HA NOI6237052120190109155714228384707080000111163049CE4

Build an QR string to render dynamic QR code with account number

Example:

import {VietQRV1Builder, BankBIN, ServiceCode} from 'vietqrjs';
const builder = new VietQRV1Builder();
const qrDataStr = builder.setMerchantAccountInfo({
    beneficiaryOrg: {
      acquierId: BankBIN.MB_BANK,
      merchantId: '03123445xxx', // account number
    },
    serviceCode: ServiceCode.BY_ACCOUNT_NUMBER,
  })
  .setTxnAmount(86000)
  .setMerchantName('Cua hang tien loi') // optional
  .setMerchantCity('NANOI') // optional
  .setPostalCode('10000') // optional
  .setTxnDescription('Thanh toan hoa don') // optional
  .setAdditionalData({  // optional
    billNumber: 'B123456',
    storeLabel: 'NPS124',
  })
  .build()
  .getQrString();

Build QR code from payment account information

Example:

import {VietQRV1Builder, BankBIN, ServiceCode} from 'vietqrjs';
const builder = new VietQRV1Builder();
const qrBase64Image = await builder
 .quickBuild({
   acquierId: BankBIN.TP_BANK, // ID DVCNTT
   merchantId: '123456789', // Tài khoản/Số thẻ thụ hưởng
   serviceCode: ServiceCode.BY_ACCOUNT_NUMBER,
 })
 .generateQR({
   width: 300,
   margin: 2,
   color: '#555555',
   bgColor: '#EEEEEE',
 });
console.log(qrBase64Image);
// data:image/png;base64,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

VietQrV1Decryptor (supported from v1.1.0)

Decrypt QR string to get information for payment.

Check CRC checksum of QR string

isValidChecksum(qrString: string): boolean;

Example:

import { VietQrV1Decryptor } from 'vietqrjs';
const decryptor = new VietQrV1Decryptor();
const isValid = decryptor.isValidChecksum('00020101021238500010A000000727012200069704030108123456780206QRCASH5204601153037045802VN5915NGUYEN HUU HUAN6005HANOI6105100006237052120190109155714228384707080000111164260002en0107shop vn0205Hanoi63047611');
console.log(isValid) // false

Decrypt QR string to get information for payment

decrypt(qrString: string, options?: IDecryptedQrDataOptions): IVietQrDataV1

Example:

import { VietQrV1Decryptor } from 'vietqrjs';
const decryptor = new VietQrV1Decryptor();
// decrypt QR string and get full fields QR data 
const qrData = decryptor.decrypt(
  '00020101021238500010A000000727012200069704030108123456780206QRCASH5204601153037045802VN5915NGUYEN HUU HUAN6005HANOI6105100006237052120190109155714228384707080000111164260002en0107shop vn0205Hanoi630476DA',
  { lean: false },
);
console.log(qrData);
// {
//   version: '01',
//   initMethod: '12',
//   merchantAccInfo: {
//     guid: 'A000000727',
//     beneficiaryOrg: {
//       acquierId: '970403',
//       merchantId: '12345678'
//     },
//     serviceCode: 'QRCASH'
//   },
//   merchantCategoryCode: '6011',
//   txnCurrency: 704,
//   txnAmount: undefined,
//   tipConvenienceIndicator: undefined,
//   convenienceFeeFixed: undefined,
//   convenienceFeePercentage: undefined,
//   countryCode: 'VN',
//   merchantName: 'NGUYEN HUU HUAN',
//   merchantCity: 'HANOI',
//   postalCode: '10000',
//   additionalData: {
//     billNumber: undefined,
//     mobileNumber: undefined,
//     storeLabel: undefined,
//     loyaltyNumber: undefined,
//     referenceLabel: '201901091557142283847',
//     customerLabel: undefined,
//     terminalLabel: '00001111',
//     purposeOfTxn: undefined,
//     additionalConsumerDataReq: undefined
//   },
//   languageTemplate: {
//     preference: 'en',
//     merchantName: 'shop vn',
//     merchantCity: 'Hanoi',
//   },
//   crcCode: '76DA'
// }
const leanQrData = decryptor.decrypt(
  '00020101021238500010A000000727012200069704030108123456780206QRCASH5204601153037045802VN5915NGUYEN HUU HUAN6005HANOI6105100006237052120190109155714228384707080000111164260002en0107shop vn0205Hanoi630476DA',
);
console.log(leanQrData);
// {
//   version: '01',
//   initMethod: '12',
//   merchantAccInfo: {
//     guid: 'A000000727',
//     beneficiaryOrg: {
//       acquierId: '970403',
//       merchantId: '12345678'
//     },
//     serviceCode: 'QRCASH'
//   },
//   merchantCategoryCode: '6011',
//   txnCurrency: 704,
//   countryCode: 'VN',
//   merchantName: 'NGUYEN HUU HUAN',
//   merchantCity: 'HANOI',
//   postalCode: '10000',
//   additionalData: {
//     referenceLabel: '201901091557142283847',
//     terminalLabel: '00001111',
//   },
//   languageTemplate: {
//     preference: 'en',
//     merchantName: 'shop vn',
//     merchantCity: 'Hanoi',
//   },
//   crcCode: '76DA'
// }

Package Sidebar

Install

npm i vietqrjs

Weekly Downloads

84

Version

1.1.3

License

MIT

Unpacked Size

297 kB

Total Files

31

Last publish

Collaborators

  • trantuan94