1.1.3 • Published 4 months ago

vietqrjs v1.1.3

Weekly downloads
-
License
MIT
Repository
github
Last release
4 months ago

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)

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'
// }
1.1.3

4 months ago

1.1.2

4 months ago

1.1.1

4 months ago

1.1.0

4 months ago

1.0.2

5 months ago

1.0.1

3 years ago

1.0.0

3 years ago

2.0.0

3 years ago