Giới thiệu
Hiện nay thì việc thanh toán Online trên các nền tảng trực tuyến như Website, App Mobile đã không còn xa lạ nữa. Nó đang dẫn trở nên phổ biến và được nhiều người sử dụng.
Và để các bạn có thể tích hợp dịch vụ thanh toán Online trên Website của mình thì hôm nay mình sẽ hướng dẫn các bạn làm điều đó.
Cụ thể ở bài viết này mình sẽ hướng dẫn các bạn tích hợp một trong nhưng ứng dụng thanh toán online phổ biến nhất hiện nay đó là: VNPay
Chuẩn bị phần mêm cần thiết
Các bạn cần chuẩn bị một IDE hỗ trợ code C# sịn sò cho mình. Các bạn có thể xem Top các IDE dành cho C# TẠI ĐÂY
Ở đây mình sử dụng Rider :D
Đăng ký tài khoản VNPay
Ở bài viết này mình dùng môi trường Test của VNPay để Demo. Các bạn muốn đưa ra bản Production thì cần liên hệ với VNPay để làm hợp đồng nhé.
Còn code thì sẽ giống nhau cả thôi :D Chỉ khác cái mã và API thôi à.
Thì đầu tiên các bạn vào link sau để đăng ký tài khoản cho môi trường Test của VNPay TẠI ĐÂY và điền các thông tin cần thiết vào form như hình bên dưới

Sau khi đăng ký thành công các bạn mở Email lên và kiểm tra

Click vào link được đính kèm trong email để xác thực tài khoản

Sau khi xác thực thành công VnPay sẽ gửi một email kèm các thông tin cài đặt cho môi trường như sau:

