Quản lý webhook
Đăng ký URL nhận sự kiện, xoay secret, xem lịch sử gửi và gửi lại.
Liệt kê endpoint
GET/v1/webhook_endpoints
Mọi URL đang nhận sự kiện.
Trả về
200 · Một trang WebhookEndpoint và nextCursor để lấy trang tiếp theo.
curl https://api.hensa.example/v1/webhook_endpoints \ -H "Authorization: Bearer $HENSA_API_KEY"const res = await fetch('https://api.hensa.example/v1/webhook_endpoints', { method: 'GET', headers: { Authorization: `Bearer ${process.env.HENSA_API_KEY}`, },})const data = await res.json()<?php$ch = curl_init('https://api.hensa.example/v1/webhook_endpoints');curl_setopt_array($ch, [ CURLOPT_CUSTOMREQUEST => 'GET', CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => [ 'Authorization: Bearer ' . getenv('HENSA_API_KEY'), ],]);$data = json_decode(curl_exec($ch), true);import os, requests
res = requests.get( "https://api.hensa.example/v1/webhook_endpoints", headers={ "Authorization": f"Bearer {os.environ['HENSA_API_KEY']}", }, timeout=10,)res.raise_for_status(){ "data": [ { "id": "whe_01JD7R1S3T5V7X9Z1B3D5F7H9K", "url": "https://cuahang.vn/webhooks/hensa", "events": [ "payment_request.paid", "bank_transaction.created" ], "status": "active", "secretLast4": "9f2a", "createdAt": "2026-11-03T07:00:00Z" } ]}/v1/webhook_endpointsTạo endpoint
POST/v1/webhook_endpoints
URL phải là HTTPS công khai (không chấp nhận địa chỉ nội bộ). Secret ký (whsec_…) chỉ trả về một lần – lưu ngay.
Nội dung gửi lên
urlstringbắt buộcURL HTTPS công khai sẽ nhận sự kiện.
eventsstring[]bắt buộcDanh sách sự kiện muốn nhận (ít nhất một).
Giá trị:
bank_transaction.createdpayment_request.paidpayment_request.partially_paidpayment_request.expiredbank_connection.status_changed
Trả về
201 · WebhookEndpoint + secret
Lỗi có thể gặp
validation_error400 Dữ liệu gửi lên không hợp lệ – xemmessage.url_not_https422 URL webhook phải dùng HTTPS.url_private_address422 URL trỏ tới địa chỉ nội bộ – không được phép.
curl -X POST https://api.hensa.example/v1/webhook_endpoints \ -H "Authorization: Bearer $HENSA_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"url":"https://cuahang.vn/webhooks/hensa","events":["payment_request.paid","bank_transaction.created"]}'const res = await fetch('https://api.hensa.example/v1/webhook_endpoints', { method: 'POST', headers: { Authorization: `Bearer ${process.env.HENSA_API_KEY}`, 'Idempotency-Key': crypto.randomUUID(), 'Content-Type': 'application/json' }, body: JSON.stringify({ "url": "https://cuahang.vn/webhooks/hensa", "events": [ "payment_request.paid", "bank_transaction.created" ] })})const data = await res.json()<?php$ch = curl_init('https://api.hensa.example/v1/webhook_endpoints');curl_setopt_array($ch, [ CURLOPT_CUSTOMREQUEST => 'POST', CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => [ 'Authorization: Bearer ' . getenv('HENSA_API_KEY'), 'Idempotency-Key: ' . bin2hex(random_bytes(16)), 'Content-Type: application/json', ], CURLOPT_POSTFIELDS => '{"url":"https://cuahang.vn/webhooks/hensa","events":["payment_request.paid","bank_transaction.created"]}',]);$data = json_decode(curl_exec($ch), true);import os, uuid, requests
res = requests.post( "https://api.hensa.example/v1/webhook_endpoints", headers={ "Authorization": f"Bearer {os.environ['HENSA_API_KEY']}", "Idempotency-Key": str(uuid.uuid4()), }, json={ "url": "https://cuahang.vn/webhooks/hensa", "events": [ "payment_request.paid", "bank_transaction.created" ] }, timeout=10,)res.raise_for_status(){ "endpoint": { "id": "whe_01JD7R1S3T5V7X9Z1B3D5F7H9K", "url": "https://cuahang.vn/webhooks/hensa", "events": [ "payment_request.paid", "bank_transaction.created" ], "status": "active", "secretLast4": "9f2a", "createdAt": "2026-11-03T07:00:00Z" }, "secret": "…"}/v1/webhook_endpointsXóa endpoint
DELETE/v1/webhook_endpoints/{id}
Ngừng gửi sự kiện tới URL này ngay lập tức.
Tham số
idstring · đường dẫnbắt buộcID endpoint.
Trả về
204 · Không có nội dung.
Lỗi có thể gặp
not_found404 Không tìm thấy (hoặc không thuộc cửa hàng của khóa này).
curl -X DELETE https://api.hensa.example/v1/webhook_endpoints/whe_01JD7R1S3T5V7X9Z1B3D5F7H9K \ -H "Authorization: Bearer $HENSA_API_KEY"const res = await fetch('https://api.hensa.example/v1/webhook_endpoints/whe_01JD7R1S3T5V7X9Z1B3D5F7H9K', { method: 'DELETE', headers: { Authorization: `Bearer ${process.env.HENSA_API_KEY}`, },})// 204 No Content<?php$ch = curl_init('https://api.hensa.example/v1/webhook_endpoints/whe_01JD7R1S3T5V7X9Z1B3D5F7H9K');curl_setopt_array($ch, [ CURLOPT_CUSTOMREQUEST => 'DELETE', CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => [ 'Authorization: Bearer ' . getenv('HENSA_API_KEY'), ],]);$data = json_decode(curl_exec($ch), true);import os, requests
res = requests.delete( "https://api.hensa.example/v1/webhook_endpoints/whe_01JD7R1S3T5V7X9Z1B3D5F7H9K", headers={ "Authorization": f"Bearer {os.environ['HENSA_API_KEY']}", }, timeout=10,)res.raise_for_status()/v1/webhook_endpoints/Đổi secret ký
POST/v1/webhook_endpoints/{id}/rotate_secret
Tạo secret mới. Secret cũ còn hiệu lực thêm 24 giờ – trong thời gian đó mỗi sự kiện mang hai chữ ký v1 để bạn chuyển đổi không gián đoạn.
Tham số
idstring · đường dẫnbắt buộcID endpoint.
Trả về
200 · WebhookEndpoint + secret
Lỗi có thể gặp
not_found404 Không tìm thấy (hoặc không thuộc cửa hàng của khóa này).
curl -X POST https://api.hensa.example/v1/webhook_endpoints/whe_01JD7R1S3T5V7X9Z1B3D5F7H9K/rotate_secret \ -H "Authorization: Bearer $HENSA_API_KEY"const res = await fetch('https://api.hensa.example/v1/webhook_endpoints/whe_01JD7R1S3T5V7X9Z1B3D5F7H9K/rotate_secret', { method: 'POST', headers: { Authorization: `Bearer ${process.env.HENSA_API_KEY}`, },})const data = await res.json()<?php$ch = curl_init('https://api.hensa.example/v1/webhook_endpoints/whe_01JD7R1S3T5V7X9Z1B3D5F7H9K/rotate_secret');curl_setopt_array($ch, [ CURLOPT_CUSTOMREQUEST => 'POST', CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => [ 'Authorization: Bearer ' . getenv('HENSA_API_KEY'), ],]);$data = json_decode(curl_exec($ch), true);import os, requests
res = requests.post( "https://api.hensa.example/v1/webhook_endpoints/whe_01JD7R1S3T5V7X9Z1B3D5F7H9K/rotate_secret", headers={ "Authorization": f"Bearer {os.environ['HENSA_API_KEY']}", }, timeout=10,)res.raise_for_status(){ "endpoint": { "id": "whe_01JD7R1S3T5V7X9Z1B3D5F7H9K", "url": "https://cuahang.vn/webhooks/hensa", "events": [ "payment_request.paid", "bank_transaction.created" ], "status": "active", "secretLast4": "9f2a", "createdAt": "2026-11-03T07:00:00Z" }, "secret": "…"}/v1/webhook_endpoints//rotate_secretGửi sự kiện thử
POST/v1/webhook_endpoints/{id}/test
Gửi ngay một sự kiện mẫu (đã ký) tới endpoint và trả về kết quả.
Tham số
idstring · đường dẫnbắt buộcID endpoint.
Trả về
200 · WebhookDelivery
Lỗi có thể gặp
not_found404 Không tìm thấy (hoặc không thuộc cửa hàng của khóa này).
curl -X POST https://api.hensa.example/v1/webhook_endpoints/whe_01JD7R1S3T5V7X9Z1B3D5F7H9K/test \ -H "Authorization: Bearer $HENSA_API_KEY"const res = await fetch('https://api.hensa.example/v1/webhook_endpoints/whe_01JD7R1S3T5V7X9Z1B3D5F7H9K/test', { method: 'POST', headers: { Authorization: `Bearer ${process.env.HENSA_API_KEY}`, },})const data = await res.json()<?php$ch = curl_init('https://api.hensa.example/v1/webhook_endpoints/whe_01JD7R1S3T5V7X9Z1B3D5F7H9K/test');curl_setopt_array($ch, [ CURLOPT_CUSTOMREQUEST => 'POST', CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => [ 'Authorization: Bearer ' . getenv('HENSA_API_KEY'), ],]);$data = json_decode(curl_exec($ch), true);import os, requests
res = requests.post( "https://api.hensa.example/v1/webhook_endpoints/whe_01JD7R1S3T5V7X9Z1B3D5F7H9K/test", headers={ "Authorization": f"Bearer {os.environ['HENSA_API_KEY']}", }, timeout=10,)res.raise_for_status(){ "id": "whd_01JD7QC4V6X8Z0B2D4F6H8K0MP", "endpointId": "whe_01JD7R1S3T5V7X9Z1B3D5F7H9K", "eventType": "payment_request.paid", "status": "succeeded", "httpStatus": 200, "durationMs": 142, "attempt": 1, "createdAt": "2026-11-03T08:03:12Z"}/v1/webhook_endpoints//testLịch sử gửi
GET/v1/webhook_endpoints/{id}/deliveries
Mọi lần gửi trong 30 ngày, kể cả lần thất bại.
Tham số
idstring · đường dẫnbắt buộcID endpoint.
limitinteger · querySố bản ghi mỗi trang (1–100, mặc định 25).
cursorstring · queryGiá trị
nextCursorcủa trang trước.
Trả về
200 · Một trang WebhookDelivery và nextCursor để lấy trang tiếp theo.
Lỗi có thể gặp
not_found404 Không tìm thấy (hoặc không thuộc cửa hàng của khóa này).
curl https://api.hensa.example/v1/webhook_endpoints/whe_01JD7R1S3T5V7X9Z1B3D5F7H9K/deliveries \ -H "Authorization: Bearer $HENSA_API_KEY"const res = await fetch('https://api.hensa.example/v1/webhook_endpoints/whe_01JD7R1S3T5V7X9Z1B3D5F7H9K/deliveries', { method: 'GET', headers: { Authorization: `Bearer ${process.env.HENSA_API_KEY}`, },})const data = await res.json()<?php$ch = curl_init('https://api.hensa.example/v1/webhook_endpoints/whe_01JD7R1S3T5V7X9Z1B3D5F7H9K/deliveries');curl_setopt_array($ch, [ CURLOPT_CUSTOMREQUEST => 'GET', CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => [ 'Authorization: Bearer ' . getenv('HENSA_API_KEY'), ],]);$data = json_decode(curl_exec($ch), true);import os, requests
res = requests.get( "https://api.hensa.example/v1/webhook_endpoints/whe_01JD7R1S3T5V7X9Z1B3D5F7H9K/deliveries", headers={ "Authorization": f"Bearer {os.environ['HENSA_API_KEY']}", }, timeout=10,)res.raise_for_status(){ "data": [ { "id": "whd_01JD7QC4V6X8Z0B2D4F6H8K0MP", "endpointId": "whe_01JD7R1S3T5V7X9Z1B3D5F7H9K", "eventType": "payment_request.paid", "status": "succeeded", "httpStatus": 200, "durationMs": 142, "attempt": 1, "createdAt": "2026-11-03T08:03:12Z" } ], "nextCursor": "…"}/v1/webhook_endpoints//deliveriesGửi lại
POST/v1/webhook_deliveries/{id}/redeliver
Gửi lại một sự kiện (trong 30 ngày). Cùng id sự kiện – hệ thống của bạn phải xử lý trùng.
Tham số
idstring · đường dẫnbắt buộcID lần gửi.
Trả về
200 · WebhookDelivery
Lỗi có thể gặp
not_found404 Không tìm thấy (hoặc không thuộc cửa hàng của khóa này).delivery_too_old422 Chỉ gửi lại được sự kiện trong 30 ngày.
curl -X POST https://api.hensa.example/v1/webhook_deliveries/whd_01JD7QC4V6X8Z0B2D4F6H8K0MP/redeliver \ -H "Authorization: Bearer $HENSA_API_KEY"const res = await fetch('https://api.hensa.example/v1/webhook_deliveries/whd_01JD7QC4V6X8Z0B2D4F6H8K0MP/redeliver', { method: 'POST', headers: { Authorization: `Bearer ${process.env.HENSA_API_KEY}`, },})const data = await res.json()<?php$ch = curl_init('https://api.hensa.example/v1/webhook_deliveries/whd_01JD7QC4V6X8Z0B2D4F6H8K0MP/redeliver');curl_setopt_array($ch, [ CURLOPT_CUSTOMREQUEST => 'POST', CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => [ 'Authorization: Bearer ' . getenv('HENSA_API_KEY'), ],]);$data = json_decode(curl_exec($ch), true);import os, requests
res = requests.post( "https://api.hensa.example/v1/webhook_deliveries/whd_01JD7QC4V6X8Z0B2D4F6H8K0MP/redeliver", headers={ "Authorization": f"Bearer {os.environ['HENSA_API_KEY']}", }, timeout=10,)res.raise_for_status(){ "id": "whd_01JD7QC4V6X8Z0B2D4F6H8K0MP", "endpointId": "whe_01JD7R1S3T5V7X9Z1B3D5F7H9K", "eventType": "payment_request.paid", "status": "succeeded", "httpStatus": 200, "durationMs": 142, "attempt": 1, "createdAt": "2026-11-03T08:03:12Z"}/v1/webhook_deliveries//redeliverĐối tượng
WebhookEndpoint
idstringbắt buộcID endpoint.
urlstringbắt buộcURL HTTPS công khai nhận sự kiện.
eventsstring[]bắt buộcCác sự kiện đăng ký.
Giá trị:
bank_transaction.createdpayment_request.paidpayment_request.partially_paidpayment_request.expiredbank_connection.status_changedstatusstringbắt buộcactive·failing(đang lỗi, đã gửi email cảnh báo) ·disabled.secretLast4stringbắt buộc4 ký tự cuối của secret ký – để đối chiếu.
createdAtstringbắt buộcThời điểm tạo.
{ "id": "whe_01JD7R1S3T5V7X9Z1B3D5F7H9K", "url": "https://cuahang.vn/webhooks/hensa", "events": [ "payment_request.paid", "bank_transaction.created" ], "status": "active", "secretLast4": "9f2a", "createdAt": "2026-11-03T07:00:00Z"}WebhookDelivery
idstringbắt buộcID lần gửi.
endpointIdstringbắt buộcEndpoint nhận.
eventTypestringbắt buộcLoại sự kiện.
Giá trị:
bank_transaction.createdpayment_request.paidpayment_request.partially_paidpayment_request.expiredbank_connection.status_changedstatusstringbắt buộcsucceeded·failed·retrying.httpStatusinteger | nullbắt buộcMã HTTP máy chủ của bạn trả về.
Giá trị:
durationMsinteger | nullbắt buộcThời gian phản hồi (ms).
Giá trị:
attemptintegerbắt buộcLần gửi thứ mấy (1–8).
createdAtstringbắt buộcThời điểm gửi.
{ "id": "whd_01JD7QC4V6X8Z0B2D4F6H8K0MP", "endpointId": "whe_01JD7R1S3T5V7X9Z1B3D5F7H9K", "eventType": "payment_request.paid", "status": "succeeded", "httpStatus": 200, "durationMs": 142, "attempt": 1, "createdAt": "2026-11-03T08:03:12Z"}