Biểu mẫu HTML
Một cách để thêm thanh toán tiền mã hóa vào trang web, cửa hàng trực tuyến hoặc bot. Người mua bấm nút, và trang thanh toán với hóa đơn mở ra.
Biểu mẫu chỉ gửi qua POST đến https://dash.bitsby.app/invoices/form và chứa hai trường:
| Trường | Nội dung |
|---|---|
data | base64url của JSON chứa các trường hóa đơn |
signature | HMAC-SHA256 của chuỗi data, 64 ký tự hex |
Một dự án có thể có tối đa 50 hóa đơn chưa thanh toán được tạo theo cách này tại mọi thời điểm.
Ví dụ biểu mẫu
<form method="post" action="https://dash.bitsby.app/invoices/form" target="_blank">
<input type="hidden" name="data" value="eyJwcm9qZWN0SWQiOiJhMWIyYzNkNC01ZTZm...">
<input type="hidden" name="signature" value="f77d6da1be35bd2900e0bfed9f202b04...">
<button type="submit">Pay</button>
</form>
Máy chủ của cửa hàng điền cả hai giá trị khi kết xuất trang. Khóa bí mật không bao giờ xuất hiện trong mã đánh dấu.
Thuộc tính target="_blank" là tùy chọn: với nó, giỏ hàng vẫn mở trong tab ban đầu.
Cách dựng container
- Dựng một đối tượng JSON với các trường hóa đơn.
- Mã hóa nó thành base64url. Đây là chuỗi
data. - Tính
signature = HMAC-SHA256(data, formSecret).
Chữ ký tính trên toàn bộ chuỗi data, nên thứ tự khóa JSON, thụt lề và kiểu thoát Unicode không quan trọng. Bên nhận cũng chấp nhận base64 chuẩn, có hoặc không có phần đệm.
Đừng dựng lại data sau khi ký: chỉ cần một byte thay đổi, bạn phải tính lại chữ ký.
Cách tính chữ ký, kèm ví dụ sẵn dùng bằng bốn ngôn ngữ, được trình bày trong Chữ ký biểu mẫu HTML.
Các khóa bên trong data
| Khóa | Bắt buộc | Nội dung |
|---|---|---|
projectId | có | ID dự án lấy từ cài đặt trong bảng điều khiển, uuid |
amountFiat | có | Số tiền từ 1 đến 100.000, tối đa hai chữ số thập phân. Dưới dạng chuỗi "10.50" hoặc số 10.5 |
currencyFiat | có | Tiền pháp định: USD, EUR hoặc RUB |
timeToPay | có | Thời hạn thanh toán tính bằng giờ: 0.5, 1, 3, 6, 12. Dưới dạng chuỗi hoặc số |
description | không | Mô tả cho người mua, tối đa 1.000 ký tự |
serviceData | không | Định danh đơn hàng phía cửa hàng, tối đa 1.000 ký tự. Không hiển thị cho người mua nhưng thấy được trong mã nguồn của biểu mẫu — đừng đặt dữ liệu nhạy cảm ở đây |
output | không | errors — hiển thị chi tiết lỗi kiểm tra dữ liệu |
Khóa tùy chọn có thể bỏ khỏi JSON — điều đó tương đương chuỗi rỗng. Các khóa có thể theo bất kỳ thứ tự nào; bên nhận bỏ qua khóa không xác định.
Giá trị là chuỗi hoặc số JSON. Boolean, mảng và đối tượng lồng nhau không được tính là giá trị trường và đến dưới dạng chuỗi rỗng.
Ví dụ nội dung của data:
{
"projectId": "a1b2c3d4-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
"amountFiat": 10.5,
"currencyFiat": "USD",
"timeToPay": 1,
"description": "Order #7, delivery",
"serviceData": "order-7"
}
Ở đây số tiền và thời hạn thanh toán truyền dưới dạng số; chuỗi cũng được chấp nhận. Khóa tùy chọn output hoàn toàn không đặt.
Định dạng số tiền
Chỉ chữ số và dấu chấm thập phân, tối đa hai chữ số thập phân: 10, 10.00, 1000.50. Khoảng trắng bao quanh bị cắt bỏ.
Mọi định dạng khác đều bị từ chối — dấu phân tách hàng nghìn, dấu phẩy thay cho dấu chấm, ký hiệu lũy thừa, dấu trước số, ký hiệu tiền tệ. Không có làm tròn: chữ số thập phân thứ ba không bị cắt bớt mà gây từ chối.
Khóa bí mật biểu mẫu
Khóa bí mật nằm trong cài đặt dự án ở bảng điều khiển, trong trường Khóa bí mật biểu mẫu (Form secret). Máy chủ cấp nó khi dự án được tạo. Bạn không thể tự đặt giá trị; khóa bí mật chỉ có thể được cấp lại — ví dụ, khi nó bị lộ.
Khóa bí mật phải nằm lại trên máy chủ của cửa hàng. Nếu nó lọt vào HTML của mặt tiền cửa hàng, chữ ký trở nên vô nghĩa.
Khóa bí mật biểu mẫu và khóa bí mật webhook là hai khóa khác nhau; đừng nhầm lẫn chúng.
Định danh đơn hàng
Luôn điền serviceData: đặt định danh đơn hàng của riêng bạn vào đó. Giá trị này quay lại trong thông báo thanh toán — cửa hàng dùng nó để tìm đơn hàng.
serviceData được điền giúp chống trùng lặp. Gửi lại biểu mẫu hoặc bấm đúp nút không tạo hóa đơn thứ hai: người mua được đưa đến hóa đơn chưa thanh toán hiện có. Việc so khớp dựa trên các trường đơn hàng — dự án, số tiền, đồng tiền, mô tả và serviceData — chứ không trên các byte của data.
Giá trị phải là duy nhất cho mỗi đơn hàng. Với cùng một giá trị, người mua thứ hai sẽ rơi vào hóa đơn chưa thanh toán của người mua thứ nhất.
serviceData rỗng làm mất lớp bảo vệ này: không còn gì để nhận ra lần gửi lặp, và mỗi lần gửi tạo một hóa đơn mới. Các bản trùng chiếm dụng giới hạn 50 hóa đơn chưa thanh toán, và khi một hóa đơn được thanh toán, cửa hàng không có gì để gắn khoản thanh toán với đơn hàng.
Lỗi và chế độ gỡ lỗi
Biểu mẫu trải qua hai bước kiểm tra: trước tiên là chữ ký và container, sau đó là giá trị các trường.
| Điều gì xảy ra | Dịch vụ hiển thị gì |
|---|---|
| Chữ ký không khớp, container không đọc được, dự án thuộc về người khác hoặc không tồn tại | Lỗi chung, không nêu lý do |
| Chữ ký khớp, nhưng một trường điền sai | Lỗi chung. Với "output":"errors" — lỗi chi tiết |
| Cả hai bước kiểm tra đều đạt | Trang thanh toán với hóa đơn |
Bước kiểm tra thứ nhất không bao giờ tiết lộ lý do, dù cài đặt thế nào.
Cặp "output":"errors" trong JSON bật chi tiết cho bước kiểm tra thứ hai: dịch vụ nêu tên trường, liệt kê các giá trị cho phép và báo khi chạm trần 50 hóa đơn chưa thanh toán. Khóa này nằm bên trong container đã ký, nên không thể bị chèn từ bên ngoài.
Trong lúc thiết lập biểu mẫu, hãy đặt "output":"errors" vào JSON; khi thiết lập xong, hãy bỏ khóa này và dựng lại container.
Nếu bản thân chữ ký không khớp, hãy so sánh data và chữ ký của bạn với bộ tham chiếu trong Chữ ký biểu mẫu HTML.
Tiếp theo
Dịch vụ xử lý hóa đơn tạo bằng biểu mẫu giống như hóa đơn từ API hoặc bảng điều khiển:
- Xác nhận thanh toán đến tại Webhook URL. Hãy xác minh chữ ký thông báo bằng khóa bí mật webhook và chỉ giao hàng dựa trên đó.
- Đưa người mua quay lại trang của bạn được cấu hình qua URL thành công (Successful URL) và URL không thành công (Unsuccessful URL) — xem mục “Đưa người mua quay lại trang cửa hàng” trên trang Vòng đời hóa đơn. Việc rơi vào các URL này không xác nhận thanh toán.
- Trạng thái hóa đơn và cửa sổ tìm kiếm thanh toán được mô tả trong Vòng đời hóa đơn.
- Người mua chuyển sai số tiền — xem Khớp thanh toán và chênh lệch số tiền.