Kiểm tra dữ liệu với signature
1. Kiểm tra thông tin bằng chữ ký
Giá trị signature
được dùng để kiểm tra tính chính xác của dữ liệu.
Cách tạo signature
- Sử dụng thuật toán HMAC_SHA256 để tạo signature.
- data tạo signature dạng: key1=value1&key2=value2... (key1: tên field, value1 = giá trị của key1).
- Dữ liệu tạo signature sắp xếp theo key thứ tự alphabet.
- Cấu trúc: hash_hmac("sha256", string $data , string $checksum_key)
Lưu ý:
Checksum Key được tạo ra sau khi tạo cổng thanh toán thành công
Code mẫu kiểm tra chính xác dữ liệu
- PHP
- Javascript
- Python
- Java
<?php
$checksum_key = "1a54716c8f0efb2744fb28b6e38b25da7f67a925d98bc1c18bd8faaecadd7675"
$webhookData = Array(
"code" => "00",
"desc" => "success",
"data" => Array(
"orderCode" => 123,
"amount" => 3000,
"description" => "VQRIO123",
"accountNumber" => "12345678",
"reference" => "TF230204212323",
"transactionDateTime" => "2023-02-04 18:25:00",
"paymentLinkId" => "124c33293c43417ab7879e14c8d9eb18",
"code" => "00",
"desc" => "Thành công",
"counterAccountBankId" => "",
"counterAccountBankName" => "",
"counterAccountName" => "",
"counterAccountNumber" => "",
"virtualAccountName" => "",
"virtualAccountNumber" => ""
),
"signature" => "8d8640d802576397a1ce45ebda7f835055768ac7ad2e0bfb77f9b8f12cca4c7f"
);
function isValidData($transaction, $transaction_signature){
ksort($transaction);
$transaction_str_arr = [];
foreach ($transaction as $key => $value) {
$transaction_str_arr[] = $key . "=" . $value;
}
$transaction_str = implode('&', $transaction_str_arr);
$signature = hash_hmac('sha256', $transaction_str, $checksum_key);
return $signature == $transaction_signature;
}
isValidData($webhookData['data'], $webhookData['signature']);
import CryptoJS from 'crypto-js';
const checksum_key = "1a54716c8f0efb2744fb28b6e38b25da7f67a925d98bc1c18bd8faaecadd7675"
const webhookData = {
code: '00',
desc: 'success',
data: {
orderCode: 123,
amount: 3000,
description: 'VQRIO123',
accountNumber: '12345678',
reference: 'TF230204212323',
transactionDatetime: '2023-02-04 18:25:00',
paymentLinkId: '124c33293c43417ab7879e14c8d9eb18',
code: '00',
desc: 'Thành công',
counterAccountBankId: '',
counterAccountBankName: '',
counterAccountName: '',
counterAccountNumber: '',
virtualAccountName: '',
virtualAccountNumber: '',
},
signature:'8d8640d802576397a1ce45ebda7f835055768ac7ad2e0bfb77f9b8f12cca4c7f'
}
function sortObjDataByAlphabet(obj) {
const sortedKeys = Object.keys(obj).sort();
const sortedObject = {};
sortedKeys.forEach((key) => {
sortedObject[key] = obj[key];
});
return sortedObject;
}
function isValidData(data, current_signature) {
const sortData = sortObjDataByAlphabet(data);
const stringifyData = Object.keys(sortData)
.map((key) => `${key}=${data[key]}`)
.join('&');
return CryptoJS.HmacSHA256(stringifyData, checksum_key).toString(CryptoJS.enc.Hex) == current_signature;
}
return isValidData(webhookData.data, webhookData.signature)
// Python3
import hmac
import hashlib
checksum_key = "1a54716c8f0efb2744fb28b6e38b25da7f67a925d98bc1c18bd8faaecadd7675"
webhook_data = {
"code": '00',
"desc": 'success',
"data": {
"orderCode": 123,
"amount": 3000,
"description": 'VQRIO123',
"accountNumber": '12345678',
"reference": 'TF230204212323',
"transactionDatetime": '2023-02-04 18:25:00',
"paymentLinkId": '124c33293c43417ab7879e14c8d9eb18',
"code": '00',
"desc": 'Thành công',
"counterAccountBankId": '',
"counterAccountBankName": '',
"counterAccountName": '',
"counterAccountNumber": '',
"virtualAccountName": '',
"virtualAccountNumber": '',
},
"signature": '8d8640d802576397a1ce45ebda7f835055768ac7ad2e0bfb77f9b8f12cca4c7f'
}
def is_valid_data(transaction, transaction_signature):
sorted_transaction = dict(sorted(transaction.items()))
transaction_str_arr = []
for key, value in sorted_transaction.items():
transaction_str_arr.append(f"{key}={value}")
transaction_str = "&".join(transaction_str_arr)
signature = hmac.new(
bytes(checksum_key, 'utf-8'),
msg=bytes(transaction_str, 'utf-8'),
digestmod=hashlib.sha256
).hexdigest()
return signature == transaction_signature
import java.util.*;
import org.apache.commons.codec.digest.HmacUtils;
import org.json.JSONObject;
String checksumKey = "1a54716c8f0efb2744fb28b6e38b25da7f67a925d98bc1c18bd8faaecadd7675";
String transaction = "{'orderCode':123,'amount':3000,'description':'VQRIO123','accountNumber':'12345678','reference':'TF230204212323','transactionDatetime':'2023-02-04 18:25:00','paymentLinkId':'124c33293c43417ab7879e14c8d9eb18','code':'00','desc':'Thành công','counterAccountBankId':'','counterAccountBankName':'','counterAccountName':'','counterAccountNumber':'','virtualAccountName':'','virtualAccountNumber':''}";
String transactionSignature = "8d8640d802576397a1ce45ebda7f835055768ac7ad2e0bfb77f9b8f12cca4c7f";
public Boolean isValidData(String transaction, String transactionSignature) {
JSONObject jsonObject = new JSONObject(transaction);
Iterator<String> sortedIt = sortedIterator(jsonObject.keys(), (a, b) -> a.compareTo(b));
StringBuilder transactionStr = new StringBuilder();
while (sortedIt.hasNext()) {
String key = sortedIt.next();
String value = jsonObject.get(key).toString();
transactionStr.append(key);
transactionStr.append('=');
transactionStr.append(value);
if (sortedIt.hasNext()) {
transactionStr.append('&');
}
}
String signature = new HmacUtils("HmacSHA256", checksumKey).hmacHex(transactionStr.toString());
return signature.equals(transactionSignature);
}
public static Iterator<String> sortedIterator(Iterator<String> it, Comparator<String> comparator) {
List<String> list = new ArrayList<String>();
while (it.hasNext()) {
list.add(it.next());
}
Collections.sort(list, comparator);
return list.iterator();
}
Xem chi tiết về API tại đây.
2. Thông tin dữ liệu mẫu
code required | string Mã lỗi |
desc required | string Thông tin lỗi |
required | object |
signature required | string Chữ kí để kiểm tra thông tin, chi tiết dữ liệu mẫu |
{- "code": "string",
- "desc": "string",
- "data": {
- "orderCode": 123,
- "amount": 3000,
- "description": "VQRIO123",
- "accountNumber": "12345678",
- "reference": "TF230204212323",
- "transactionDateTime": "2023-02-04 18:25:00",
- "paymentLinkId": "124c33293c43417ab7879e14c8d9eb18",
- "code": "00",
- "desc": "Thành công",
- "counterAccountBankId": "",
- "counterAccountBankName": "",
- "counterAccountName": "",
- "counterAccountNumber": "",
- "virtualAccountName": "",
- "virtualAccountNumber": ""
}, - "signature": "8d8640d802576397a1ce45ebda7f835055768ac7ad2e0bfb77f9b8f12cca4c7f"
}