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

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ườngNội dung
database64url của JSON chứa các trường hóa đơn
signatureHMAC-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

  1. Dựng một đối tượng JSON với các trường hóa đơn.
  2. Mã hóa nó thành base64url. Đây là chuỗi data.
  3. 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óaBắt buộcNội dung
projectIdID dự án lấy từ cài đặt trong bảng điều khiển, uuid
amountFiatSố 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
currencyFiatTiền pháp định: USD, EUR hoặc RUB
timeToPayThờ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ố
descriptionkhôngMô tả cho người mua, tối đa 1.000 ký tự
serviceDatakhô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
outputkhôngerrors — 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 raDị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ạiLỗi chung, không nêu lý do
Chữ ký khớp, nhưng một trường điền saiLỗi chung. Với "output":"errors" — lỗi chi tiết
Cả hai bước kiểm tra đều đạtTrang 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.