Tính phí ship theo khoảng cách bằng Directions API
Hướng dẫn tính phí ship/cước vận chuyển theo khoảng cách và thời gian thực tế bằng /v1/directions của GoGoDuk — tối ưu cho xe máy, miễn phí.
Phí ship đồng giá nghe thì gọn, nhưng càng chạy càng lệch: đơn ở xa thì lỗ, đơn ở gần thì khách thấy đắt và bỏ giỏ hàng. Cách công bằng hơn là tính phí theo khoảng cách và thời gian thực tế của tuyến đường. Bài này hướng dẫn lấy hai con số đó từ Directions API của GoGoDuk rồi biến thành công thức tính cước ship — với routing tối ưu cho xe máy, đúng cách phần lớn shipper ở Việt Nam di chuyển.
Vì sao tính theo khoảng cách thực, không phải chim bay
Nhiều người tính phí bằng khoảng cách đường chim bay (Haversine) giữa hai toạ độ. Vấn đề là khoảng cách chim bay gần như luôn ngắn hơn quãng đường thật. Ví dụ một shop ở Quận 1 giao cho khách ở Thủ Đức (TP.HCM): đường chim bay có thể chỉ ~9 km, nhưng quãng đường xe máy thật — qua cầu, đường một chiều, vòng xoay — thường dài hơn đáng kể. Tính phí theo chim bay nghĩa là bạn đang trợ giá cho mọi đơn đi xa.
Mô hình này khác với tính phí theo vùng (zone-based): chia thành phố thành các quận/phường rồi gán phí cố định cho mỗi vùng. Nếu bạn cần mô hình đó, xem bài Xây dựng phân vùng giao hàng (Delivery Zones). Quy tắc chọn nhanh:
- Theo vùng — đơn giản, dễ đoán, hợp khi bạn chỉ phục vụ vài quận nội thành.
- Theo khoảng cách — chính xác và công bằng, hợp khi bán kính giao rộng hoặc muốn phí phản ánh đúng chi phí từng đơn.
Lấy khoảng cách & thời gian từ /v1/directions
Endpoint trả về định dạng tương thích Google Directions, nên hai trường ta
cần nằm ngay trong routes[0].legs[0].
Request
Gọi trực tiếp bằng curl hoặc fetch — SDK TypeScript hiện chưa bọc directions,
nên ở đây dùng request thô. Ví dụ shop ở Quận 1 giao cho khách ở Thủ Đức:
origin/destination— dạnglat,lng.vehicle— hiện hỗ trợmotobike(mặc định);carsẽ có sau.- Scope key cần có:
routing:read.
Response
JSON rút gọn — ta chỉ quan tâm distance.value và duration.value của leg đầu:
Lưu ý đơn vị, dễ sai nhất ở đây:
distance.valuetính bằng mét (chia 1000 ra km).duration.valuetính bằng giây (chia 60 ra phút).
Công thức tính phí ship
Hãy tách phần tính phí thành một hàm thuần, dễ test và tái sử dụng. Các con số VND dưới đây chỉ là minh hoạ — không phải giá của GoGoDuk, cũng không phải biểu cước của hãng giao hàng nào; bạn thay bằng chính sách giá của mình.
Phụ phí theo thời gian
duration.value cho phép cộng thêm phụ phí cho tuyến mất nhiều thời gian (giờ
cao điểm, đường kẹt) — distance và duration bổ sung cho nhau:
Xử lý tuyến ESTIMATED
Khi engine không nối được hai điểm (đảo, mạng đường đứt đoạn, input lệch), GoGoDuk
không trả lỗi mà trả tuyến ước lượng với status: "ESTIMATED": lúc này
distance là khoảng cách chim bay nhân hệ số đường bộ, duration ước theo vận
tốc trung bình. Bạn vẫn luôn có một con số để tính phí, nhưng nên xử lý minh bạch:
Hai cách thường dùng: (1) vẫn báo phí nhưng gắn cờ "phí ước lượng", hoặc (2) với đơn giá trị cao thì bắt nhân viên xác nhận trước khi chốt.
Lưu ý khi đưa lên production
- Tính phí ở backend, không ở client. Nếu để JavaScript trình duyệt tính, khách có thể chỉnh giá trước khi gửi đơn.
- Cache theo cặp
origin→destination. Cùng một shop giao tới cùng một địa chỉ thì khoảng cách không đổi — cache lại để khỏi gọi lại mỗi lần. - Hiện chỉ có point-to-point, chưa có distance-matrix. Nếu một đơn có nhiều
điểm giao, gọi
/v1/directionsnhiều lần cho từng chặng (batch matrix nằm trong roadmap, chưa khả dụng). - Khi khách thả ghim trên bản đồ thay vì gõ địa chỉ, dùng reverse geocoding để ra tỉnh/huyện và toạ độ trước, rồi mới đưa toạ độ vào directions.
Khi nào không nên tự build
Thẳng thắn: Google Directions và Goong Directions đều đã trưởng thành và rất ổn
định — nếu bạn đã trả tiền và hài lòng, không nhất thiết phải đổi. Điểm mạnh của
GoGoDuk ở bài toán này là miễn phí vĩnh viễn và hồ sơ định tuyến xe máy
tinh chỉnh cho đường Việt Nam, nên quãng đường (và do đó phí ship) khớp với cách
shipper thật chạy. Lưu ý hồ sơ car chưa có; nếu đội xe của bạn là ô tô, hãy chờ
bản cập nhật đó.
Kết luận
Công thức gọn lại chỉ là: gọi /v1/directions → lấy distance.value (mét) và
duration.value (giây) → đưa vào hàm tính phí theo bậc, cộng phụ phí thời gian
nếu cần, và xử lý riêng tuyến ESTIMATED.
- Đọc tài liệu Directions API.
- Tạo API key trong dashboard với scope
routing:read. - Xem thêm bài giới thiệu Directions API.
Có câu hỏi hay muốn khoe sản phẩm? Tham gia nhóm hỗ trợ Telegram của chúng tôi.
Muốn dùng GoGoDuk?
Miễn phí trọn đời — 100 request/ngày mỗi tài khoản, không cần thẻ tín dụng. Giới hạn cao hơn theo yêu cầu.
Đăng ký →