Chuyển tới nội dung chính

Webhook URL

Tổng quan

Tính năng này chuyển dữ liệu của hóa đơn đã thanh toán đến máy chủ của người bán. Nó tồn tại để cửa hàng của người bán có thể xử lý khoản thanh toán tự động và giao sản phẩm hoặc dịch vụ cho người mua của bạn.

Webhook URL được đặt riêng cho từng dự án và trỏ đến các script xử lý thanh toán bên trong cửa hàng của người bán. Địa chỉ phải dùng HTTPS và tên miền: địa chỉ IP không được chấp nhận, và chứng chỉ được xác minh ở mỗi lần gửi.

Mỗi khi trạng thái hóa đơn chuyển sang Đã thanh toán (Paid), dịch vụ gửi một yêu cầu POST đến URL này theo định dạng sau:

{
"wallet":{
"id":"47aa71e2-07a0-482e-9172-7114d7376ba0",
"name":"usdt-tron",
"blockchain":"tron",
"cryptocurrency":"usdt",
"address":"TKbstUwMzLrfTAGL4erYb7gc7ghmHQ9zG7"
},
"project":{
"id":"9deea1e2-0c08-41a3-bdc2-a34eada3892d",
"name":"My project",
"commissionPayer":"seller",
"commissionRate":1
},
"invoice":{
"id":"a4c9e2ee-9a03-43e5-a1a1-00caf679d16a",
"uid":"AFhygKX21ecd",
"createDatetime":"2024-02-26 13:29:24",
"timeToPayDatetime":"2024-02-27 01:29:24",
"commissionFiatUSD":0.05,
"amountFiatUSD":5.02,
"amountFiat":5,
"calcAmountFiat":5.02,
"currencyFiat":"USD",
"description":null,
"serviceData":null,
"status":"paid"
},
"payment":{
"id":"f986ad8d-2298-473d-982a-efbc817b975d",
"amount":5.02,
"hash":"74763b65e43bcc9492a6ce9a7f26fbfdbd7635aecd3454420b5e9534cba50ee6",
"transactionDatetime":"2024-02-26 13:32:57"
}
}

Thông báo phát đi ở mỗi lần chuyển sang Đã thanh toán — cả khi dịch vụ tự tìm thấy khoản thanh toán lẫn khi người bán khớp khoản thanh toán với hóa đơn thủ công.

Tham số yêu cầu

Tham sốMô tả
wallet.idID ví ở định dạng UUID
wallet.nameTên ví
wallet.blockchainBlockchain của ví tiền mã hóa
wallet.cryptocurrencyTiền mã hóa của ví
wallet.addressĐịa chỉ của ví tiền mã hóa
project.idID dự án ở định dạng UUID
project.nameTên dự án
project.commissionPayerBên trả phí dịch vụ
project.commissionRateMức phí tính bằng %
invoice.idID hóa đơn ở định dạng UUID
invoice.uidID hóa đơn (dành cho người mua)
invoice.createDatetimeNgày giờ tạo hóa đơn (UTC)
invoice.timeToPayDatetimeNgày giờ hóa đơn còn hiệu lực với người mua đến (UTC). Việc tìm kiếm thanh toán tiếp tục thêm 1 giờ sau mốc này — để tính đến các mạng chậm. Vì vậy thông báo có thể đến cho hóa đơn đã hiển thị là hết hạn
invoice.commissionFiatUSDSố tiền phí dịch vụ. Tính từ số tiền invoice.amountFiatUSD
invoice.amountFiatUSDSố tiền bằng USD. Khi tạo hóa đơn, nó được tính từ invoice.amountFiat theo tỷ giá hiện tại. Tại thời điểm thanh toán, nó bị ghi đè bằng số tiền thực nhận, quy đổi sang USD theo tỷ giá lúc đó. Phí trong invoice.commissionFiatUSD cũng được tính lại từ nó
invoice.amountFiatSố tiền gốc của hóa đơn bằng tiền pháp định. Không thay đổi
invoice.calcAmountFiatSố tiền tính bằng đồng tiền invoice.currencyFiat theo tỷ giá tiền mã hóa tại thời điểm thanh toán. Nó có thể khác invoice.amountFiat vì người mua có thể thanh toán hóa đơn sau khi tạo một khoảng thời gian chứ không phải ngay lập tức. Trong khoảng thời gian đó, tỷ giá tiền mã hóa so với invoice.currencyFiat có thể biến động theo cả hai chiều
invoice.currencyFiatTiền pháp định
invoice.descriptionMô tả đặt khi tạo hóa đơn
invoice.serviceDataDữ liệu dịch vụ đặt khi tạo hóa đơn
invoice.statusTrạng thái hóa đơn
payment.idID khoản thanh toán ở định dạng UUID
payment.amountSố tiền thanh toán bằng tiền mã hóa
payment.hashHash của giao dịch on-chain
payment.transactionDatetimeNgày giờ của giao dịch on-chain (UTC)

