Skip to Content
Khái niệmĐơn hàng
View as Markdown

Đơn hàng

Nếu CheckoutSession là thứ người mua thấy, thì Order mới là thứ bạn quan tâm. Nó là bản ghi vĩnh viễn về:

  • Người mua đang mua gì (line items)
  • Bao nhiêu được nợ và bao nhiêu thực tế đã trả
  • Refund đang chờ và đã được áp dụng
  • Reference ngoài của bạn (external_ref) — thường là order ID của chính bạn, được lưu trên Order và trả về tại GET /b2b/v1/orders/{id} (không echo trong payload webhook — xem bên dưới)

Order không bắt buộc có line items: gửi amount thay cho items để thu một số tiền cố định (hoá đơn, tiền đặt cọc, link thanh toán tuỳ ý). Gửi một trong hai, không gửi cả hai.

CheckoutSession chết sau khi một trong các PaymentIntent của nó được settle hoặc TTL hết hạn. Order sống mãi mãi.

Khi nào Order được tạo

Khi bạn gọi POST /b2b/v1/checkout-sessions/quick, InfraIO Pay tạo cả Order mới và CheckoutSession mới trong cùng một transaction. Nếu bạn đã có Order và muốn retry checkout (ví dụ sau khi người mua từ bỏ), dùng POST /b2b/v1/checkout-sessions để gắn một session mới vào order đã có — giữ nguyên audit trail.

Vòng đời

Trạng tháiÝ nghĩa
PENDINGMột CheckoutSession đang chạy và chưa được giải quyết.
PAIDToàn bộ số tiền đã được settle. Webhook payment.settled được phát ở đây. An toàn để fulfillment.
PARTIAL_PAIDTiền đã đến nhưng ít hơn tổng. Xem “Underpayment” bên dưới.
CANCELEDSession hết hạn hoặc merchant đã hủy. metadata.canceled_reason giải thích lý do (payment_timeout, merchant_canceled, …).
REFUNDEDToàn bộ số tiền đã trả đều đã được hoàn lại.
PARTIALLY_REFUNDEDCó refund đã được thực thi nhưng phần còn lại vẫn được giữ là đã trả.

Trạng thái để chuyển logic fulfillment là PAID — không phải COMPLETED của CheckoutSession. Webhook payment.settled là tín hiệu canonical.

Trường external_ref

Khi tạo session bạn có thể đưa kèm external_ref (chuỗi bất kỳ tối đa 255 ký tự — thường là order ID của chính bạn). Nó xuyên suốt cả pipeline:

  • Lưu trên Order
  • Hiển thị trong merchant dashboard cho việc tra cứu support
  • Trả về tại GET /b2b/v1/orders/{id} để webhook handler có thể lấy sau khi nhận payment.settled

Payload webhook không bao gồm external_ref. Để map một webhook payment.* về record của riêng bạn, lấy order_id từ payload và fetch order.

Underpayment

Nếu giao dịch chuyển on-chain của người mua clear ít hơn tổng order, Order chuyển sang PARTIAL_PAID. Bạn có ba lựa chọn:

  1. Chấp nhận và resolve. Chuyển order sang PAID và phát order.resolved. Lựa chọn này không có sẵn qua REST API, nên với luồng self-serve hãy dùng lựa chọn 2 (thu phần còn thiếu).
  2. Chờ phần còn thiếu. Tạo một CheckoutSession mới ứng với cùng Order với amount_due = residual. Người mua trả phần chênh lệch; khi nó settle, Order chuyển sang PAID.
  3. Hủy và refund. Hoàn lại số tiền partial và hủy Order. Người mua chịu mọi chain fee.

Refunds

Refund là API surface riêng và là khái niệm riêng. Xem Khái niệm → Hoàn tiền.

API endpoints

MethodPathGhi chú
POST/b2b/v1/ordersTạo Order mà không có session (hiếm)
GET/b2b/v1/orders/:order_idĐọc order đầy đủ với line items + lịch sử thanh toán
PATCH/b2b/v1/orders/:order_id/cancelHủy một order chưa thanh toán
PATCH/b2b/v1/orders/:order_id/reopenMở lại một order bị auto-cancel (payment_timeout)

Tiếp theo