1.2. IPN và Checksum
IPN và Checksum
IPN là gì?
- IPN (Instant Payment Notification) là phương thức thông báo ngược lại cho đối tác khi có một sự thay đổi về trạng thái của một yêu cầu giao dịch (thành công hoặc thất bại)
- Đối tác phải thiết kế một đầu nhận API (URI) theo mô tả trong tài liệu để phía server của MB có thể gọi ngược lại và khớp với các đặc tả.
Lưu ý
- Đầu API của đối tác phải cấu hình
HTTPs
và cung cấp toàn bộ certificate của các bên cấp cerificate trong trong chuỗi (trừ root) (Full chain of Intermediate Certificate) - Đối tác có thể check certificate tại trang web sau: https://www.sslshopper.com/ssl-checker.html
Checksum là gì?
- Checksum là phương thức bảo mật giúp phía server của đối tác xác nhận được rằng thông tin gửi từ server của MB là chính xác và không bị thay đổi
- Checksum dựa trên phương pháp tạo ra chuỗi cần mẫ hóa từ các thông tin quan trọng cần xác nhận. Sau đó chuỗi đó sẽ được băm cùng với mã bảo mật của MB thỏa thuận với đối tác (
CALLBACK_CHECKSUM_SECRET
). - Đối tác cần đối chiếu mã checksum được tạo ra trên server và mã checksum do MB gửi về trong trường
checksum
Các bước tạo checksum
Bước 1: Tạo chuỗi dữ liệu cần mã hóa dựa trên các trường dữ liệu được truyền sang khi gọi API của đối tác. Chú ý, nếu trường dữ liệu là
NULL
thì khi ghép chuỗi sẽ sử dụng giá trị chuỗi rỗng- Ví dụ: Đối với yêu cầu checksum có cấu trúc là:
merchantCode+transactionId+typeCode+cif+amount+status
- Trong đó:
merchantCode
: Mã đối táctransactionId
: ID giao dịchtypeCode
: Mã loại giao dịchcif
: Mã khách hàng tại MBamount
: Số tiền thực hiện giao dịchstatus
: Trạng thái giao dịch
Ví dụ
Chuỗi dữ liệu tương ứng cần mã hóa là: MICAJX014TUYI1121BHUT103267334100000PAID
- Ví dụ: Đối với yêu cầu checksum có cấu trúc là:
Bước 2: Băm chuỗi dữ liệu bằng thuật toán
HmacSha256
với khóa bí mật của đối tác để tạo ra chuỗi nhị phân sau đó mã hóa chuỗi nhị phân bằng thuật toánBase64
Ví dụ
Đối với
CALLBACK_CHECKSUM_SECRET=uLK65GkdfJNGmsRymgxhLm6jnYS6eVvU
, kết quả sẽ là:z/xrET4mBfy8xaXcVqtlmU9ztC2EA60RY2JRDZK7UCI=
Code tham khảo
Code Sample
- JSX
- PHP
- JAVA
- C#
const crypto = require("crypto");
let sig = crypto
.createHmac("sha256", process.env.CHECKSUM_KEY)
.update(data)
.digest("base64");
<?php
$sig = base64_encode(hash_hmac('sha256', $string, $CHECKSUM_KEY, true));
?>
import javax.crypto.Mac;
import java.util.Base64;
import javax.crypto.spec.SecretKeySpec;
class Crypto {
public String hmac256(String data, String checksumKey) {
try {
Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
SecretKeySpec secret_key = new SecretKeySpec(checksumKey.getBytes(), "HmacSHA256");
sha256_HMAC.init(secret_key);
String signature = Base64.getEncoder().encodeToString(sha256_HMAC.doFinal(data.getBytes()));
return signature;
}
catch(Exception e) {
// Do something
}
}
}
using System;
using System.Security.Cryptography;
using System.Text;
public class Crypto
{
public static String checksum(String checksumSecret, String data)
{
HMACSHA256 hmac = new HMACSHA256(Encoding.ASCII.GetBytes(checksumSecret));
byte[] hashValue = hmac.ComputeHash(Encoding.ASCII.GetBytes(data));
return Convert.ToBase64String(hashValue);
}
}