API Webhooks
Tài liệu về cách sử dụng API webhooks thông qua OAuth2 trong SePay.
Giới thiệu
API Webhooks của SePay cho phép bạn quản lý các webhook để nhận thông báo thời gian thực về giao dịch. Webhook là một cách hiệu quả để tự động hóa quy trình thanh toán, giúp hệ thống của bạn nhận được thông báo ngay khi có giao dịch mới.
webhook:read
để xem, webhook:write
để tạo/cập nhật, và webhook:delete
để xóa webhook.
Các Endpoints
API Webhooks cung cấp các endpoints sau:
Method | Endpoint | Mô tả |
---|---|---|
GET | /api/v1/webhooks |
Lấy danh sách webhooks với các tùy chọn lọc |
GET | /api/v1/webhooks/{id} |
Lấy thông tin chi tiết về một webhook cụ thể |
POST | /api/v1/webhooks |
Tạo webhook mới |
PATCH | /api/v1/webhooks/{id} |
Cập nhật thông tin webhook |
DELETE | /api/v1/webhooks/{id} |
Xóa webhook |
Lấy danh sách webhooks
GET /api/v1/webhooks
Endpoint này trả về danh sách webhooks của công ty bạn. Bạn có thể lọc kết quả theo nhiều tiêu chí khác nhau.
Quyền yêu cầu
- Scope:
webhook:read
- Quyền người dùng: Webhooks (
Xem danh sách webhooks
)
Tham số truy vấn
Tham số | Kiểu | Mô tả |
---|---|---|
webhook_url |
string | Lọc theo URL webhook (tìm kiếm một phần) |
api_key |
string | Lọc theo API key |
active |
integer | Lọc theo trạng thái hoạt động (0: không hoạt động, 1: đang hoạt động) |
page |
integer | Số trang, bắt đầu từ 1 |
limit |
integer | Số lượng kết quả trên mỗi trang |
Yêu cầu
GET /api/v1/webhooks?active=1
Authorization: Bearer {YOUR_ACCESS_TOKEN}
Phản hồi
{
"status": "success",
"data": [
{
"id": 23,
"bank_account_id": 19,
"name": "Tích hợp với shop online",
"event_type": "In_only",
"authen_type": "Api_Key",
"webhook_url": "https://example.com/webhook/payment",
"is_verify_payment": true,
"skip_if_no_code": true,
"retry_conditions": {
"non_2xx_status_code": 0
},
"only_va": true,
"active": true,
"created_at": "2025-02-15 14:23:56",
"api_key": "a7c3b4e5f6a7b8c9d0e1f2a3b4c5d6e7",
"request_content_type": "Json",
"bank_sub_account_ids": [25, 26]
},
{
"id": 22,
"bank_account_id": 18,
"name": "Tích hợp với CRM",
"event_type": "All",
"authen_type": "OAuth2.0",
"webhook_url": "https://crm.example.com/webhook/transactions",
"is_verify_payment": false,
"skip_if_no_code": false,
"retry_conditions": {
"non_2xx_status_code": 0
},
"only_va": false,
"active": true,
"created_at": "2025-02-10 09:45:32",
"oauth2_client_id": "client_id_example",
"oauth2_client_secret": "client_secret_example",
"oauth2_access_token_url": "https://crm.example.com/oauth/token"
}
],
"meta": {
"pagination": {
"total": 5,
"per_page": 20,
"current_page": 1,
"last_page": 1
}
}
}
Lấy chi tiết webhook
GET /api/v1/webhooks/{id}
Endpoint này trả về thông tin chi tiết của một webhook dựa trên ID.
Quyền yêu cầu
- Scope:
webhook:read
- Quyền người dùng: Webhooks (
Xem danh sách webhooks
)
Tham số đường dẫn
Tham số | Kiểu | Mô tả |
---|---|---|
id |
integer | ID của webhook |
Yêu cầu
GET /api/v1/webhooks/23
Authorization: Bearer {YOUR_ACCESS_TOKEN}
Phản hồi
{
"status": "success",
"data": {
"id": 23,
"bank_account_id": 19,
"name": "Tích hợp với shop online",
"event_type": "In_only",
"authen_type": "Api_Key",
"webhook_url": "https://example.com/webhook/payment",
"is_verify_payment": true,
"skip_if_no_code": true,
"retry_conditions": {
"only_va": true,
"active": true,
"created_at": "2025-02-15 14:23:56",
"api_key": "a7c3b4e5f6a7b8c9d0e1f2a3b4c5d6e7",
"request_content_type": "Json",
"bank_sub_account_ids": [25, 26]
}
}
Tạo webhook mới
POST /api/v1/webhooks
Endpoint này cho phép bạn tạo một webhook mới để nhận thông báo về giao dịch.
Quyền yêu cầu
- Scope:
webhook:write
- Quyền người dùng: Webhooks (
Thêm webhooks
)
Tham số yêu cầu
Tham số | Kiểu | Yêu cầu | Mô tả |
---|---|---|---|
bank_account_id |
integer | Bắt buộc | ID của tài khoản ngân hàng |
name |
string | Bắt buộc | Tên của webhook |
event_type |
string | Bắt buộc | Loại sự kiện (All , In_only , Out_only ) |
authen_type |
string | Bắt buộc | Kiểu xác thực (No_Authen , OAuth2.0 , Api_Key ) |
webhook_url |
string | Bắt buộc | URL nhận webhook |
is_verify_payment |
integer | Bắt buộc | Có xác thực thanh toán không (0: không, 1: có) |
skip_if_no_code |
integer | Tùy chọn | Bỏ qua nếu không có mã thanh toán (0: không, 1: có) |
active |
integer | Tùy chọn | Trạng thái hoạt động (0: không hoạt động, 1: đang hoạt động) |
retry_conditions |
array | Tùy chọn | Điều kiện thử lại khi gặp lỗi |
only_va |
integer | Tùy chọn | Chỉ nhận giao dịch từ tài khoản ảo (0: không, 1: có) |
bank_sub_account_ids |
array | Bắt buộc nếu only_va=1 | Danh sách ID tài khoản ảo |
Thêm tham số cho từng kiểu xác thực:
Kiểu xác thực | Tham số bổ sung | Yêu cầu | Mô tả |
---|---|---|---|
OAuth2.0 |
oauth2_access_token_url |
Bắt buộc | URL để lấy access token |
oauth2_client_id |
Bắt buộc | Client ID | |
oauth2_client_secret |
Bắt buộc | Client Secret | |
Api_Key |
api_key |
Bắt buộc | API Key |
request_content_type |
Bắt buộc | Kiểu nội dung yêu cầu (Json , multipart_form-data ) |
|
No_Authen |
request_content_type |
Bắt buộc | Kiểu nội dung yêu cầu (Json , multipart_form-data ) |
Yêu cầu
POST /api/v1/webhooks
Content-Type: application/json
Authorization: Bearer {YOUR_ACCESS_TOKEN}
{
"bank_account_id": 19,
"name": "Tích hợp với shop online",
"event_type": "In_only",
"authen_type": "Api_Key",
"webhook_url": "https://example.com/webhook/payment",
"is_verify_payment": 1,
"skip_if_no_code": 1,
"active": 1,
"only_va": 1,
"bank_sub_account_ids": [25, 26],
"retry_conditions": {
"non_2xx_status_code": 1
},
"api_key": "a7c3b4e5f6a7b8c9d0e1f2a3b4c5d6e7",
"request_content_type": "Json"
}
Phản hồi
{
"message": "Thêm WebHooks thành công",
"id": 23,
}
Cập nhật webhook
PATCH /api/v1/webhooks/{id}
Endpoint này cho phép bạn cập nhật thông tin của một webhook hiện có.
Quyền yêu cầu
- Scope:
webhook:write
- Quyền người dùng: Webhooks (
Sửa webhooks
)
Tham số đường dẫn
Tham số | Kiểu | Mô tả |
---|---|---|
id |
integer | ID của webhook |
Tham số yêu cầu
Tham số yêu cầu giống như khi tạo webhook, nhưng tất cả đều là tùy chọn. Bạn chỉ cần cung cấp các tham số cần thay đổi.
Yêu cầu
PATCH /api/v1/webhooks/23
Content-Type: application/json
Authorization: Bearer {YOUR_ACCESS_TOKEN}
{
"active": 0,
"skip_if_no_code": 0
}
Phản hồi
{
"message": "Cập nhật WebHooks thành công",
"id": "23",
}
Xóa webhook
DELETE /api/v1/webhooks/{id}
Endpoint này cho phép bạn xóa một webhook.
Quyền yêu cầu
- Scope:
webhook:delete
- Quyền người dùng: Webhooks (
Xóa webhooks
)
Tham số đường dẫn
Tham số | Kiểu | Mô tả |
---|---|---|
id |
integer | ID của webhook |
Yêu cầu
DELETE /api/v1/webhooks/23
Authorization: Bearer {YOUR_ACCESS_TOKEN}
Phản hồi
{
"message": "Xóa WebHooks thành công"
}
Ví dụ sử dụng
# Lấy danh sách webhooks
curl -X GET "https://my.sepay.vn/api/v1/webhooks" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
# Lấy chi tiết webhook
curl -X GET "https://my.sepay.vn/api/v1/webhooks/23" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
# Tạo webhook mới
curl -X POST "https://my.sepay.vn/api/v1/webhooks" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"bank_account_id": 19,
"name": "Tích hợp với shop online",
"event_type": "In_only",
"authen_type": "Api_Key",
"webhook_url": "https://example.com/webhook/payment",
"is_verify_payment": 1,
"skip_if_no_code": 1,
"active": 1,
"api_key": "a7c3b4e5f6a7b8c9d0e1f2a3b4c5d6e7",
"request_content_type": "Json"
}'
# Cập nhật webhook
curl -X PUT "https://my.sepay.vn/api/v1/webhooks/23" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"active": 0
}'
# Xóa webhook
curl -X DELETE "https://my.sepay.vn/api/v1/webhooks/23" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
<?php
$accessToken = 'YOUR_ACCESS_TOKEN';
$baseUrl = 'https://my.sepay.vn/api/v1/webhooks';
// Hàm lấy danh sách webhooks
function getWebhooks($accessToken, $filters = []) {
global $baseUrl;
$queryString = http_build_query($filters);
$url = $queryString ? "$baseUrl?$queryString" : $baseUrl;
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Authorization: Bearer ' . $accessToken
]);
$response = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($status == 200) {
return json_decode($response, true);
} else {
return ['error' => $status, 'message' => $response];
}
}
// Hàm lấy chi tiết webhook
function getWebhookDetails($accessToken, $webhookId) {
global $baseUrl;
$ch = curl_init("$baseUrl/$webhookId");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Authorization: Bearer ' . $accessToken
]);
$response = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($status == 200) {
return json_decode($response, true);
} else {
return ['error' => $status, 'message' => $response];
}
}
// Hàm tạo webhook mới
function createWebhook($accessToken, $data) {
global $baseUrl;
$ch = curl_init($baseUrl);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Authorization: Bearer ' . $accessToken,
'Content-Type: application/json'
]);
$response = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
return json_decode($response, true);
}
// Hàm cập nhật webhook
function updateWebhook($accessToken, $webhookId, $data) {
global $baseUrl;
$ch = curl_init("$baseUrl/$webhookId");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Authorization: Bearer ' . $accessToken,
'Content-Type: application/json'
]);
$response = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
return json_decode($response, true);
}
// Hàm xóa webhook
function deleteWebhook($accessToken, $webhookId) {
global $baseUrl;
$ch = curl_init("$baseUrl/$webhookId");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'DELETE');
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Authorization: Bearer ' . $accessToken
]);
$response = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
return json_decode($response, true);
}
// Ví dụ sử dụng
$webhooks = getWebhooks($accessToken, ['active' => 1]);
$webhookDetails = getWebhookDetails($accessToken, 23);
// Tạo webhook mới
$newWebhook = createWebhook($accessToken, [
'bank_account_id' => 19,
'name' => 'Tích hợp với shop online',
'event_type' => 'In_only',
'authen_type' => 'Api_Key',
'webhook_url' => 'https://example.com/webhook/payment',
'is_verify_payment' => 1,
'skip_if_no_code' => 1,
'active' => 1,
'api_key' => 'a7c3b4e5f6a7b8c9d0e1f2a3b4c5d6e7',
'request_content_type' => 'Json'
]);
// Cập nhật webhook
$updateResult = updateWebhook($accessToken, 23, [
'active' => 0
]);
// Xóa webhook
$deleteResult = deleteWebhook($accessToken, 23);
const accessToken = 'YOUR_ACCESS_TOKEN';
const baseUrl = 'https://my.sepay.vn/api/v1/webhooks';
// Hàm lấy danh sách webhooks
async function getWebhooks(filters = {}) {
try {
// Tạo query string từ filters
const queryParams = new URLSearchParams();
for (const [key, value] of Object.entries(filters)) {
if (value !== undefined && value !== null) {
queryParams.append(key, value);
}
}
const url = queryParams.toString()
? `${baseUrl}?${queryParams.toString()}`
: baseUrl;
const response = await fetch(url, {
headers: {
'Authorization': `Bearer ${accessToken}`
}
});
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}
return await response.json();
} catch (error) {
console.error('Error fetching webhooks:', error.message);
throw error;
}
}
// Hàm lấy chi tiết webhook
async function getWebhookDetails(webhookId) {
try {
const response = await fetch(`${baseUrl}/${webhookId}`, {
headers: {
'Authorization': `Bearer ${accessToken}`
}
});
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}
return await response.json();
} catch (error) {
console.error(`Error fetching webhook ${webhookId}:`, error.message);
throw error;
}
}
// Hàm tạo webhook mới
async function createWebhook(webhookData) {
try {
const response = await fetch(baseUrl, {
method: 'POST',
headers: {
'Authorization': `Bearer ${accessToken}`,
'Content-Type': 'application/json'
},
body: JSON.stringify(webhookData)
});
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}
return await response.json();
} catch (error) {
console.error('Error creating webhook:', error.message);
throw error;
}
}
// Hàm cập nhật webhook
async function updateWebhook(webhookId, webhookData) {
try {
const response = await fetch(`${baseUrl}/${webhookId}`, {
method: 'PUT',
headers: {
'Authorization': `Bearer ${accessToken}`,
'Content-Type': 'application/json'
},
body: JSON.stringify(webhookData)
});
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}
return await response.json();
} catch (error) {
console.error(`Error updating webhook ${webhookId}:`, error.message);
throw error;
}
}
// Hàm xóa webhook
async function deleteWebhook(webhookId) {
try {
const response = await fetch(`${baseUrl}/${webhookId}`, {
method: 'DELETE',
headers: {
'Authorization': `Bearer ${accessToken}`
}
});
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}
return await response.json();
} catch (error) {
console.error(`Error deleting webhook ${webhookId}:`, error.message);
throw error;
}
}
// Ví dụ sử dụng
async function exampleUsage() {
try {
// Lấy danh sách webhooks
const webhooks = await getWebhooks({active: 1});
console.log('Webhooks:', webhooks);
// Lấy chi tiết webhook
const webhookDetails = await getWebhookDetails(23);
console.log('Webhook details:', webhookDetails);
// Tạo webhook mới
const newWebhook = await createWebhook({
bank_account_id: 19,
name: 'Tích hợp với shop online',
event_type: 'In_only',
authen_type: 'Api_Key',
webhook_url: 'https://example.com/webhook/payment',
is_verify_payment: 1,
skip_if_no_code: 1,
active: 1,
api_key: 'a7c3b4e5f6a7b8c9d0e1f2a3b4c5d6e7',
request_content_type: 'Json'
});
console.log('New webhook created:', newWebhook);
// Cập nhật webhook
const updateResult = await updateWebhook(23, {
active: 0
});
console.log('Update result:', updateResult);
// Xóa webhook
const deleteResult = await deleteWebhook(23);
console.log('Delete result:', deleteResult);
} catch (error) {
console.error('Example usage error:', error);
}
}
exampleUsage();
Mã lỗi
Dưới đây là các mã lỗi có thể gặp khi sử dụng API webhooks:
Mã HTTP | Mã lỗi | Mô tả |
---|---|---|
400 | validation_error |
Lỗi xác thực dữ liệu đầu vào |
401 | unauthorized |
Token không hợp lệ hoặc hết hạn |
403 | forbidden |
Không có quyền truy cập vào tài nguyên này |
404 | not_found |
Không tìm thấy webhook |
Bước tiếp theo
Sau khi đã tạo webhook, bạn cần chuẩn bị máy chủ của mình để xử lý dữ liệu webhook được gửi từ SePay. Ngoài ra, bạn có thể tìm hiểu thêm về cách sử dụng API Webhook kết hợp với các API khác để tạo ra các giải pháp tích hợp hoàn chỉnh.