[TOC]
# 外賣接口(前端)
## 1. 簡述
### 1.1 常規說明
* 接口使用 RESTful 風格。
* URL中的 `<id>` / `<slug>` 替換為實際的數值。
* **狀態碼**一般都是指 HTTP 狀態碼。
* 身份驗證信息放在 `Authorization` 請求頭,示例 `Authorization: Bearer <token>`
* 帶有 **公開** 字樣的接口是可以匿名訪問的,為了便于封裝,所有接口都可以帶上身份驗證信息,只是公開的接口會忽略身份驗證信息
### 1.2 HTTP 狀態碼及返回內容說明
**HTTP 狀態碼說明:**
* 200 - 請求成功
* 201 - 請求成功, 并創建了一個對象. 一般是執行 **POST** 動作創建一個新對象時返回.
* 204 - 請求成功, 沒有內容返回. 一般是執行 **DELETE** 動作時返回.
* 400 - 客戶端請求無效. 一般是指客戶端提交的參數不符合要求.
* 401 - 需要身份驗證. 當需要身份驗證, 而未提供身份驗證信息或者身份驗證信息無效.
* 403 - 禁止訪問. 一般情況是權限不足.
* 404 - 資源不存在
* 405 - 動作不允許. 例如接口只接受 **POST** 動作, 而客戶端使用了 **GET** 動作.
* 500 - 服務器內部錯誤
**返回內容說明:**
返回內容是 JSON 格式。除了 2xx, 400 狀態碼之外, 其他狀態碼的出錯信息都出現在 `detail` 字段中, 例如:
```
{
"detail": "身份認證信息未提供。"
}
```
**400狀態碼返回內容說明:**
客戶端請求參數檢查不通過的話,返回狀態碼都是 400,參數出錯的話,返回結果中帶有對應參數的出錯信息列表(數組),一般情況下數組只有一個元素,對于不是參數出錯的錯誤信息,通過 `non_field_errors` 給出,格式與參數的出錯信息相同(都是數組)。
例如:
```
{
"context": [
"使用場景(context)不能為空"
]
}
```
### 1.3 國際手機號碼說明
1. 國內手機號碼不存儲**國家/地區代碼**,僅存儲 11 位數字,如:`18682265887`
2. 國際手機號碼存儲**國家/地區代碼**(包含前置的加號(`+`))和**手機號碼**,如:`+79118064728`
3. 客戶端提交手機號碼參數時,將**國家/地區代碼**和**手機號碼**組合成一個字符串,如:`+79118064728`,`+8618682265887`。后端接收到之后自動進行處理,對于`+86`開頭的手機號碼,自動去掉`+86`標識。
### 1.4 桌臺二維碼說明
桌臺二維碼分為 3 類:堂食桌臺、外賣桌臺、等取桌臺。
二維碼 URL 規則
* 堂食 `http://xxx.com/?rid=1&tid=2&ver=1`
* 堂食(自選) `http://xxx.com/?rid=1&tid=-99&ver=1`
* 外賣 `http://xxx.com/?rid=1&tid=-1&ver=1`
* 等取 `http://xxx.com/?rid=1&tid=-2&ver=1`
查詢參數說明:
* `rid` - 表示外賣后端的餐廳id
* `tid` - 表示桌臺id(以收銀端桌臺table_id為準)
* `ver` - 表示二維碼版本
掃描二維碼進入手機外賣前端頁面(H5)之后,前端從外賣后端獲取到對應餐廳的桌臺數據(在餐廳信息中),并對比 URL 傳過來的 `ver` 是否與后端的(`qrcode_version`)一致,若不一致,則可以告知二維碼失效,并禁用點餐功能。
## 2. 餐廳接口
### 2.1 餐廳信息
`GET /api/v1/frontend/restaurants/<id>?table_id=<table_id>`
查詢參數:
* `table_id` - 桌臺ID(二維碼中的`tid`),`paid_types` 數據與桌臺(用餐類型)有關
返回數據結構如下:
```
{
"id": 1, // 餐廳id
"categories": [ // 分類
{
"id": 2, // 分類id
"name": "Esppresso" // 分類名稱
},
{
"id": 4,
"name": "Brewed"
},
{
"id": 6,
"name": "Hot"
},
{
"id": 8,
"name": "Iced"
},
{
"id": 10,
"name": "Blended Ice"
},
{
"id": 12,
"name": "Food Items"
}
],
"takeout": { // 外賣信息
"slides": [ // 餐廳圖片列表
{
"image": "http://www.baidu.com",
"link": "http://gicater.com",
},
{
"image": "http://www.baidu.com", // 圖片URL
"link": "", // 鏈接URL,值為空則不跳轉
}
],
"phones": [ // 餐廳電話列表
"0755-81234567"
],
"eat_types_enable": [ // 用餐類型狀態(是否可接單),以 eat_type 值作為索引(下標)
true, // 下標0,堂食是否接單,true-是,false-否
true, // 下標1,外賣(配送)是否接單,true-是,false-否
false, // 下標2,外賣(自取/來取)是否接單,true-是,false-否
true // 下標3,等取是否接單,true-是,false-否
],
"cny_exrate": 0.0, // 餐廳計價貨幣對人民幣匯率,用于在線支付時轉換成人民幣金額;人民幣金額=餐廳計價貨幣金額*cny_exrate,只有 cny_exrate 大于0時進行換算,否則 人民幣金額=餐廳計價貨幣金額。
"address": "", // 餐廳地址
"is_user_address_reversed": false, // 用戶地址是否反向,true-反向(從小到大),false-不反向(從大到小)
"region": "深圳市", // 餐廳所在城市,只有中文版收銀有值,可用在百度地圖接口 region 字段
"delivery_times": [ // 外賣配送可選的時間列表(單位分鐘),超過60分鐘的,前端自行轉換成時分格式
30,
45,
60,
75,
90,
105,
120,
135
],
"collect_times": [ // 外賣自取可選的時間列表(單位分鐘)
15,
30,
45,
60,
75,
90
],
"longitude": 0.0, // 餐廳經度
"latitude": 0.0, // 餐廳緯度
"notice": "公告", // 公告
"summary": "餐廳簡介", // 簡介
"attention": "注意事項", // 注意事項
"show_total": 1, // 是否顯示總價
"show_zero": 0, // 是否顯示價格為0的菜
"enable_service": 1,
"pay_mch": "qf", // 支付服務商標識,qf-錢方,sqb-收錢吧。錢方需要走獲取用戶 openid 流程,參考 8 錢方微信支付
"language_type": 1, // 語言類型,1-系統默認,2-自定義(可自選)
"country_code": "+86", // 國家地區代碼,發送國際短信時需要
"takeaway_use_takeout_price": true // 等取是否使用外志價格,true-是,false-否
},
"takeout_delivery_fee": { // 外賣費信息
"delivery_scope": "0.0~20.0", // 配送范圍,單位公里,只做顯示,不做計算依據
"min_amount": 5.0 // 起送金額
},
"takeout_periods": { // 外賣營業時間,0周日,1-6周一至周六,每天有多個時間段(目前最多2個)
"open": [ // 是否營業,true-營業,false-停業;下標 0~6 表示周日至周六
false,
false,
true,
true,
true,
true,
true
],
"0": [
{ // 營業時間段
"start_time": "12:00", // 開始時間
"end_time": "14:00" // 結束時間
}
],
"1": [
{
"start_time": "00:00",
"end_time": "23:59"
}
],
"2": [
{
"start_time": "00:00",
"end_time": "23:59"
}
],
"3": [
{
"start_time": "00:00",
"end_time": "23:59"
}
],
"4": [
{
"start_time": "00:00",
"end_time": "23:59"
}
],
"5": [
{
"start_time": "00:00",
"end_time": "23:59"
}
],
"6": [
{
"start_time": "00:00",
"end_time": "23:59"
}
]
},
"tables": [ // 桌臺列表
{
"table_id": 1, // 桌臺ID
"table_name": "A1", // 桌臺名稱
"seat_num": 1, // 座位數
"qrcode_version": 1 // 桌臺二維碼版本號
},
{
"table_id": 2,
"table_name": "A2",
"seat_num": 1,
"qrcode_version": 1
},
{
"table_id": 5,
"table_name": "A5",
"seat_num": 1,
"qrcode_version": 1
}
],
"paid_types": [ // 可用的支付類型列表(下單接口會用到)
{ // 默認線下支付
"value": 1,
"label": "線下支付"
},
{ // 微信支付需要餐廳支持,餐廳支持的情況下,前端需要判斷是不是微信瀏覽器,若不是,則不可用
"value": 2,
"label": "微信支付"
},
{ // 需要餐廳支持并啟用
"value": 3,
"label": "會員卡"
}
],
"order_default": { // 開臺消費,沒有的話返回 null
"periods": [ // 有開臺消費的時間段,如果開始時間大于結束時間,比較方法 start_time <= nowTime 或者 end_time >= nowTime
{
"start_time": "04:00", // 開始時間
"end_time": "14:00" // 結束時間
},
{
"start_time": "14:00",
"end_time": "04:00"
}
],
"products": [ // 開臺消費必選的商品(菜品)
{
"id": 480, // 商品id
"item_id": 6005, // 商品item_id
"item_name": "Garden Salad", // 商品名稱
"item_type": 0,
"specs": [ // 規格,只有1個
{
"pu": 0, // 規格索引
"price": 4.2, // 價格(堂食)
"unit": "", // 規格名稱(單位)
"takeout_price": 4.2
}
],
"thumbnail": "//pos-cn-node.oss-cn-beijing.aliyuncs.com/1.jpg", // 縮略圖URL
"description": "Refreshing ingredient with savory Thousand Island Sauce",
"num": 1, // 單份包含商品的數量
"is_by_seat": false // 是否按位消費
}
]
},
"name": "aaa", // 餐廳名稱
"location_name_1": "", // 餐廳地址
"slug": "",
"is_support_tax": false, // 是否支持計稅功能,若不支持,下單時可不調用稅費計算接口
"show_privacy_policy": false, // 是否顯示隱私政策,true-顯示,false-不顯示
"product_include_tax": true, // 菜品是否含稅
"currency_name": "¥", // 貨幣符號
"decimal_places": 2,
"decimal_char": ".",
"edition": "cn", // 收銀軟件版本,cn-中文版,en-英文版,優先判斷是不是中文版,其他情況可當作英文版
"start_time": "04:00:00",
"is_member_card_enable": true, // 會員卡服務是否可用,true-可用,false-不可用
"tz_offset": 0,
"tz_string": "Z",
"today": "2019-04-18", // 餐廳當前日期
"weekday": 4 // 餐廳當前周幾,0周日,1-6周一至周六
}
```
營業狀態判斷(至少要做 3 個判斷):
1. 用餐類型(`eat_type`)是否**可接單**,根據 `takeout.eat_types_enable` 判斷
2. 當天**是否營業**,根據 `takeout_periods.open` 判斷
3. 當前時間是否在營業時間段內,根據 `takeout_periods.X` 判斷
## 3. 用戶接口
### 3.1 發送短信驗證碼
`POST /api/v1/frontend/users/send-phone-token`
提交參數:
* `res_id` - 餐廳id
* `phone` - 手機號碼
* `context` - 短信場景,`login`-登錄(驗證碼快捷登錄),`register`-注冊/綁定手機
請求成功返回狀態碼200,返回數據結構如下:
```
{
"send": true // true 表示發送成功, false 表示發送失敗
}
```
### 3.2 登錄
`POST /api/v1/frontend/users/login`
提交參數:
* `res_id` - 餐廳id
* `username` - 手機號碼 / 電子郵件,目前只支持手機號碼
* `password` - 密碼,至少 6 位;若使用手機短信快捷登錄,這里傳手機驗證碼,短信發送接口 `context=login`
身份驗證成功的話返回狀態碼200,返回數據結構如下:
```
{
"id": 2,
"token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1aWQiOjIsImlhdCI6MTU0ODAzNjI2NCwiZXhwIjoxNTQ4MTIyNjY0fQ.thercE0EgPEWDtwF-YhSRUw8zu2UTOO0sBuaTI1yM_g", // token
"ttl": 86400 // token 有效期(單位秒)
}
```
若用戶名或密碼錯誤,返回狀態碼403。
### 3.3 獲取用戶信息
`GET /api/v1/frontend/users/me`
```
{
"id": 1,
"username": "digwtx01", // 用戶名
"phone": "", // 電話號碼
"email": "",
"avatar": "http://www", // 頭像URL
"nick_name": "digwtx", // 昵稱
"addresses": [{ // 送餐地址列表
"id": 1,
"name": "iwerwer", // 姓名
"gender": 0, // 性別,0-女性,1-男性
"phone": "15389781522", // 電話
"address": "iwierew", // 地址
"distance": 2, // 與餐廳的距離(單位千米)
"is_default": false // 是否為默認地址
}, {
"id": 2,
"name": "iwerwer",
"gender": 0, // 性別,0-女性,1-男性
"phone": "18682265887",
"address": "iwierew",
"distance": 3,
"is_default": false
}
],
"member_card": { // 會員卡信息,若沒有則為 null
"card_id": "wx001" // 會員卡號
}
}
```
### 3.4 修改用戶信息
`POST /api/v1/frontend/users/me`
可修改的信息(可任意修改一項或多項):
* `avatar` - 頭像URL
* `nick_name` - 昵稱
修改成功返回狀態碼200,數據數據結構與 **3.3 獲取用戶信息** 相同。
### 3.5 Facebook 登錄
假設前端使用 Facebook JavaScript JDK 進行開發,可以獲取到用戶的 `access_token`。
當拿到 FB 用戶的 `access_token` 之后,調用 `3.2 登錄` 接口進行登錄。
提交參數(JSON):
```
{
"res_id": 1, // 餐廳id,按實際傳值
"username": "user_id", // 可隨意傳,只要不為空即可
"password": "access_token", // FB 用戶的 access_token,非常重要
"user_type": 2 // 固定傳2
}
```
返回及異常參考 `3.2 登錄` 接口。
### 3.6 綁定手機號碼
`POST /api/v1/frontend/users/bind-phone`
此接口需要提供身份信息。
此接口需要發送短信驗證碼:向需要綁定的手機號碼發送一個注冊驗證碼,短信發送接口 `context=register`
提交參數示例(JSON):
```
{
"phone": "13811115555", // 需要綁定的手機號碼
"token": "138532" // 手機驗證碼
}
```
綁定成功的話返回狀態碼200。
若驗證碼無效,則返回狀態碼400。
若用戶已綁定手機號碼,則返回狀態碼403,返回信息**用戶已綁定手機號碼**。
## 4. 用戶地址接口
此部分接口需要登錄。
### 4.1 地址列表
`GET /api/v1/frontend/user-addresses`
返回數據結構如下:
```
{
"count": 3,
"code": 0,
"next": null, // 下一頁URL
"previous": null, // 上一頁URL
"results": [ // 結果集
{
"id": 2,
"name": "iewirwe", // 姓名
"gender": 0, // 性別,0-女性,1-男性
"phone": "irweirweiriwe", // 電話
"address": "iweirweir", // 地址
"longitude": 0, // 經度
"latitude": 0, // 緯度
"distance": 1, // 地址與餐廳的距離(單位千米)
"is_default": true // 是否為默認地址
},
// ...
]
}
```
### 4.2 地址詳情
`GET /api/v1/frontend/user-addresses/<id>`
數據結構參與列表接口。
### 4.3 增加地址
`POST /api/v1/frontend/user-addresses`
提交數據結構(JSON):
```
{
"name": "iewirwe", // 姓名
"gender": 0, // 性別,0-女性,1-男性
"phone": "15388882222", // 聯系電話
"address": "iweirweir", // 地址
"longitude": 0, // 經度(可不傳,建議傳)
"latitude": 0, // 緯度(可不傳,建議傳)
"distance": 1, // 地址與餐廳的距離(單位千米),負數表示距離未知
"is_default": false // 是否為默認地址
}
```
### 4.4 修改地址
* `PUT /api/v1/frontend/user-addresses/<id>` 要提交所有需要字段
* `PATCH /api/v1/frontend/user-addresses/<id>` 可只提交部分字段
### 4.5 刪除地址
`DELETE /api/v1/frontend/user-addresses/<id>`
刪除成功的話返回狀態碼204。
### 4.6 設為默認地址
`POST /api/v1/frontend/user-addresses/<id>/set-default`
設置成功的話返回狀態碼200,返回地址詳情。
## 5. 商品(菜品)接口
普通菜品、套餐、調味品本質上都是商品,都存儲在同一個數據庫表中,數據結構也大致相同。
1. 普通商品有**多規格**,套餐目前暫定單規格。多規格單選。
2. 普通商品有**可選調味品**,套餐本身的**可選調味品**無效,套餐內菜品有**可選調味品**。**可選調味品**多選。調味品有可能有**規格**(單位),單規格的。
3. 套餐**必選組**內的菜品全部必選。
3. 套餐**可選組**中的菜品可能有**多規格**,如果處理比較麻煩,當有多規格時,可考慮只使用第一規格。
### 5.1 商品列表
`GET /api/v1/frontend/products/simple?res_id=<res_id>&table_id=<table_id>`
參數說明:
* `res_id` - (必填)餐廳id
* `table_id` - (必填)桌臺ID(二維碼中的`tid`),菜品跟用餐類型有關,有些菜品只在指定的用餐類型中可用
* `category_id` - (選填)分類id,分類id從餐廳信息 `categories` 中獲取
返回數據結構如下(默認帶分頁,可針對需求取消分頁):
```
{
"count": 3,
"next": null, // 下一頁URL
"previous": null, // 上一頁URL
"results": [] // 結果集,單個數據結構參見商品詳情
}
```
### 5.2 商品詳情
`GET /api/v1/frontend/products/<id>?res_id=<res_id>`
查詢參數說明:
* `res_id` - (必填)餐廳id
返回數據結構如下:
```
{
"id": 30, // 商品id
"specs": [ // 規格,至少會有1個,如果只有一個,則不需要選擇
{
"pu": 0, // 規格索引,值范圍0~4
"price": 5.0, // 價格(堂食)
"takeout_price": 5.0, // 外賣價格
"unit": "Dozen" // 規格(單位)
}
],
"condiments": [ // 需要選擇的調味品
{
"id": 33, // 調味品(商品)id
"item_id": 6002, // 調味品(商品)item_id
"item_name": "no sugar", // 調味品(商品)名稱
"price": 0.0 // 價格,有些調味味需要額外收費
},
{
"id": 34,
"item_id": 6003,
"item_name": "cream",
"price": 3.0
}
],
"thumbnail": "", // 商品縮略圖URL
"images": [
{
"url": "xxxx"
}
],
"tax": 0,
"courses": [ // 套餐組信息,只有當商品是套餐時才會有
{
"id": 1, // 分組id
"group_name": "必選組", // 分組名稱
"is_must": 1, // 是否必選,1-必選,0-可選,必選的話則該分組下所有商品都要選擇
"choose_num": 1, // 需要選擇的數量,必選組的話,則這個數量忽略
"entries": [ // 分組內的商品
{
"id": 21, // 商品id
"item_id": 1021, // 商品item_id
"item_name": "Iced Caffe Mocha", // 套餐中的商品名稱
"num": 1.0, // 包含數量
"specs": [{ // 套餐組中的規格,至少有一組規格,也可能有多組規格
"pu": 1, // 規格索引
"unit": "C", // 規格,顯示時需要將規格一并顯示
"price": 0, // 加價價格,大于0表示加價,如果選擇了的話,則需要計入套餐總價
"origin_price": 4.0, // 原始價格,可用在某些需要顯示的場景
}],
"condiments": []
}
]
},
{
"id": 2,
"group_name": "可選組",
"is_must": 0, // 是否必選
"choose_num": 2,
"entries": [
{
"id": 17,
"item_id": 1017,
"item_name": "Bottle of Water",
"num": 1.0,
"specs": [{
"pu": 0,
"unit": "C",
"price": 1.0,
"origin_price": 2.0
}],
"condiments": [ // 套餐中的商品也是有可能需要選擇調味品的
{
"id": 33,
"item_id": 6002,
"item_name": "no sugar",
"price": 0.0
},
{
"id": 34,
"item_id": 6003,
"item_name": "cream",
"price": 3.0
}
]
},
{
"id": 12,
"item_id": 1012,
"item_name": "Starbucks Coffee",
"num": 1.0,
"specs": [{
"pu": 0,
"unit": "T",
"price": 0.0,
"origin_price": 2
}],
"condiments": []
}
]
},
{
"id": 3,
"group_name": "可選組2",
"is_must": 0,
"choose_num": 1,
"entries": [
{
"id": 13,
"item_id": 1013,
"item_name": "Shot In The Dark ",
"num": 1,
"specs": [ // 套餐組中的菜品的多個規格
{
"pu": 0,
"unit": "T",
"price": 0,
"origin_price": 3.25
},
{
"pu": 1,
"unit": "C",
"price": 0,
"origin_price": 3.5
},
{
"pu": 2,
"unit": "V",
"price": 0,
"origin_price": 3.75
}
],
"condiments": []
},
{
"id": 9,
"item_id": 1009,
"item_name": "Espresso",
"num": 1.0,
"specs": [
"pu": 0,
"unit": "D",
"price": 0.5,
"origin_price": 3,
],
"condiments": []
}
]
}
],
"item_id": 6004, // 商品item_id
"item_name": "abc23ccccc", // 商品名稱
"item_type": 3, // 商品類型,0-普通菜品,3-套餐
"box_fee": 0.0, // 餐盒費
"category": 8,
"tax_group": null
}
```
## 6. 訂單
### 6.1 訂單列表
* 外賣訂單列表 `GET /api/v1/frontend/orders?res_id=<res_id>&table_id=-1` [需要登錄]
* 堂食訂單列表 `GET /api/v1/frontend/orders?res_id=<res_id>&table_id=<tabel_id>`
查詢參數:
* `res_id` - (必填)餐廳id
* `table_id` - (必填)桌臺id
* `status` - (選填)訂單狀態,`9`-已完成的,`unfinished`-未完成的
返回數據結構:
```
{
"count": 15,
"code": 0,
"next": null, // 下一頁URL
"previous": null, // 上一頁URL
"results": [ // 結果集
{ // 訂單
"id": 1, // 訂單id
"products": [ // 訂單產品(菜品)
{
"product_item_id": 6000,
"product_item_name": "milk", // 菜品名稱
"pu": 0,
"unit": "C", // 菜品規格
"desc": "C", // 描述信息,如果是套餐,則描述套餐內容,如果是普通菜品,則描述規格
"price": 3.0, // 菜品單價
"origin_price": 0.0,
"qty": 1, // 菜品數量
"box_fee": 0.0, // 單個菜品總的餐盒費
"total_price": 3.0 // 總價
},
{
"product_item_id": 1016,
"product_item_name": "Hot Chocolate",
"pu": 0,
"unit": "D",
"desc": "D",
"price": 25.0,
"origin_price": 0.0,
"qty": 1,
"box_fee": 0.0,
"total_price": 25.0
}
],
"customer_name": "", // 客戶姓名
"customer_phone": "", // 客戶電話
"customer_address": "", // 客戶地址
"customer_count": 1, // 客戶人數或者餐具數
"eat_type": 0, // 0-堂食,1-外賣配送,2-外賣自取,3-等取
"paid_type": 1, // 付款方式,1-線下支付,2-微信支付,3-會員卡
"is_paid": false, // 是否支付,支付狀態和訂單狀態分開
"paid_time": null, // 支付時間
"plan_time": null, // 計劃時間(預計時間)
"total_price": 29.0, // 菜品總價
"total_box_fee": 0.0, // 總餐盒費
"total_tax_fee": 0.0,
"delivery_fee": 0.0, // 配送費
"total_fee": 35.0, // 訂單總金額
"remark": "", // 備注信息
"trade_no": "11556070571001", // 訂單號
"take_code": "15", // 取餐號,eat_type值為0、2、3時才會有
"take_code_datauri": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAARwAAABSCAIAA", // 取餐號條形碼圖片(DataURI,Base64格式)
"status": 1, // 訂單狀態,0-用戶下單,1-待商家確認,2-商家制作中,3-商家制作完成,4-配送中,5-已送達,9-已完成,-1-用戶取消,-2-商家取消
"create_time": "2019-04-24T09:49:31.543714+08:00", // 下單時間
"restaurant": 1,
"table": { // 如果沒有會是 null
"table_id": 1,
"table_name": "1",
}
},
// ...
]
}
```
### 6.2 訂單詳情
`GET /api/v1/frontend/orders/<id>?res_id=<res_id>`
數據結構參考列表接口。
### 6.3 計算配送費
`POST /api/v1/frontend/orders/calc-delivery-fee?res_id=<res_id>`
提交參數:
```
{
"distance": 2 // 距離(單位千米)
}
```
返回數據結構:
```
{
"delivery_fee": 0 // 配送費,負數表示不在配送范圍
}
```
### 6.4 計算稅費
`POST /api/v1/frontend/orders/calc-tax-fee?res_id=<res_id>`
提交數據結構(為了方便,可直接提交**下單**接口的數據結構):
```
{
"restaurant": 1, // res_id
"delivery_fee": 0, // 配送費
"total_box_fee": 0, // 總餐盒費
"discount_fee": 0, // 折扣金額,正數
"products": [{
"product": 549, // 菜品id
"price": 4.2, // 菜品價格
"qty": 1, // 數量
"item_id": 6005, // 菜品item_id
"item_name": "Garden Salad", // 菜品名稱
"total_price": 4.2, // 菜品總價
}
]
}
```
返回數據結構:
```
{
"tax_fee": "1.06", // 稅費
"is_tax_included": false // 是否已含稅,若已含稅,則稅費不計入 total_fee
}
```
### 6.5 下單
`POST /api/v1/frontend/orders?res_id=<res_id>`
提交數據結構(JSON):
```
{
"restaurant": 1, // 餐廳id
"table_id": 5, // 桌臺id,參考桌臺信息
"eat_type": 1, // 0-堂食,1-外賣配送,2-外賣自取,3-等取
"paid_type": 1, // 支付類型,1-線下支付(默認),2-微信支付,3-會員卡
"user_address": 18, // 用戶收貨地址id,沒有可不傳或者傳null
"customer_name": "", // 客戶姓名
"customer_phone": "", // 客戶電話
"customer_address": "", // 客戶地址
"customer_count": 1, // 客戶人數或者餐具數
"total_price": 28, // 商品總價
"total_box_fee": 0, // 總餐盒費
"total_tax_fee": 0, // 總稅費,調用稅費計算接口獲得
"delivery_fee": 0, // 配送費
"discount_fee": 0, // 用正數表示,計算 total_fee 時要減去,調用折扣計算接口獲得
"service_fee": 0, // 服務費
"total_fee": 34, // 總金額
"total_fee_cny": -1, // 總金額(人民幣計價),只有 在線支付 時需要換算并傳入,否則傳-1值或者該字段不傳。當 takeout.cny_exrate>0 時 total_fee_cny=total_fee * cny_exrate,否則 total_fee_cny=total_fee。在線支付目前只支持人民幣結算。
"remark": "", // 整單備注信息
"plan_time": "2019-04-28T15:22+0800", // 計劃時間,ISO8601格式,對于配送,是預計(期望)送達時間;對于來取,是預計到店時間;若沒有則不傳。
"ignore_extra_price": true, // 是否忽略菜品中的加價菜、調味品的價格
"products": [{ // 訂單商品列表
"product": 1, // 菜品id
"item_id": 3, // 菜品item_id
"price": 3, // 菜品價格
"unit": "C", // 菜品規格
"pu": 0, // 菜品規格索引
"req": "", // 備注,需求
"qty": 1, // 菜品數量
"box_fee": 0, // 餐盒費=單個菜品餐盒費*數量。(目前前端傳的是單份菜的餐盒費,后端也按單份驗證)
"total_price": 3, // 商品總價=單個菜品價格*數量
"condiments": [{ // 調味品,如果沒有可不傳或傳空列表[]
"product": 33, // 調味品id
"price": 0, // 調味品價格
"item_name": " no sugar" // 調味品名稱
}, {
"product": 34,
"price": 3,
"item_name": "cream"
}
]
}, {
"product": 30,
"item_id": 6004,
"price": 25,
"unit": "D",
"pu": 0,
"qty": 1, // 套餐數量(份數)
"total_price": 25,
"box_fee": 0,
"children": [{ // 套餐中選擇的菜品,套餐需要有 children,
"product": 21,
"item_id": 53,
"price": 0,
"unit": "X",
"pu": 0,
"qty": 1, // 單份套餐中包含的數量
"total_price": 0,
"condiments": []
}, {
"product": 17,
"item_id": 1017,
"price": 1,
"unit": "C",
"pu": 1,
"qty": 1,
"total_price": 1,
"condiments": [{ // 套餐中的菜品的調味品,如果沒有可不傳或傳空列表[]
"product": 34,
"price": 3,
"item_name": "cream"
}
]
}
]
}
],
"discounts": [], // 折扣明細,參考 6.9 接口
"services": [] // 服務費明細,參考 6.9 接口
}
```
提交數據有問題的話,返回狀態碼400。
下單成功返回狀態碼200,返回訂單詳情(數據結構參考列表接口)。
---
1. `product` / `product.children` 數據結構基本相同。
總價計算方式:
1. 菜品/套餐的 `price` 使用單價,加價菜品、調味品 `price` 單獨表示,計算 `total_price` / `total_fee` / 單個菜品/套餐總價 時再加上。
2. 菜品/套餐的 `price` 使用總價(包含加價菜品、調味品的 `price`),下單時增加 `ignore_extra_price` 進行聲明。[目前采用這種方式]
### 6.6 獲取支付URL
* 在線支付(微信) `GET /api/v1/frontend/orders/<id>/pay-url?res_id=<res_id>&openid=<openid>&method=wechat`
* 會員卡支付 `GET /api/v1/frontend/orders/<id>/pay-url?res_id=<res_id>&method=member`
在線支付目前對接兩種:
* 錢方 (`qf`)
* 收錢吧 (`sqb`)
當餐廳使用錢方支付方式(`takeout.pay_mch == 'qf'`)時,需要獲取用戶 `openid`,并傳入。
以下幾種情況會返回 HTTP 狀態碼 403:
* 使用錢方支付方式 且 `openid` 為空
* 訂單下單時傳的 **支付類型** 不是微信支付
* 訂單已支付、訂單已取消(關閉)、訂單已完成
沒有異常的情況下,返回數據結構:
```
{
"url": "http://xxxxx"
}
```
若 `url` 為空字符串,表示獲取支付URL失敗(或異常),需要重新獲取。
若 `url` 不為空,則跳轉到這個 `url`,會進入 錢方/收錢吧 提供的支付頁面,這個頁面會喚醒微信支付。
支付成功的話,會跳轉到前端的一個支付結果頁面(攜帶 `rid` 和 `oid` (訂單id)兩個查詢參數,例如`?rid=1&oid=3`),支付結果頁需要根據下面的接口查詢最終的**支付狀態**。
### 6.7 查詢支付結果
`GET /api/v1/frontend/orders/<id>/is-paid?res_id=<res_id>`
返回數據結構:
```
{
"is_paid": true // 是否支付
}
```
### 6.8 計算折扣金額(優惠金額)
`POST /api/v1/frontend/orders/calc-discount-fee?res_id=<res_id>`
提交數據結構:
```
{
"restaurant": 1, // res_id
"products": [{
"product": 549, // 菜品id
"price": 4.2, // 菜品價格
"qty": 1, // 數量
"item_id": 6005, // 菜品item_id
"item_name": "Garden Salad", // 菜品名稱
"total_price": 4.2, // 菜品總價
}
]
}
```
返回數據結構:
```
{
"discount_fee": 1.5 // 用正數表示,0表示沒有折扣
}
```
### 6.9 統一計算費用
`POST /api/v1/frontend/orders/calc-fee?res_id=<res_id>`
提交數據結構:
```
{
"restaurant": 1, // res_id,必傳
"table_id": 1, // 桌臺ID,必傳
"eat_type": 0, // 用餐類型,參考下單接口,一定要傳
"distance": 0, // 配送距離,非配送訂單可不傳,或者傳0值
"total_box_fee": 0, // 總餐盒費
"products": [{
"product": 549, // 菜品id
"price": 4.2, // 菜品價格
"qty": 1, // 數量
"item_id": 6005, // 菜品item_id
"item_name": "Garden Salad", // 菜品名稱
"total_price": 4.2, // 菜品總價
}
]
}
```
返回數據結構:
```
{
"delivery_fee": 0, // 配送費,負數表示不在配送范圍,僅限配送訂單使用
"discount_fee": 1.5, // 用正數表示,0表示沒有折扣。包括開臺折扣、會員折扣。
"service_fee": 0.6, // 額外的服務費
"tax_fee": "1.06", // 稅費
"is_tax_included": false, // 是否已含稅,若已含稅,則 tax_fee 不計入 total_fee
"discounts": [ // 折扣明細,下單時原樣傳回
{
"name": "XXX 1 元",
"value": 1
},
{
"name": "5% off",
"value": 0.68
},
{
"name": "Discount 0.8",
"is_member": true,
"value": 2.38
}
],
"services": [ // 服務費明細,下單時原樣傳回
{
"name": "5% Service",
"value": 0.6
}
]
}
```
## 7. 圖片上傳
### 7.1 Base64 形式
`POST /api/v1/frontend/image-upload-base64`
提交參數:
```
{
"base64": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABoAAAAaCAYAAACpSkzOAAAAK0lEQVRIiWNUUNP7z0AHwEQPS0YtGrVo1KJRi0YtGrVo1KJRi0YtGj4WAQCQSgGnEEr+twAAAABJRU5ErkJggg==" // base64 圖片數據
}
```
上傳成功返回圖片URL:
```
{
"url": "http://localhost:8040/media/orgs/gicater/wx_onvmr1aXGcOaACz-_JFfM_Eoophc.jpg"
}
```
## 8. 錢方微信支付
目前通過錢方支付對接微信支付。(暫不使用官方微信支付)
微信支付相關接口需要在微信瀏覽器內使用。
**特別說明**:接口前綴 `/api/v1/frontend/weixin` 改為 `/api/v1/frontend/qfpay`。
### 8.1 [公開] 獲取微信授權登錄 URL
`GET /api/v1/frontend/qfpay/authorize-url?res_id=<res_id>&table_id=<table_id>`
* `res_id` <- `rid`
* `table_id` <- `tid`
返回數據結構:
```
{
"url": "https://openapi-test.qfpay.com/tool/v1/get_weixin_oauth_code?app_code=2DAB13A0AF4D4031820149BCD58188D0&redirect_uri=https%3A%2F%2Fapi.digwtx.com%3Frid%3D1&mchid=2w1exh5NlY&sign=4A6CBC119E5F948F6525EAF1E202156A"
}
```
得到 `url` 之后在微信瀏覽器中打開, 然后會跳轉到 `redirect_uri` 對應的頁面, 并且隨帶 `code` 查詢參數, `code` 參數用于獲取用戶的 `openid`。
`redirect_uri` 對應的前端頁面需要讀取 `code` 參數,并通過下面的接口獲取用戶的 `openid`。
### 8.2 [公開] 獲取微信 openid
`POST /api/v1/frontend/qfpay/get-weixin-openid?res_id=<res_id>`
提交參數:
```
{
"code": "iweirwieriweriweirwei" // 上一步獲取的 code
}
```
若 `code` 無效或已使用,則返回 HTTP 狀態碼 400。
返回數據結構:
```
{
"openid": "olaIk1gMClTA5_RnkC7hvmhVpChE"
}
```
`openid` 在微信支付時需要使用,`openid` 有可能會變化(錢方可能會有多個公眾號),前端需要保存 `openid`。
## 9. 微信
### 9.1 獲取 JSSDK 配置信息
### 9.2 獲取微信授權登錄 URL
`GET /api/v1/frontend/weixin/authorize-url?res_id=<res_id>&table_id=<table_id>`
* `res_id` <- `rid`
* `table_id` <- `tid`
返回狀態碼 200, 返回數據結構如下:
```
{
"url": "https://open.weixin.qq.com/connect/oauth2/authorize?appid=wxe1224df14973c3c4&redirect_uri=http%3A%2F%2F192.168.199.149%3A8099%2F%3Frid%3D1%26tid%3D-1&response_type=code&scope=snsapi_userinfo&state=biz:1haIYC:UXDWpHpJ6kyV4YFgbBvOsw_EFyk#wechat_redirect"
}
```
得到 `url` 之后在微信瀏覽器中打開. 若用戶授權登錄, 則跳轉到 `redirect_uri`, 并且隨帶 `code` / `state`參數, `code` 參數用于獲取 `access_token`.
`redirect_uri` 對應的頁面需要讀取 `code` / `state` 參數。
### 9.3 獲取微信 access_token
`POST /api/v1/frontend/weixin/access-token`
提交參數:
```
{
"res_id": 1, // 店鋪標識
"invite_code": "邀請碼", // 用戶的邀請碼
"code": "081by3xF1rgqj803NFuF17abxF1by3xD", // 跳轉到 redirect_uri 附帶的 code
"state": "biz%3A1h10MA%3AKSlANGsFNq96Qd2GvVTn7LDsE1A" // 跳轉到 redirect_uri 附帶的 state
}
```
說明:
* 在未登錄狀態(或登錄已失效)調用時,請求中不要帶 `Authorization` 請求頭。
* 若請求后返回401狀態碼,需要重試。
* 若在系統中沒有跟微信用戶對應用戶,則會創建一個新的用戶(根據微信用戶微信)。
* 在有效登錄狀態下調用此接口,會將微信用戶與當前登錄用戶進行綁定。
若成功獲取 `access_token`, 則返回狀態碼 200, 返回數據結構如下(與 `3.2 登錄` 接口相同):
```
{
"token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1aWQiOjM0LCJpYXQiOjE1NTE3NTUwMTQsImV4cCI6MTU1MTg0MTQxNH0.NiT1uN_OKTYlTxn9TvZBTMyQKR8UBYg4g2tciKVyMIo", // 用戶 token
"openid": "wieriweirweir", // 在微信公眾號下的openid
"id": 34, // 用戶ID
"ttl": 86400 // token 有效期(單位秒)
}
```
否則返回狀態碼 400. 主要是提示 `code` / `state` 無效.
## 10. Facebook
### 10.1 驗證 access_token
`POST /api/v1/frontend/facebook/debug-token`
提交參數:
```
{
"res_id": 1, // 餐廳ID
"user_id": 23423424234, // facebook登錄后得到的用戶id
"access_token": "081by3xF1rgqj803NFuF17abxF1by3xD", // facebook 登錄后得到的 accessToken
"name": "xxxx" // facebook 用戶昵稱
}
```
若驗證成功,則返回狀態碼 200, 返回數據結構如下(與 `3.2 登錄` 接口相同):
```
{
"token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1aWQiOjM0LCJpYXQiOjE1NTE3NTUwMTQsImV4cCI6MTU1MTg0MTQxNH0.NiT1uN_OKTYlTxn9TvZBTMyQKR8UBYg4g2tciKVyMIo", // 用戶 token
"openid": "wieriweirweir", // 在微信公眾號下的openid
"id": 34, // 用戶ID
"ttl": 86400 // token 有效期(單位秒)
}
```
驗證失敗,返回狀態碼400。
## 11. 會員卡
說明:
* 若用戶沒有開通(或綁定)會員卡,則調用這些接口會返回狀態碼403.
### 11.1 開卡/領卡
`POST /api/v1/frontend/user-member-card/open`
若開卡成功,返回狀態碼200.
異常:
* 若已有會員卡,則返回狀態碼403.
### 11.2 綁定已有卡片
`POST /api/v1/frontend/user-member-card/bind`
提交數據:
```
{
"card_id": "xxx", // 會員卡號
"card_pwd": "", // 會員卡密碼,允許為空密碼
}
```
若卡號、密碼驗證成功且綁定成功,則返回狀態碼200.
異常:
* 若已有會員卡,則返回狀態碼403.
* 若會員卡已被綁定,則返回狀態碼400.
* 若卡號或密碼錯誤,則返回狀態碼400.
### 11.3 查詢會員信息
`GET /api/v1/frontend/user-member-card/query`
返回數據結構:
```
{
"cur_score": 480, // 當前積分
"status": 1,
"card_level": "", // 卡等級名稱
"discount": 0.8, // 當前折扣,0.8表示8折
"discount_desc": "", // 當前折扣描述
"balance": "361.79", // 可用余額
"card_id": "wx001" // 卡號
}
```
### 11.4 查詢消費明細(余額明細)
`GET /api/v1/frontend/user-member-card/consume-logs`
返回數據結構:
```
{
"count": 20,
"next": "/api/v1/frontend/user-member-card/consume-logs?page=2&page_size=20", // 下一頁URL,沒有則為 null
"previous": null, // 上一頁URL,沒有則為 null
"results": [ // 結果集
{
"ori_money": 13.6,
"act_money": 13.6, // 實際金額,若打折或贈送,則與 ori_money 值會不同
"description": "消費13.6,獲得積分13\n", // 說明,只有中文,不支持多語言
"org_name": "DIGWTX01", // 餐廳名稱
"amount": 361.79, // 余額,最多顯示2位小數
"time": "2019-08-20T11:52:40+08:00", // 時間
"type": 2 // 1-充值,2-消費
},
// ...
]
}
```
### 11.5 查詢積分明細
`GET /api/v1/frontend/user-member-card/score-logs`
返回數據結構:
```
{
"count": 20,
"next": "/api/v1/frontend/user-member-card/score-logs?page=2&page_size=20", // 下一頁URL,沒有則為 null
"previous": null, // 上一頁URL,沒有則為 null
"results": [ // 結果集
{
"org_name": "DIGWTX01", // 餐廳名稱
"type": 7, // 見下面描述
"description": "消費13.6,獲得積分13\n", // 說明,只有中文,不支持多語言
"save_score": 13, // 積分變化,正數表示增加,負數表示扣減
"time": "2019-08-20T11:52:40+08:00" // 時間
},
// ...
]
}
```
積分類型(`type`)說明:
* `6`/`9` - 充值贈送
* `7` - 消費獲得
* `71` - 抵扣積分
* 其他數值 - 其他
### 11.6 解綁會員卡
`POST /api/v1/frontend/user-member-card/unbind`
若解綁成功,則返回狀態碼200. 前端需要刷新數據,因為會員卡沒有了。
異常:
* 若解綁時用戶無會員卡,則返回狀態碼403.
## 12. 會員充值
### 12.1 獲取充值金額列表
`GET /api/v1/frontend/deposit-orders/prices`
返回數據結構:
```
{
"can_order": true, // 是否可以進行充值操作
"wechat": [ // 微信支付充值金額
{
"money_price": "1.00", // 計價貨幣金額,即實際充到會員卡的金額
"price": "5.00" // 對應的人民幣金額,即實際需要支付的金額
},
{
"money_price": "10.00",
"price": "70.00"
},
{
"money_price": "100.00",
"price": "700.00"
}
],
"alipay": [] // 支付寶支付充值金額
}
```
目前只支持微信支付。
### 12.2 訂單列表
`GET /api/v1/frontend/deposit-orders`
返回數據結構:
```
{
"count": 42,
"code": 0,
"next": "/api/v1/frontend/deposit-orders?page=2",
"previous": null,
"results": [
{
"id": 50,
"pay_type": "wechat", // 支付方式
"money_price": "1.00", // 要充值的金額
"price": "5.00", // 要支付的金額
"status": "success", // 狀態,new-待支付,expired-已過期,success-已支付/已完成
"pay_time": "2019-08-13T11:49:48.590637+08:00", // 支付時間,未支付時為 null
"expiry_time": "2019-08-13T12:04:08.912040+08:00", // 過期時間
"create_time": "2019-08-13T11:49:08.912040+08:00" // 下單時間
},
// ...
]
}
```
### 12.3 下單
`POST /api/v1/frontend/deposit-orders`
提交參數:
```
{
"pay_type": "wechat", // 支付方式
"money_price": "10", // 要充值的金額
"price": "70" // 要支付的金額
}
```
`money_price` / `price` 由 `12.1` 接口提供。
下單成功返回狀態碼201,返回數據結構參考 列表 接口。
### 12.4 獲取支付鏈接
`GET /api/v1/frontend/deposit-orders/<id>/pay-url`
返回數據結構:
```
{
"url": "http://xxx/xxxx" // 支付URL,跳轉過去
}
```
異常:
* 若訂單已過期或已支付,則返回狀態碼403.
支付成功后,會跳轉到前端的結果頁,同時在 URL 上附帶餐廳ID和訂單ID參數(示例 `?rid=1&doid=108` )查詢參數。
### 12.5 查詢支付結果
`GET /api/v1/frontend/deposit-orders/<id>/is-paid`
返回數據結構:
```
{
"is_paid": true, // 是否支付,true-已支付,false-未支付
"order": {
"id": 101,
"pay_type": "wechat",
"money_price": "1.00",
"price": "5.00",
"status": "success",
"pay_time": "2019-08-20T09:16:08.344958+08:00",
"deposit_time": null,
"expiry_time": "2019-08-20T09:30:52.853616+08:00",
"create_time": "2019-08-20T09:15:52.853616+08:00"
}
}
```
## 13 異常充值訂單
### 13.1 異常訂單列表
`GET /api/v1/frontend/deposit-orders/exceptions`
返回數據結構:
```
{
"count": 64,
"code": 0,
"next": "/api/v1/frontend/deposit-orders/exceptions?page=2", // 下一頁URL,沒有則為null
"previous": null, // 上一頁URL,沒有則為null
"results": [ // 結果集
{
"id": 251, // 訂單id
"order_id": "D251", // 訂單編號
"feedback": { // 申訴狀態,未申訴則為null
"status": "new", // 申訴狀態,new-待處理,success-已處理
"has_images": false
},
"pay_type": "wechat", // 支付類型
"money_price": "1.00", // 充值金額
"price": "5.00", // 付款金額(¥)
"status": "expired", // 狀態,new-待支付,expired-已過期,success-已支付/已完成
"pay_time": null, / 支付時間
"deposit_time": null,
"expiry_time": "2019-09-02T18:35:52.392855+08:00",
"create_time": "2019-09-02T18:20:52.392855+08:00" // 下單時間
},
// ...
]
}
```
已處理/未處理 根據 `feedback.status` 判斷:
* `new` 或者 `feedback`為空 - 未處理
* `success` - 已處理
已到賬/未到賬根據 **充值訂單** 的 `status` 判斷:
* `new` / `expired` - 未到賬
* `success` - 已到賬
### 13.2 充值訂單申訴
`POST /api/v1/frontend/deposit-order-feedback`
提交數據:
```
{
"order": 251, // 充值訂單id
"phone": "15389781522", // 聯系電話
"reason": "xxx", // 申訴原因
"image_1": "", // 憑證圖片1 URL
"image_2": "", // 憑證圖片2 URL
"image_3": "", // 憑證圖片3 URL
}
```
圖片上傳參考 `7.1` 接口。圖片至少要1張。
**申訴原因** 前端固定傳。
提交成功返回狀態碼 200.
返回狀態碼 400 的情況:
* 訂單已申訴的
* 訂單已完成的
## 14 異常收款訂單
### 14.1 異常訂單列表
`GET /api/v1/frontend/orders/exceptions`
返回數據結構(主要結構參考 `6.1` 接口):
```
{
"count": 1,
"code": 0,
"next": null, // 下一頁URL,沒有則為null
"previous": null,
"results": [ // 訂單列表,數據結構參考 6.1 接口
{
"id": 1073,
"products": [
{
"product_item_id": 6009,
"product_item_name": "Spaghetti Americana",
"desc": "",
"pu": 0,
"unit": "",
"price": 7.5,
"origin_price": 0.0,
"qty": 1,
"box_fee": 0.0,
"total_price": 7.5,
"thumbnail": "//pos-cn-node.oss-cn-beijing.aliyuncs.com//{90063812-9CAF-11E9-99B5-FCAA144EED3C}/6009-1.png?x-oss-process=image%2Fauto-orient%2C1%2Fresize%2Cm_fill%2Cw_256%2Ch_256%2Fquality%2Cq_85"
},
{
"product_item_id": 6005,
"product_item_name": "Garden Salad",
"desc": "",
"pu": 0,
"unit": "",
"price": 4.2,
"origin_price": 0.0,
"qty": 1,
"box_fee": 0.0,
"total_price": 4.2,
"thumbnail": "//pos-cn-node.oss-cn-beijing.aliyuncs.com//{90063812-9CAF-11E9-99B5-FCAA144EED3C}/6005-1.png?x-oss-process=image%2Fauto-orient%2C1%2Fresize%2Cm_fill%2Cw_256%2Ch_256%2Fquality%2Cq_85"
}
],
"table": {
"table_id": -1,
"table_name": "Quick Service"
},
"feedback": { // 申訴狀態,未申訴則為null
"status": "new", // 申訴狀態,new-待處理,success-已處理
"has_images": false
},
"customer_name": "234",
"customer_phone": "234234234234",
"customer_address": "中山市興中道28號中山市興中體育場|||123456",
"customer_count": 1,
"eat_type": 1,
"paid_type": 2,
"is_paid": false,
"paid_time": null,
"paid_mch": "caijinbao",
"plan_time": "2019-09-19T17:13:47.666000+08:00",
"total_price": 11.7,
"total_box_fee": 0.0,
"delivery_fee": 1.0,
"discount_fee": 2.34,
"is_tax_included": false,
"total_tax_fee": 0.07,
"total_fee": 10.43,
"total_fee_cny": 1.27,
"total_fee_cny_real": -1.0,
"take_code": "",
"take_code_datauri": "",
"lang": "zh-hans",
"remark": "",
"trade_no": "11568882596073",
"out_trade_no": "11568882596073X97833",
"out_order_id": "",
"order_head_id": 0,
"status": 0,
"create_time": "2019-09-19T16:43:16.698245+08:00",
"restaurant": 1,
"user_address": 18
}
]
}
```
已處理/未處理 根據 `feedback.status` 判斷:
* `new` 或者 `feedback`為空 - 未處理
* `success` - 已處理
已收款/未收款根據 **is_paid** 判斷:
* `true` - 已收款
* `false` - 未收款
### 14.2 訂單申訴
`POST /api/v1/frontend/order-feedback`
提交數據:
```
{
"order": 251, // 訂單id
"phone": "15389781522", // 聯系電話
"reason": "xxx", // 申訴原因
"image_1": "", // 憑證圖片1 URL
"image_2": "", // 憑證圖片2 URL
"image_3": "", // 憑證圖片3 URL
}
```
圖片上傳參考 `7.1` 接口。圖片至少要1張。
**申訴原因** 前端固定傳。
提交成功返回狀態碼 200.
返回狀態碼 400 的情況:
* 訂單已申訴的
* 訂單已完成的