Skip to content

Webhook vận chuyển ​

Cách này dành cho cửa hàng muốn tự nối đơn vị giao hàng riêng thay vì dùng kênh Ahamove / AllinGo có sẵn ở Hub kết nối. Chủ cửa hàng dựng 2 webhook (ví dụ bằng n8n) (báo giá, tạo đơn giao) gọi AllinGo/Ahamove, rồi khai báo địa chỉ ở Cài đặt → Giao hàng.

Luồng: nhân viên mở đơn → Giao hàng → nhập/kiểm tra địa chỉ giao → SieuTroly gọi webhook báo giá → hiện danh sách giá của nhiều hãng/dịch vụ → chọn một → Giao hàng → SieuTroly gọi webhook tạo đơn → đơn chuyển sang trạng thái «Đang giao hàng» (tự tạo nếu workspace chưa có) → n8n gọi về webhook trạng thái khi có tài xế/đang giao/đã giao.

Yêu cầu: URL https công khai (không nhận địa chỉ nội bộ/localhost). Mỗi lần gọi tối đa 25 giây, phản hồi ≤ 512KB, JSON.

1) Webhook báo giá — SieuTroly → n8n ​

POST {quote_url}

json
{
  "event": "shipping.quote",
  "provider": "allingo",
  "order": { "id": "…", "number": "DH20261012-001", "total": 120000, "paid": false, "cod_amount": 120000, "note": "",
             "items": [{ "name": "Heo quay", "quantity": 2, "price": 60000 }] },
  "pickup":  { "name": "Heo Quay", "phone": "0281234567", "address": "1 Lê Lợi, Q1", "lat": 10.77, "lng": 106.70 },
  "dropoff": { "name": "An", "phone": "0900000000", "address": "12 Nguyễn Huệ, Q1", "lat": null, "lng": null },
  "package": { "weight_kg": 2 }
}

cod_amount = số tiền tài xế thu hộ (0 nếu đơn đã thanh toán). lat/lng chỉ có khi đã nhập.

Phản hồi — danh sách báo giá (một trong các dạng: {quotes:[…]}, {data:{quotes:[…]}}, hoặc mảng thuần; cũng nhận khóa services/rates/options):

json
{ "quotes": [
  { "id": "grab-bike", "carrier": "GrabExpress", "service": "Bike", "fee": 38000, "eta": "25 phút" },
  { "id": "aha-bike",  "carrier": "Ahamove",     "service": "Bike", "fee": 32000, "eta_minutes": 20, "logo": "https://…/logo.png" }
] }
  • fee (hoặc price, total_price, ship_fee…): số VND (38000), chuỗi "38.000đ", "38k". Báo giá không có giá (≤ 0) bị bỏ.
  • id nên duy nhất; thiếu thì SieuTroly tự đặt. Mọi trường khác của từng báo giá được giữ nguyên và gửi lại ở bước tạo đơn (quote.raw) để n8n dùng.
  • Lỗi: { "error": "1", "message": "Địa chỉ ngoài vùng phục vụ" } (hoặc success:false) → hiện thông điệp cho nhân viên.

2) Webhook tạo đơn giao — SieuTroly → n8n ​

POST {create_url}

json
{
  "event": "shipping.create", "provider": "allingo",
  "order": { … như trên … }, "pickup": { … }, "dropoff": { … }, "package": { "weight_kg": 2 },
  "quote": { "id": "grab-bike", "carrier": "GrabExpress", "service": "Bike", "fee": 38000, "raw": { …nguyên báo giá… } },
  "callback_url": "https://api.example.com/webhooks/shipping/<workspaceId>"
}

Chỉ nhận báo giá đã trả về ở bước 1 (trong vòng 15 phút) — phí không do máy khách quyết định.

Phản hồi (bắt buộc có mã đơn giao):

json
{ "order_id": "AHM123", "tracking_url": "https://…", "driver_name": "Tài xế A", "driver_phone": "0987654321", "status": "ASSIGNING", "fee": 38000 }

(order_id có thể là tracking_id/id/shipment_id; có thể đặt trong data.) Lỗi như bước 1.

3) Webhook trạng thái — n8n → SieuTroly ​

POST {callback_url} (hiện ở Cài đặt → Giao hàng) kèm header X-SieuTroly-Token: <khóa> — khóa sinh ở nút Tạo khóa webhook trạng thái (chỉ hiện một lần; hệ thống chỉ lưu băm).

json
{ "order_id": "AHM123", "status": "delivering", "status_text": "Tài xế đang giao", "driver_name": "…", "driver_phone": "…", "tracking_url": "https://…", "fee": 38000 }
  • Xác định đơn bằng order_id (mã đơn giao ở bước 2) hoặc order_number của SieuTroly.
  • status: delivered/completed/done/đã giao… → đã giao; failed/cancelled/returned/huỷ… → thất bại (cho phép tạo lại đơn giao); còn lại → đang giao.
  • Bật Tự chuyển sang Hoàn thành khi đã giao để đơn tự sang trạng thái completed (nếu workspace có trạng thái này).
  • Phản hồi: { "ok": true, "state": "delivered" }; sai khóa → 401.

Dữ liệu trên đơn ​

GET /api/orders/:id và API công khai trả shipping: { provider, carrier, service, fee, state (created|delivering|delivered|failed), status_text, tracking_id, tracking_url, driver_name, driver_phone }. Webhook thuê bao có thêm sự kiện order.shipping_created.