vietqr-parser

command module
v0.1.5 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 28, 2024 License: MIT Imports: 7 Imported by: 0

README

QRPay EMVCo for VietQR

A Go package to help build and parse EMVCo VietQR easier with few lines only. This package was based on format of Napas about VietQR which called EMVCo to build QR Code at VietNam. Bank applications will follow this standard to parse info of EMVCo QR and fill in all necessary information to IBFT transfer to account.

Beside that, this package also supports build some more complex use cases of QR such as Visa, Master, UPI, build QR with amount, description, tip and fee as well, ...etc

Examples for build basic QR Code

Build QR with some basic information like beneficiary account, bank name

basicQRPay := qrpay.BuildQRPay(constants.Bin_VCB, "0881000458086")
	qr, err := basicQRPay.GenerateQRCode()
	if err != nil {
		fmt.Println("generate qr code failed", err)
		os.Exit(1)
	}

	fmt.Printf("QR Code: %s\n", qr)

	qrPay, err := qrpay.ParseQRPay(qr)
	if err != nil {
		fmt.Printf("parse VietQR ERROR: %v\n", err)
		os.Exit(1)
	}

	fmt.Printf("Amount: %v\n", qrPay.Amount)
	data, _ := json.Marshal(qrPay)
	fmt.Println(string(data))

  // Print out
  /**
    QR Code: 00020001021238570010A00000072701270006970436011308810004580860208QRIBFTTA53037045802VN6304CD60
    Amount: 0
    {"Version":"00","initiation_method":"12","merchant_info":{"name":"","city":"","country_code":"VN","postal_code":"","napas_provider":{"id":"A000000727","bank_bin":"970436","transfer_to":"0881000458086","method":"QRIBFTTA"},"master_account":"","visa_account":"","jcb_account":"","upi_account":"","category_code":""},"currency_code":"704","amount":0,"tip_and_fee_type":"","tip_and_fee_amount":0,"tip_and_fee_percent":0,"description":"","addition_data":{}}
   **/

Please using this tool https://vi.qr-code-generator.com/ and paste the QR code to generating. We will have the QR as below which accepted by all VietNam bank applications that allow users input amont of money and make the transfer complete.

Basic VietQR

The IBFT transfer screen of TPBank when scanning above QR Code:

Example for build more complex QR

Complex QR Example

With more information like amount, currency code, description, tip and fee, merchant category code, merchant city, postal code, ...etc we can using code as below:

	complexQRPay := qrpay.BuildQRPay(
		constants.Bin_VCB,
		"0881000458086",
		qrpay.WithAmount(69000),
		qrpay.WithCurrencyCode(fmt.Sprintf("%d", countries.Singapore.Currency())),
		qrpay.WithDescription("Thanh toán mua sữa"),
		qrpay.WithTipAndFeeType(models.PredefinedTip),
		qrpay.WithTipAndFeeAmount(1000),
		qrpay.WithMerchantInfo(
			qrpay.BuildMerchantInfo(
				"Cửa hàng sữa Vinamilk",
				qrpay.WithCategoryCode(constants.GroceryStoresSupermarkets),
				qrpay.WithMerchantCity("Hồ Chí Minh"),
				qrpay.WithMerchantPostalCode("70000"),
			),
		),
	)

	qr, err = complexQRPay.GenerateQRCode()
	if err != nil {
		fmt.Printf("Error generating QR %v\n", err)
		os.Exit(1)
	}

	fmt.Printf("ComplexQR: %s\n", qr)

	qrPay, err = qrpay.ParseQRPay(qr)
	if err != nil {
		fmt.Printf("parse VietQR ERROR: %v\n", err)
		os.Exit(1)
	}

  // Will print out
  /**
    ComplexQR: 00020001021138570010A00000072701270006970436011308810004580860208QRIBFTTA520454115303702540569000550202560410005802VN5921Cua hang sua Vinamilk6011Ho Chi Minh61057000062220818Thanh toan mua sua63043611
    Amount: 69000
    {"Version":"00","initiation_method":"11","merchant_info":{"name":"Cua hang sua Vinamilk","city":"Ho Chi Minh","country_code":"VN","postal_code":"70000","napas_provider":{"id":"A000000727","bank_bin":"970436","transfer_to":"0881000458086","method":"QRIBFTTA"},"master_account":"","visa_account":"","jcb_account":"","upi_account":"","category_code":"5411"},"currency_code":"702","amount":69000,"tip_and_fee_type":"02","tip_and_fee_amount":1000,"tip_and_fee_percent":0,"description":"","addition_data":{}}
  **/

complex qr

