Nhà phát triển
Webhook
Khi trạng thái hóa đơn thay đổi, CryBit gửi một yêu cầu POST có chữ ký với nội dung JSON đến URL webhook của merchant.
Cài đặt
Đặt URL webhook và chọn các sự kiện trong cài đặt merchant, ở tab tích hợp: paid, expired, refunded, cancelled. URL phải là địa chỉ HTTP hoặc HTTPS công khai trên cổng 80, 443, 8080 hoặc 8443; chuyển hướng không được theo dõi. URL được đặt trên merchant chứ không phải trong yêu cầu tạo hóa đơn.
Header
| Header | Giá trị |
|---|---|
X-CryBit-Event | Tên sự kiện, ví dụ payment.paid. |
X-CryBit-Signature | t=<unix time>,v1=<hex>: HMAC-SHA256 của "<t>.<raw body>" với signing secret của bạn. |
Xác minh chữ ký
Signing secret hiển thị trong cài đặt merchant, cạnh URL webhook. Tính chữ ký trên raw body, so sánh trong thời gian hằng số và từ chối các yêu cầu cũ hơn năm phút.
PHP
$secret = getenv('CRYBIT_WEBHOOK_SECRET');
$body = file_get_contents('php://input');
$header = $_SERVER['HTTP_X_CRYBIT_SIGNATURE'] ?? '';
parse_str(str_replace(',', '&', $header), $p); // t=…&v1=…
$t = (int) ($p['t'] ?? 0);
$expected = hash_hmac('sha256', $t . '.' . $body, $secret);
if (abs(time() - $t) > 300 || !hash_equals($expected, $p['v1'] ?? '')) {
http_response_code(400);
exit;
}
// the request is genuine: store the event, answer 200, do the rest later
http_response_code(200);Node.js
import crypto from 'node:crypto'
export function verify(rawBody, header, secret) {
const parts = Object.fromEntries(header.split(',').map((kv) => kv.split('=')))
const t = Number(parts.t)
const expected = crypto.createHmac('sha256', secret).update(t + '.' + rawBody).digest('hex')
const ok = parts.v1 && parts.v1.length === expected.length
&& crypto.timingSafeEqual(Buffer.from(parts.v1), Buffer.from(expected))
return ok && Math.abs(Date.now() / 1000 - t) <= 300
}Gửi và thử lại
- Trả lời bằng mã trạng thái 2xx nhanh chóng: CryBit chờ khoảng mười hai giây.
- Nếu bạn không trả lời, CryBit thử lại sau 15 giây, 1 phút, 5, 15 và 30 phút, rồi 2, 6 và 24 giờ.
- Phản hồi 4xx, trừ 429, sẽ dừng việc thử lại.
- Cùng một sự kiện có thể đến nhiều lần: hãy xử lý idempotent, dựa trên order_id hoặc uuid của hóa đơn.
- Nếu bạn bỏ lỡ webhook, hãy đọc trạng thái bằng GET /api/v1/payments/{uuid}: đây luôn là nguồn dữ liệu chuẩn.
FAQ
Tôi có thể xem những gì đã được gửi không?
Có. Trang nhật ký API trong tài khoản merchant liệt kê các yêu cầu và lần gửi webhook cùng mã trạng thái và nội dung.