#Quan trọng
Ở đây có một vài thông tin quan trọng mà các bạn cần lưu lại như hình trên bao gồm:
- - vnp_TmnCode
- - vnp_HashSecret
- - vnp_Url
Setup Code
Bây giờ chúng ta sẽ bắt đầu vào code phần thanh toán sau khi đã đăng ký xong môi trường với VnPay
Trong file appsetting.json các bạn thêm đoạn code như sau đồng thời sửa lại các thông tin TmnCode, HashSecret, BaseUrl bằng thông tin của các bạn vừa đăng ký
"Vnpay": {
"TmnCode": "I5L22N4F",
"HashSecret": "NJ22IGZBHGJISKIBWBTHXAATUSXQIAHL",
"BaseUrl": "https://sandbox.vnpayment.vn/paymentv2/vpcpay.html",
"Command": "pay",
"CurrCode": "VND",
"Version": "2.1.0",
"Locale": "vn"
},
Do code khá dài nên mình sẽ chỉ giải thích và đưa ra các hàm cần lưu ý thôi nhá. Các bạn Download source code về coi cho chi tiết nhé
Mình sẽ tạo ra 1 interfaces có tên IVnPayService và 1 class VnPayService sẽ implement interfaces IVnPayService
IVnPayService sẽ có 2 method như sau
string CreatePaymentUrl(PaymentInformationModel model, HttpContext context);
PaymentResponseModel PaymentExecute(IQueryCollection collections);
CreatePaymentUrl sẽ có trách nhiệm tạo ra URL thanh toán tại VnPay. Còn PaymentExecute sẽ thực kiểm tra thông tin giao dịch và sẽ lưu lại thông tin đó sau khi thanh toán thành công.
CreatePaymentUrl nhận vào một object có tên PaymentInformationModel model này này sẽ chứa các thông tin của hóa đơn thanh toán. Và một HttpContext để lấy địa chỉ IP Address của client thanh toán đơn hàng đó.
public class PaymentInformationModel
{
public string OrderType { get; set; }
public double Amount { get; set; }
public string OrderDescription { get; set; }
public string Name { get; set; }
}
Các bạn có thể thêm các thông tin khác mà các bạn muốn vào model này để xử lý dữ liệu theo logic của mình
PaymentExecute nhận vào 1 IQueryCollection đây là thông tin trên URL mà VnPay trả về trong các parameter sau khi thanh toán thành công hoặc lỗi. Cụ thể các bạn xem phần dưới để rõ hơn
CreatePaymentUrl
public string CreatePaymentUrl(PaymentInformationModel model, HttpContext context)
{
var timeZoneById = TimeZoneInfo.FindSystemTimeZoneById(_configuration["TimeZoneId"]);
var timeNow = TimeZoneInfo.ConvertTimeFromUtc(DateTime.UtcNow, timeZoneById);
var tick = DateTime.Now.Ticks.ToString();
var pay = new VnPayLibrary();
var urlCallBack = _configuration["PaymentCallBack:ReturnUrl"];
pay.AddRequestData("vnp_Version", _configuration["Vnpay:Version"]);
pay.AddRequestData("vnp_Command", _configuration["Vnpay:Command"]);
pay.AddRequestData("vnp_TmnCode", _configuration["Vnpay:TmnCode"]);
pay.AddRequestData("vnp_Amount", ((int)model.Amount * 100).ToString());
pay.AddRequestData("vnp_CreateDate", timeNow.ToString("yyyyMMddHHmmss"));
pay.AddRequestData("vnp_CurrCode", _configuration["Vnpay:CurrCode"]);
pay.AddRequestData("vnp_IpAddr", pay.GetIpAddress(context));
pay.AddRequestData("vnp_Locale", _configuration["Vnpay:Locale"]);
pay.AddRequestData("vnp_OrderInfo", $"{model.Name} {model.OrderDescription} {model.Amount}");
pay.AddRequestData("vnp_OrderType", model.OrderType);
pay.AddRequestData("vnp_ReturnUrl", urlCallBack);
pay.AddRequestData("vnp_TxnRef", tick);
var paymentUrl =
pay.CreateRequestUrl(_configuration["Vnpay:BaseUrl"], _configuration["Vnpay:HashSecret"]);
return paymentUrl;
}
Ở đây mình có tạo một class có tên VnPayLibrary có nhiệm vụ tạo ra URL để Redirect tới trang thanh toán của VnPay và xác thực giao dịch. Chi tiết các bạn Download Code về coi nhá.
Các bạn chú ý dòng pay.AddRequestData("vnp_Amount", ((int)model.Amount * 100).ToString()). Ở đây số tiền của mình sẽ cần nhân với 100 để khử phần thập phân sau khi thanh toán. Cái này do VnPay quy định nên mình cũng chịu :D. Các bạn cứ làm theo là được. Nhớ nhé:
Số tiền thanh toán = Số tiền thanh toán x 100
PaymentExecute
public PaymentResponseModel PaymentExecute(IQueryCollection collections)
{
var pay = new VnPayLibrary();
var response = pay.GetFullResponseData(collections, _configuration["Vnpay:HashSecret"]);
return response;
}
Trong hàm xử lý này sẽ lấy ra các thông tin sau khi giao dịch tại VnPay
public PaymentResponseModel GetFullResponseData(IQueryCollection collection, string hashSecret)
{
var vnPay = new VnPayLibrary();
foreach (var (key, value) in collection)
{
if (!string.IsNullOrEmpty(key) && key.StartsWith("vnp_"))
{
vnPay.AddResponseData(key, value);
}
}
var orderId = Convert.ToInt64(vnPay.GetResponseData("vnp_TxnRef"));
var vnPayTranId = Convert.ToInt64(vnPay.GetResponseData("vnp_TransactionNo"));
var vnpResponseCode = vnPay.GetResponseData("vnp_ResponseCode");
var vnpSecureHash =
collection.FirstOrDefault(k => k.Key == "vnp_SecureHash").Value; //hash của dữ liệu trả về
var orderInfo = vnPay.GetResponseData("vnp_OrderInfo");
var checkSignature =
vnPay.ValidateSignature(vnpSecureHash, hashSecret); //check Signature
if (!checkSignature)
return new PaymentResponseModel()
{
Success = false
};
return new PaymentResponseModel()
{
Success = true,
PaymentMethod = "VnPay",
OrderDescription = orderInfo,
OrderId = orderId.ToString(),
PaymentId = vnPayTranId.ToString(),
TransactionId = vnPayTranId.ToString(),
Token = vnpSecureHash,
VnPayResponseCode = vnpResponseCode
};
}
Controller
Trong Controller mình sẽ gọi ra 2 Services trên như sau:
public IActionResult CreatePaymentUrl(PaymentInformationModel model)
{
var url = _vnPayService.CreatePaymentUrl(model, HttpContext);
return Redirect(url);
}
public IActionResult PaymentCallback()
{
var response = _vnPayService.PaymentExecute(Request.Query);
return Json(response);
}
Testing
Phần code giao diện đơn giản như này thôi :D

#Quan trọng: Các bạn vào đây để xem thông tin tài khoản Test của VnPay nhé XEM TẠI ĐÂY

Sau khi nhấn Thanh Toán màn hình thanh toán tại VnPay sẽ hiện lên. Các bạn chọn mục thanh toán để checkout
Ở đây mình chọn: Thẻ nội địa và tài khoản ngân hàng
Tiếp đến chọn ngân hàng NCB để test

Mình sử dụng thông tin tài khoản sau để test:
- - Ngân hàng:
NCB
- - Số thẻ:
9704198526191432198
- - Tên chủ thẻ:
NGUYEN VAN A
- - Ngày phát hành:
07/15
- - Mật khẩu OTP:
123456
Sau khi thanh toán thành công VnPay sẽ Redirect về URL https://localhost:5001/Home/PaymentCallback mà trước đó mình đã config.
Và kết quả chúng ta nhận được

Với dữ liệu được trả về thành công các bạn có thể lưu nó xuống bất kỳ đâu các bạn muốn ví dụ như Database hoặc Excel tùy các bạn.
Tạm kết
Vậy là mình đã hướng dẫn xong rồi. Nếu thấy hay thì cho mình một share nhé.
Cám ơn các bạn đã theo dõi 😘