Đây là hướng dẫn cách tạo mã VietQR bằng Golang
Hôm trước lục lọi trên mạng để tìm giải pháp thanh toán Online tiện lợi bằng VietQR sử dụng ngôn ngữ Golang, mình đã tìm ra một thư viện khá hay của anh ducnpdev, thư viện này cho phép ta tạo mã VietQR vô cùng dễ dàng.
Thư viện này có cách sử dụng ví dụ như sau:
package vietqr
import (
"fmt"
)
func main() {
content := GenerateViQR(RequestGenerateViQR{
MerchantAccountInformation: MerchantAccountInformation{
AccountNo: "999990335280715",
},
TransactionAmount: "505000",
AdditionalDataFieldTemplate: AdditionalDataFieldTemplate{
Description: "test noi dung",
},
})
fmt.Println("content-main:", content)
// => 00020101021238590010A0000007270129000697043701159999903352807150208QRIBFTTA53037045406505005802VN62170813test noi dung630433C4
}
Tìm hiểu ra thì Nam mới hiểu là mã QR được tạo từ 1 đoạn mã, như vậy ta cần một thư viện để tạo hình ảnh và truyền nó ra ngoài Frontend (như của Golang là sử dụng Go/HTML Package)
Dưới đây là hàm mà Nam sử dụng vừa áp dụng Code tạo mã QR, vừa áp dụng thư viện tạo QR hình ảnh
func HandleVietQRPayment(w http.ResponseWriter, r *http.Request) {
// Get the cart data from the session
session, _ := store.Get(r, "mysession")
strcart := session.Values["cart"].(string)
var cart []models.Item
json.Unmarshal([]byte(strcart), &cart)
// Retrieve the new total from the session
var total float64
if newTotal, ok := session.Values["newTotal"].(float64); ok {
total = newTotal
} else {
total = Product_total(cart)
}
totalString := strconv.FormatFloat(total, 'f', -1, 64)
content := vietqr.GenerateViQR(vietqr.RequestGenerateViQR{
MerchantAccountInformation: vietqr.MerchantAccountInformation{
AcqID: "970415",
AccountNo: "106873395273",
},
TransactionAmount: totalString,
AdditionalDataFieldTemplate: vietqr.AdditionalDataFieldTemplate{
Description: "test noi dung",
},
})
fmt.Println("content-main:", content)
// Generate the QR Code
qrCode, err := qrcode.New(content, qrcode.Medium)
if err != nil {
http.Error(w, "Failed to generate QR code", http.StatusInternalServerError)
return
}
// Serve the QR Code as a PNG image
w.Header().Set("Content-Type", "image/png")
err = qrCode.Write(256, w) // 256 is the image size
if err != nil {
http.Error(w, "Failed to write QR code image", http.StatusInternalServerError)
}
}
Lưu ý 1 chút như sau:
// Get the cart data from the session
session, _ := store.Get(r, "mysession")
strcart := session.Values["cart"].(string)
var cart []models.Item
json.Unmarshal([]byte(strcart), &cart)
// Retrieve the new total from the session
var total float64
if newTotal, ok := session.Values["newTotal"].(float64); ok {
total = newTotal
} else {
total = Product_total(cart)
}
totalString := strconv.FormatFloat(total, 'f', -1, 64)
Đoạn mã này bản chất là tùy vào hệ thống, như của Nam thì giá trị đơn hàng (Cart) được lưu vào Cookies mysession, và strcart (String cart) được lấy từ giá trị "cart" trong session đó. Từ đó ta giải mã chúng thành đối tượng giỏ hàng (Unmarshal)
Đoạn newTotal thì để xử lý cho phần coupon nên cũng không cần quá quan tâm, tóm lại là hàm Total sẽ bằng tổng giá trị đơn hàng.
content := vietqr.GenerateViQR(vietqr.RequestGenerateViQR{
MerchantAccountInformation: vietqr.MerchantAccountInformation{
AcqID: "970415",
AccountNo: "106873395273",
},
TransactionAmount: totalString,
AdditionalDataFieldTemplate: vietqr.AdditionalDataFieldTemplate{
Description: "test noi dung",
},
})
Lúc này thì để xác nhận tiền đã được chuyển, ta sẽ cần tạo Webhook tại Vietqr để báo tiền đã được nhận với giao dịch tương ứng, để đổ hàm callback về (Phần này Nam sẽ cần nghiên cứu thêm)