Chữ ký thông báo

Mỗi yêu cầu được ký bằng khóa bí mật webhook. Chữ ký đi trong các header X-TimestampX-Signature, giúp bạn chắc chắn thông báo đến từ dịch vụ chứ không phải từ kẻ ngoài đã biết địa chỉ trình xử lý của bạn.

Hãy xác minh chữ ký trước khi xử lý đơn hàng. Cơ chế và các ví dụ sẵn dùng nằm trong Xác minh chữ ký webhook.

Khuyến nghị xử lý

Đừng từ chối thông báo vì thời hạn thanh toán đã qua. Phép kiểm tra kiểu “hóa đơn đã hết hạn, nên khoản thanh toán không hợp lệ” trông có vẻ hợp lý nhưng cắt mất một phần các khoản thanh toán thật: trên mạng chậm, giao dịch có thể được xác nhận sau thời hạn, và người bán có thể khớp thủ công khoản thanh toán với hóa đơn hết hạn. Bản thân thông báo đã xác nhận khoản thanh toán.

Xác minh số tiền theo trường gốc invoice.amountFiat. Đây là số tiền hóa đơn như khi phát hành, và nó không thay đổi. Trường amountFiatUSD phản ánh số tiền thực nhận và có thể khác số đã phát hành — vừa do biến động tỷ giá, vừa do khớp thanh toán thủ công.

Phân tích số tiền dưới dạng số. Các số 0 cuối bị lược bỏ: số tiền 10.00 đến dưới dạng 10; hãy định dạng nó ở phía bạn khi hiển thị. Số tiền dưới 0.0001 đến ở dạng lũy thừa, ví dụ 1.0e-6 — phân tích JSON chuẩn trả về đúng con số; chỉ tự phân tích chuỗi thủ công mới hỏng.

Xử lý thông báo theo cách idempotent. Cùng một thông báo có thể đến lần nữa — ví dụ, khi script của bạn xử lý khoản thanh toán thành công nhưng trả về mã ngoài 2xx. Trước khi giao hàng, hãy kiểm tra invoice.id này đã được xử lý chưa.

Thoát ký tự các giá trị khi xuất ra. Các trường invoice.descriptioninvoice.serviceData quay lại đúng như người bán đã gửi. Nếu bạn kết xuất chúng trong HTML, hãy thoát ký tự ở phía bạn.

Lịch gửi

Máy chủ tại Webhook URL phải phản hồi bằng mã HTTP 2xx. Mã khác, hết thời gian chờ hoặc kết nối bị đứt đều tính là gửi thất bại.

Dịch vụ không đi theo chuyển hướng: phản hồi 301 hoặc 302 là gửi thất bại, không phải bước nhảy đến địa chỉ mới. Hãy đặt địa chỉ cuối cùng của trình xử lý.

Kết nối được phép 5 giây, toàn bộ yêu cầu 10 giây. Nếu trình xử lý không kịp trong khoảng đó, lần gửi tính là thất bại.

Sau lần gửi thất bại, dịch vụ thử lại theo lịch sau:

  • 5 phút sau lần gửi thất bại gần nhất
  • Sau 15 phút
  • Sau 30 phút
  • Sau 1 giờ
  • Sau 3 giờ
  • Sau 6 giờ
  • Sau 12 giờ
  • Sau 24 giờ

Sau đó, các lần gửi dừng lại.

Tắt Webhook URL

Đôi khi script webhook của cửa hàng xử lý khoản thanh toán đúng nhưng trả về mã HTTP ngoài 2xx. Điều này dẫn đến việc máy chủ của chúng tôi thử lại thường xuyên theo lịch ở trên, gây tải thêm cho cả máy chủ của chúng tôi lẫn của bạn.

Để ngăn những trường hợp như vậy, chúng tôi có cơ chế tắt Webhook URL trong dự án. Để tránh nó, hãy làm các bước sau:

  1. Sửa mã trình xử lý webhook của bạn để nó trả về mã 2xx, thường là 200, khi xử lý thanh toán thành công. Kiểm tra bằng bất kỳ trình giả lập nào, ví dụ Postman.
  2. Liên hệ hỗ trợ kỹ thuật để chỉnh lại cài đặt.
  3. Bật lại Webhook URL trong cài đặt dự án và lưu dự án.