Bắt đầu nhanh

SePay Webhooks cho phép ứng dụng của bạn nhận thông báo giao dịch theo thời gian thực mỗi khi có tiền vào hoặc tiền ra trên tài khoản ngân hàng đã liên kết. Thay vì phải kiểm tra liên tục, SePay sẽ chủ động gửi dữ liệu giao dịch đến URL bạn chỉ định.


Môi trường Sandbox

Nếu bạn cần môi trường thử nghiệm, hãy đăng ký tài khoản tại my.dev.sepay.vn. Tại đây bạn có thể tạo giao dịch giả lập, webhook để phục vụ mục đích phát triển phần mềm. Sau khi đăng ký, hãy liên hệ với SePay để được kích hoạt tài khoản.


Tổng quan luồng tích hợp

Sơ đồ dưới đây mô tả luồng tích hợp hoàn chỉnh — từ cấu hình webhook, tạo QR thanh toán, nhận thông báo giao dịch qua webhook, đến đối soát giao dịch định kỳ.

Luồng hoạt động SePay Webhooks
Rendering diagram...

Cách hoạt động

  1. Khách hàng chuyển tiền vào tài khoản ngân hàng của bạn
  2. SePay phát hiện giao dịch mới và gửi POST request đến URL webhook bạn đã cấu hình
  3. Server của bạn nhận dữ liệu, xử lý và phản hồi {"success": true}

Bắt đầu nhanh

Bước 1: Tạo Webhook trên Dashboard

Truy cập WebHooks

Đăng nhập vào my.sepay.vn → chọn menu WebHooks.

Thêm WebHooks mới

Chọn vào button + Thêm webhooks và điền thông tin:

  • Đặt tên: Tên bất kỳ để nhận biết webhook
  • Chọn sự kiện: Chọn sự kiện kích hoạt webhook khi có tiền vào, có tiền ra hoặc cả hai
  • Chọn điều kiện: Chọn tài khoản ngân hàng mà khi có giao dịch, webhook sẽ được gọi
  • Gọi đến URL: Đường dẫn nhận webhook trên server của bạn. Nếu muốn lập trình website nhận webhook, xem hướng dẫn PHP hoặc Node.js
  • Cấu hình chứng thực: Chọn OAuth 2.0, API Key hoặc Không chứng thực

Hoàn tất

Chọn Thêm để hoàn tất tích hợp.

Chi tiết cấu hình đầy đủ: Tạo Webhooks


Bước 2: Dữ liệu gửi qua WebHooks

SePay gửi một POST request với nội dung JSON như sau:

JSON
{
  "id": 92704,
  "gateway": "Vietcombank",
  "transactionDate": "2023-03-25 14:02:37",
  "accountNumber": "0123499999",
  "code": null,
  "content": "chuyen tien mua iphone",
  "transferType": "in",
  "transferAmount": 2277000,
  "accumulated": 19077000,
  "subAccount": null,
  "referenceCode": "MBVCB.3278907687",
  "description": ""
}
idinteger
ID giao dịch trên SePay
gatewaystring
Brand name của ngân hàng
transactionDatestring
Thời gian xảy ra giao dịch phía ngân hàng
accountNumberstring
Số tài khoản ngân hàng
codestring
Mã code thanh toán. SePay tự nhận diện dựa vào cấu hình tại Công ty → Cấu hình chung. Có thể null nếu không nhận diện được.
contentstring
Nội dung chuyển khoản
transferTypestring
Loại giao dịch: in = tiền vào, out = tiền ra
transferAmountinteger
Số tiền giao dịch (VND)
accumulatedinteger
Số dư tài khoản (lũy kế)
subAccountstring
Tài khoản ngân hàng phụ (tài khoản định danh / VA). Có thể null.
referenceCodestring
Mã tham chiếu của tin nhắn SMS
descriptionstring
Toàn bộ nội dung tin nhắn SMS

Bước 3: Code mẫu nhận Webhook
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
<?php
// File: webhook/sepay.php
 
// Lấy dữ liệu từ POST request
$data = json_decode(file_get_contents('php://input'));
 
if (!is_object($data)) {
http_response_code(400);
echo json_encode(['success' => false, 'message' => 'Invalid data']);
exit;
}
 
// Xác thực API Key
$apiKey = $_SERVER['HTTP_AUTHORIZATION'] ?? '';
if ($apiKey !== 'Apikey YOUR_API_KEY') {
http_response_code(401);
echo json_encode(['success' => false, 'message' => 'Unauthorized']);
exit;
}
 
// Chống trùng lặp: kiểm tra id đã xử lý chưa
// if (transactionExists($data->id)) { ... return; }
 
// Xử lý giao dịch
$transactionId = $data->id;
$amount = $data->transferAmount;
$code = $data->code; // Mã thanh toán (mã đơn hàng)
$type = $data->transferType; // 'in' hoặc 'out'
 
if ($type === 'in' && $code) {
// TODO: Cập nhật trạng thái đơn hàng theo $code
// updateOrderStatus($code, 'paid', $amount);
}
 
// Phản hồi thành công — BẮT BUỘC
http_response_code(200);
echo json_encode(['success' => true]);
 

Hướng dẫn chi tiết lưu giao dịch vào MySQL: PHP · Node.js


Bước 4: Nhận diện WebHooks thành công
Quan trọng

Khi nhận webhook từ SePay, website của bạn cần phản hồi đúng quy ước để SePay nhận diện kết quả thành công:

  • OAuth 2.0: Response body {"success": true} — HTTP Status Code 201
  • API Key: Response body {"success": true} — HTTP Status Code 200 hoặc 201
  • Không chứng thực: Response body {"success": true} — HTTP Status Code 200 hoặc 201

Nếu response không thỏa mãn các điều kiện trên, SePay sẽ xem webhook là thất bại.

Thông số timeout:

Connection timeout
5 giây
Response timeout
8 giây — Thời gian chờ phản hồi tối đa

Bước 5: Kiểm tra hoạt động
  1. Tài khoản Demo: Vào menu Giao dịchGiả lập giao dịch để tạo giao dịch thử. Xem hướng dẫn Giả lập giao dịch.
  2. Tài khoản thật: Chuyển một khoản tiền nhỏ vào tài khoản để tạo giao dịch thử nghiệm.
  3. Xem nhật ký: Vào menu Nhật ký → Nhật ký webhooks để xem danh sách webhook đã gọi.
  4. Xem theo giao dịch: Vào Giao dịch → cột Tự động → chọn Pay để xem webhook của từng giao dịch.

Bước tiếp theo

  1. Tạo QR và Form thanh toán — Tạo mã QR chuyển khoản và xây dựng trang thanh toán tự động xác nhận
  2. Tạo Webhooks — Cấu hình chi tiết webhook (sự kiện, điều kiện, retry, chứng thực)
  3. Lập trình Webhooks (PHP) — Hướng dẫn chi tiết lưu giao dịch vào MySQL bằng PHP
  4. Lập trình Webhooks (Node.js) — Hướng dẫn chi tiết bằng Node.js + Express
  5. Đối soát giao dịch — Đảm bảo không bỏ sót giao dịch nào