Bước 4 - Cập nhật trạng thái đơn hàng
Cơ chế Push
Backend
Backend cần cung cấp một Webhook để nhận kết quả thanh toán từ Checkout SDK. Webhook đơn giản là một API endpoint được gọi khi có kết quả thanh toán mới, endpoint này sẽ được đặt tên là /callback
. Lưu ý khi viết endpoint này:
orderId
nhận được từdata
của callback làcheckoutSdkOrderId
được tạo ở Bước 2. Để lấy lại đượcmyOrderId
được tạo ở Bước 1, bạn cần parseextradata
.- Response của endpoint này cần trả về đúng cấu trúc JSON được quy định ở tài liệu Checkout SDK > Webhooks > callback.
src/backend.ts
+ .post("/callback", async (req, res) => {
+ try {
+ const { data, overallMac } = req.body;
+ const { orderId, resultCode, extradata } = data;
+ // Tạo MAC
+ const dataOverallMac = Object.keys(data)
+ .sort()
+ .map((key) => `${key}=${data[key]}`)
+ .join("&");
+ const validOverallMac = createHmac(
+ "sha256",
+ process.env.CHECKOUT_SDK_PRIVATE_KEY!
+ )
+ .update(dataOverallMac)
+ .digest("hex");
+ if (overallMac === validOverallMac) {
+ // Lưu ý 1. Cách lấy `myOrderId`
+ const { myOrderId } = JSON.parse(decodeURIComponent(extradata));
+ const order = db.data.orders.find((order) => order.id === myOrderId);
+ if (order) {
+ order.info.paymentStatus = resultCode === 1 ? "success" : "failed";
+ db.write();
+ // Lưu ý 2. Cách trả về kết quả
+ res.json({
+ returnCode: 1,
+ returnMessage: "Đã cập nhật trạng thái đơn hàng thành công!",
+ });
+ } else {
+ throw Error("Không tìm thấy đơn hàng");
+ }
+ } else {
+ throw Error("MAC không hợp lệ");
+ }
+ } catch (error) {
+ res.json({
+ returnCode: 0,
+ returnMessage: String(error),
+ });
+ }
+ })
.listen(port, () => {
console.log(`Server running at http://localhost:${port}`);
});
Thiết lập
Webhook vừa tạo sẽ được gọi từ server của nền tảng, không phải từ Mini App của bạn. Để nền tảng biết vị trí của Webhook, bạn cần thiết lập Callback URL
và Sandbox Callback URL
:
Khi người dùng thanh toán thành công, đoạn code trên sẽ được thực thi và cập nhật paymentStatus
của đơn hàng thành success
hoặc failed
.