Partner API

Cổng thanh toán

Tạo order từ server, chuyển hướng payer sang trang thanh toán do Zenith host, và nhận callback có chữ ký báo kết quả. Chỉ hỗ trợ đơn VND.

Cách hoạt động

Không cần nhúng mã nào vào trang của bạn. Server tạo order bằng một lệnh gọi API, rồi đưa payer sang trang thanh toán do Zenith host — hiển thị đơn, popup thanh toán, theo dõi kết quả và đưa payer quay lại đều do Zenith lo.

  1. Server gọi POST /api/v2/payment-gateway/partner-orders, nhận orderId + checkoutUrl.
  2. Chuyển hướng payer đến checkoutUrl (toàn trang hoặc tab mới).
  3. Payer bấm nút thanh toán trên trang Zenith; popup mở ra và trang tự theo dõi kết quả.
  4. Zenith POST callback có chữ ký về endpoint của bạn báo kết quả.
  5. Thành công thì Zenith đưa payer về returnUrl của bạn.
  6. Server xác minh order bằng GET order trước khi giao hàng.

Thông tin kết nối

MụcGiá trị
Base URL của APIhttps://<api-domain>/api/v2
Header X-Access-Key-IDaccessId do Zenith cấp.
Header X-Access-Key-SecretaccessSecret — chỉ hiển thị một lần lúc cấp, chỉ dùng ở server.
webhookUrlURL callback mặc định đăng ký với Zenith (tuỳ chọn; partnerCallbackUrl theo đơn sẽ thắng).
webhookSecretKiểm tra chữ ký callback — xem trang Webhooks.

Tạo order

POST /api/v2/payment-gateway/partner-orders
curl -X POST "https://<api-domain>/api/v2/payment-gateway/partner-orders" \
  -H "Content-Type: application/json" \
  -H "X-Access-Key-ID: <accessId>" \
  -H "X-Access-Key-Secret: <accessSecret>" \
  -d '{
    "reference": "INV-2026-0001",
    "currency": "vnd",
    "description": "Don hang #0001",
    "partnerCallbackUrl": "https://shop.example.com/zenith/callback",
    "returnUrl": "https://shop.example.com/orders/0001",
    "amount": "1000000",
    "lineItems": [
      { "name": "Goi Pro 1 thang", "unitPrice": 500000, "quantity": 2 }
    ]
  }'
  • reference chỉ dùng một lần trong phạm vi merchant — gửi lại reference đã có (kể cả đơn failed/expired) nhận 409. Bỏ trống thì Zenith tự sinh.
  • amount là chuỗi số thập phân; gửi JSON number sẽ bị từ chối. Nếu gửi lineItems, tổng unitPrice × quantity phải bằng amount.
  • Lưu orderId và checkoutUrl từ response; payer quay lại trả tiếp thì dùng lại checkoutUrl đã lưu.
  • Request tạo bị timeout thì gọi GET /api/v2/payment-gateway/partner-orders?reference=… trước: có order thì dùng lại, chỉ tạo mới khi 404.
  • Phát hiện lỗi qua success / httpCode trong body, không dựa vào mã HTTP.

Trải nghiệm của payer

Trang Zenith hiển thị tóm tắt đơn; payer bấm nút thanh toán và hoàn tất trong popup trong khi trang tự theo dõi kết quả (mỗi 3 giây và khi quay lại tab). Đóng popup không bị coi là huỷ — payer có thể mở lại.

Kết quảHành vi của trang Zenith
paidHiển thị biên nhận; nếu order có returnUrl, đếm ngược 5 giây rồi tự chuyển về.
failedHiển thị thông báo thất bại — không có liên kết quay lại.
expiredHiển thị thông báo hết hạn — không có liên kết quay lại.
returnUrl được thêm hai tham số không ký — orderId và status (luôn paid, vì chỉ đơn đã trả mới được chuyển về). Không dùng tham số URL làm bằng chứng đã thanh toán; hiển thị trạng thái "đang xác nhận" và dựa vào callback hoặc GET order. Nếu returnUrl của bạn đã có sẵn tham số orderId hoặc status, Zenith sẽ ghi đè chúng (các tham số khác được giữ nguyên). Link “quay lại merchant” hiển thị trước khi Zenith xác nhận thanh toán là returnUrl gốc, không thêm tham số, nên trang return của bạn cũng phải chạy được khi thiếu các tham số này.

Xác minh và giao hàng

  1. Nhận callback kind = "paid" với chữ ký hợp lệ (xem trang Webhooks), và
  2. Gọi GET /api/v2/payment-gateway/public/orders/{orderId} từ server, kiểm status = "paid", amount/currency và reference khớp bản ghi của bạn.

Vòng đời order

Trạng tháiÝ nghĩa
pendingĐang chờ thanh toán.
paidĐã thanh toán.
failedThanh toán thất bại.
expiredQuá dueAt hoặc bị đóng do chờ quá lâu.
  • Order không có dueAt sẽ tự đóng sau khoảng 24 giờ nếu vẫn chưa trả.
  • Order expired vẫn có thể thành paid nếu thanh toán đến muộn — bạn nhận callback due rồi paid; hãy xử lý chuyển expired → paid.
  • Payer không thể thanh toán lại order failed hoặc expired trên trang checkout — tạo order mới với reference mới để thử lại. Nếu bạn thay một order đã hết hạn bằng order mới, callback paid đến muộn của order gốc vẫn có thể xuất hiện, nên hãy đảm bảo chỉ giao hàng cho một trong hai order.