When scaning with bank application, note that also we set currency code as SGD but whether the bank application will respect that or not will depend on its decision.

VietQR Structure

QRPay structure
Napas standard

EMVCo standard works with Tag length value pattern, example a tag with 000200 will have structure as:

  • TagID: 00
  • TagLength: 02
  • TagValue: 00 => has exactly length = 2
Tag Information:

Some specific acronyms are available:

  • Format: N - Number, S - String

  • Display: M - Mandatory, C - Conditional, O - Optional

Name Tag ID Max Length Display Description
Payload Format Indicator 00 02 M Version of EMVCoQR, default 00
Point of Initiation Method 01 02 M Method of EMVCoQR, Dynamic "12", Static "11"
Merchant Account Information 38 99 O VietQR Tag, contains beneficiary information as account number, bank bin, receiver channel such as QRIBFTTA: QR IBFT via Transfer to Account, QRIBFTTC: QR IBFT via Transfer to Card
Merchant Category Code 52 04 O example travel & tour: "4722", based on Napas providing
Transaction Currency 53 03 O Based on https://en.wikipedia.org/wiki/ISO_4217, example VietNam: "704"
Transaction Amount 54 13 C Amount to be transferred
Tip or Convenience Indicator 55 25 O Tip type: user input or predefined with next tag 56, 57
Value of Convenience Fee Fixed 56 25 C Tip amount will be surcharged
Value of Convenience Fee Percentage 57 25 C Tip amount will be surcharged, calculated based on percentage of amount
Country Code 58 02 M Reference to: https://developer.mastercard.com/card-issuance/documentation/code-and-formats/iso-country-and-currency-codes/
Merchant Name 59 25 O Merchant Name
Merchant City 60 15 O Merchant City
Postal Code 61 10 O Postal Code
Additional Data Field Template 62 99 C Contains information such as description, bill number, store number, loyalty number, etc
CRC 63 04 M Check sum for QR, make sure not be modified

Please reference to Napas docs on the begin of this documentation for more tag like RFU, Unreversed, etc.

Notes: thanks for package https://github.com/biter777/countries we have enough information about Currency and Country Code.

Go structure

// ..another struct

type NapasProvider struct {
	Id         string      `json:"id"`
	BankBin    string      `json:"bank_bin"`
	TransferTo string      `json:"transfer_to"`
	Method     NapasMethod `json:"method"`
}

type MerchantInfo struct {
	Name          string                         `json:"name" valid:"required,maxstringlength(25)"`
	City          string                         `json:"city"`
	CountryCode   string                         `json:"country_code"` // Reference to: https://developer.mastercard.com/card-issuance/documentation/code-and-formats/iso-country-and-currency-codes/
	PostalCode    string                         `json:"postal_code"`  // Zip code
	NapasProvider *NapasProvider                 `json:"napas_provider"`
	MasterAccount string                         `json:"master_account"`
	VisaAccount   string                         `json:"visa_account"`
	JcbAccount    string                         `json:"jcb_account"`
	UpiAccount    string                         `json:"upi_account"`
	CategoryCode  constants.MerchantCategoryCode `json:"category_code"`
}

type QRPay struct {
	// Version of the QR
	Version string

	// Method of QR, fill Dynamic if has amount greater than zero, otherwise fill Static
	InitiationMethod models.InitiationMethod `json:"initiation_method"`

	// Merchant Info to fill in, such as bank bin acquirer, beneficiary number, etc
	MerchantInfo *models.MerchantInfo `json:"merchant_info"`

	// Currency code of QR, refenrece to https://en.wikipedia.org/wiki/ISO_4217
	CurrencyCode string `json:"currency_code"`

	// Amount of money which will be transferred
	Amount int64 `json:"amount"`

	// Tip and fee type of QR
	TipAndFeeType models.TipAndFeeType `json:"tip_and_fee_type"`

	// Tip and Fee type was defined, tip and fee amount will be take first if both amount and percentage are provided
	TipAndFeeAmount int64 `json:"tip_and_fee_amount"`

	// Percent of amount will be tip
	TipAndFeePercent int `json:"tip_and_fee_percent"`

	// Description when transferring
	Description string `json:"description"`

	// This field will be overwritten when build QR, so don't initialize it when building QR
	AdditionData map[models.AdditionDataType]string `json:"addition_data"`
}

Summary

We already support UPI, Visa, Master so please reference to models.MerchantInfo for more details, fill in data and process to build QR. Any further concerns, please create a MR.

Documentation

The Go Gopher

There is no documentation for this package.

Directories

Path Synopsis
pkg

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL