OMSĐơn hàng
Tạo đơn hàng
Tạo đơn hàng mới từ nội bộ hệ thống
Tạo đơn hàng an toàn với flow checkout của API /v1/customercarts
Nếu muốn tạo đơn hàng một cách an toàn, tự động áp dụng cơ chế khuyến mãi cho chi tiết, cho giỏ hàng...thì nên gọi api checkout của customercarts (/v1/customercarts/checkout). Đây là API được sử dụng bởi màn hình POS để tạo đơn hàng.
Tạo đơn hàng mới
Để gọi API này, bạn phải tính toán trước toàn bộ thông tin đơn hàng. Bao gồm: chi tiết đơn hàng, kết quả tính toán của khuyến mãi, giá bán...API này hiện được gọi nội bộ từ flow checkout của customercarts.
Endpoint
POST /v1/orders
Headers
| Tên | Bắt buộc | Mô tả |
|---|---|---|
Authorization | Có | <JWT> của người dùng có quyền tạo đơn (order.add) tại cửa hàng store_id |
Content-Type | Có | application/json |
Idempotency-Key | Không | Khoá chống tạo trùng. Nếu không truyền, hệ thống tự sinh khoá từ nội dung payload: gửi lại cùng một payload trong vài giây sau khi tạo thành công sẽ bị từ chối với HTTP 409 |
Request Payload
JSON Object Payload:
{
"company_id": 10311,
"creator_id": 1,
"customer_id": 101,
"source": 1,
"source_name": "",
"external_id": "",
"uuid": "3b733736-2278-42d1-8c2f-31d5cef7cd81",
"store_id": 32,
"pickup_store_id": 0,
"billing_full_name": "Hoàng Văn Hải",
"billing_phone": "0909876543",
"billing_email": "",
"billing_address": "15 Trần Phú",
"billing_region_id": 88831,
"billing_sub_region_id": 88810507,
"billing_sub_sub_region_id": 88811332,
"shipping_type": 3,
"shipping_address_id": 0,
"shipping_full_name": "Hoàng Văn Hải",
"shipping_phone": "0909876543",
"shipping_email": "",
"shipping_address": "15 Trần Phú",
"shipping_region_id": 88831,
"shipping_sub_region_id": 88810507,
"shipping_sub_sub_region_id": 88811332,
"shipping_address_line_2": "",
"shipping_instruction": "",
"shipping_legacy_province_name": "",
"shipping_legacy_district_name": "",
"shipping_legacy_ward_name": "",
"shipping_carrier_id": 23,
"warehouse_id": 33,
"payment_method": 11,
"payment_status": 1,
"note": "",
"promotion_coupon": "",
"tax_name": "",
"tax_is_company": 0,
"tax_code": "",
"tax_address": "",
"tax_email": "",
"price_sell": 1963600,
"price_shipping": 20000,
"price_discount_order": 98180,
"price_discount_shipping": 12000,
"price_discount_coupon": 0,
"price_discount": 110180,
"price_final": 1873420,
"ip_address": "203.0.113.10",
"date_created": 0,
"details": [
{
"row_identifier": "486_948_1000_0",
"product_id": 486,
"product_variant_id": 948,
"uom_id": 1000,
"uom_name": "Cái",
"uom_factor": 1,
"uom_quantity": 3,
"uom_unit_price": 479200,
"uom_unit_price_original": 599000,
"selected_options": null,
"type": 1,
"sku": "2397540229784",
"item_type": 1,
"item_name": "PUMA - Áo khoác nam thể thao cổ trụ phối zip Fit Woven Half Zip Training 522129",
"item_serial_number": "",
"item_weight": 400,
"customize_required": 0,
"customize_description": "",
"file_id_list": [],
"bundle_identifier": "",
"bundle_promotion_id": 0,
"bundle_promotion_product_id": 0,
"bundle_promotion_multiplier": 0,
"bundle_index": 0,
"bundle_allocation_rule": "",
"bundle_discount_allocated": 0,
"bundle_promotion_name": "",
"bundle_promotion_type": 0
}
],
"promotionengine": {
"order_promotion_decision": {
"applied": [],
"rejected": [],
"eligible": []
},
"shipping_promotion_decision": {
"applied": [],
"rejected": [],
"eligible": []
},
"coupon_promotion_decision": {
"applied": [],
"rejected": [],
"eligible": []
}
},
"price_policy_id": 1,
"tag": "",
"file_id_list": [],
"weight": 2700,
"quantity": 7
}Các trường chính
| Tên | Kiểu | Bắt buộc | Mô tả |
|---|---|---|---|
company_id | int | Có | ID công ty, phải trùng với công ty của phiên đăng nhập |
creator_id | int | Có | ID người dùng tạo đơn (người dùng của phiên đăng nhập) |
store_id | int | Có | ID cửa hàng tạo đơn; tài khoản phải có quyền order.add tại cửa hàng này |
shipping_type | int | Có | Loại hình vận chuyển (xem constant SHIPPING_TYPE_*) |
pickup_store_id | int | Khi shipping_type = 1 | ID cửa hàng khách đến lấy hàng |
shipping_full_name, shipping_phone, shipping_address, shipping_region_id | Khi shipping_type = 3 | Thông tin người nhận khi giao hàng tận nơi | |
details | array | Có | Danh sách dòng sản phẩm (ít nhất 1 dòng). Mỗi dòng cần product_variant_id, uom_id, uom_quantity, uom_unit_price... |
uuid | string | Không | UUID của đơn. Nếu bỏ trống hệ thống tự sinh. Không được trùng với đơn chưa hủy khác của công ty |
customer_id | int | Không | ID khách hàng. Nếu bỏ trống nhưng có billing_phone, hệ thống tìm khách theo số điện thoại hoặc tự tạo khách mới |
source, source_name, external_id | Không | Nguồn đơn và mã đơn ở hệ thống bên ngoài (xem constant) | |
price_* | int | Không | Các khoản tiền của đơn đã được tính sẵn phía client (price_sell, price_shipping, price_discount_*, price_discount, price_handling, price_tax, price_final, price_deposit) |
promotion_id, promotion_coupon, promotions, coupons, promotionengine | Không | Thông tin khuyến mãi / coupon đã áp dụng | |
payment_method, payment_status | int | Không | Phương thức và trạng thái thanh toán. Với COD (11) đơn mới luôn ở PAYMENT_STATUS_PENDING |
fulfillment_status, shipping_status | int | Không | Trạng thái fulfillment / vận chuyển ban đầu |
aff_click_token | string | Không | Token click affiliate (lấy khi khách mở link cộng tác viên). Có token thì hệ thống ghi nhận hoa hồng cho cộng tác viên của link |
aff_code | string | Không | Mã giới thiệu khách nhập khi đặt hàng (dùng khi không có aff_click_token). Mã phải đang bật và thuộc cộng tác viên đang hoạt động |
redeem_points | int | Không | Số điểm tích luỹ khách dùng |
date_created | int | Không | Thời gian tạo đơn (UNIX timestamp), mặc định là thời điểm gọi API |
Workflow & Logic
- Trạng thái đơn (
status) do hệ thống xác định, không lấy từ payload:shipping_type= 9 (SHIPPING_TYPE_INSTORE): đơn được đánh dấu đã giao và hoàn tất fulfillment; nếupayment_status= 9 (COMPLETED) thìstatus=STATUS_COMPLETE, ngược lại làSTATUS_CONFIRMED_CUSTOMER.shipping_type= 1 hoặc 3: đơn do nhân viên tạo (creator_id> 0) hoặc cóexternal_idsẽ ởSTATUS_CONFIRMED_CUSTOMER, còn lại làSTATUS_NEW.
tax_invoice_typeđược gán tự động:TAX_INVOICE_TYPE_APInếu công ty đã cấu hình đầy đủ nhà cung cấp hóa đơn điện tử, ngược lạiTAX_INVOICE_TYPE_MANUAL.- Nếu không thêm được dòng chi tiết nào, đơn vừa tạo sẽ bị hủy với
cancel_reason=CANCEL_REASON_SYSTEM_ERRORvà API trả lỗi 422. - Sau khi tạo thành công, các bước hậu xử lý (cập nhật khách hàng, điểm tích luỹ, coupon, webhook...) chạy bất đồng bộ.
Response Schema
HTTP 201 - JSON Object
Error Codes
| HTTP | Code | Mô tả |
|---|---|---|
| 401 | error_jwt_is_required | Thiếu token xác thực |
| 409 | error_idempotent_check_duplicate_found | Yêu cầu trùng lặp (cùng Idempotency-Key hoặc cùng payload) vừa được xử lý |
| 422 | error_company_id_required | Thiếu company_id |
| 422 | error_company_id_notfound | company_id không thuộc phiên đăng nhập |
| 422 | error_user_id_notfound | creator_id không hợp lệ |
| 422 | error_not_permission | Không có quyền tạo đơn hàng tại cửa hàng này |
| 422 | error_order_with_uuid_existed(<uuid>) | UUID đã tồn tại trong hệ thống |
| 422 | error_shipping_type_required | Loại vận chuyển không hợp lệ |
| 422 | error_pickup_store_required | Cửa hàng nhận hàng bắt buộc cho loại pickup |
| 422 | error_pickup_store_not_exist | Cửa hàng nhận hàng không tồn tại |
| 422 | error_shift_not_exist | Ca làm việc không tồn tại |
| 422 | error_warehouse_invalid | Kho hàng không hợp lệ |
| 422 | error_order_detail_not_found | Không có chi tiết sản phẩm trong đơn hàng |
| 422 | error_setting_fetch_error | Lỗi lấy cấu hình công ty |
| 422 | error_customer_id_not_found | Khách hàng không tồn tại |
| 422 | error_create_customer_failed | Không tạo được khách hàng mới từ thông tin người đặt |
| 422 | error_shipping_full_name_required | Tên người nhận bắt buộc cho giao hàng |
| 422 | error_shipping_phone_required | Số điện thoại người nhận bắt buộc cho giao hàng |
| 422 | error_shipping_address_required | Địa chỉ giao hàng bắt buộc |
| 422 | error_shipping_region_required | Vùng giao hàng bắt buộc |
| 422 | error_shipping_region_id_not_exist | Vùng giao hàng không tồn tại |
| 422 | error_shipping_sub_region_id_not_exist | Quận/huyện giao hàng không tồn tại |
| 422 | error_shipping_sub_sub_region_id_not_exist | Phường/xã giao hàng không tồn tại |
| 422 | error_billing_region_id_not_exist | Vùng thanh toán không tồn tại |
| 422 | error_billing_sub_region_id_not_exist | Quận/huyện thanh toán không tồn tại |
| 422 | error_billing_sub_sub_region_id_not_exist | Phường/xã thanh toán không tồn tại |
| 422 | error_add_detail_order_invalid_variant_id_<product_variant_id> | Biến thể sản phẩm không tồn tại hoặc không thuộc công ty |
| 422 | error_add_detail_order_invalid_selection_<product_variant_id> | Lựa chọn trong combo trỏ tới sản phẩm không thuộc công ty |
| 422 | error_add_detail_order_sku_<product_variant_id> | Không lưu được dòng chi tiết sản phẩm |