Wixtar Member Transactions Reverse
Description
Wixtar 全通路會員中介平台 - 複合式還原交易 API。提供外部系統交易還原主入口,涵蓋全退 (full)、部分退貨 (partial) 與交易作廢情境 (POST /v1/public/members/transactions/reverse)。
業務與運算邏輯
- 退貨模式:支援
full (全額退貨) 與 partial (部分商品退貨)。
- 交易對應:必須同時帶入原交易單號
original_sale_id 與本次還原交易單號 reverse_sale_id。
- 品牌篩選 (brand_id):未帶或空字串時自動取
token_brand_id 帶入。
Resource
POST /v1/member/wixtar/transactions/reverse
Authorization
採用 OAuth 2.0 Bearer Token(全通路 Token),並支援以下兩種 Wixtar 認證模式(兩者擇一提供):
* 模式 1 (裝置端自管 Token,推薦):於 Header 帶入 X-Member-Center-Token(由 Wixtar Member Token 取得),此時 X-Client-Id 與 X-Shop-Id 為選填。
* 模式 2 (後端代管 Token,向後相容):未帶入 X-Member-Center-Token 時,必須在 Header 提供 X-Client-Id 與 X-Shop-Id,全通路將自動依後台設定與 Redis 快取代管換發 Token。
認證模式二擇一:若提供 X-Member-Center-Token,則 X-Client-Id 與 X-Shop-Id 為選填;若未提供 X-Member-Center-Token,則 X-Client-Id 與 X-Shop-Id 為必填。
| Name |
Type |
Description |
| X-Member-Center-Token |
string |
(optional) 裝置端自管之 Wixtar Access Token (由 POST /v1/member/wixtar/token 取得)。若有提供則優先以此 Token 轉發 Wixtar |
| X-Client-Id |
string |
(optional/條件必填) POS 機或呼叫端設備代碼。若未提供 X-Member-Center-Token 則為必填 |
| X-Shop-Id |
string |
(optional/條件必填) 門市代碼。若未提供 X-Member-Center-Token 則為必填 |
Request Body Parameters
| Name |
Type |
Description |
| request_id |
string |
冪等識別碼 (UUID 格式) |
| original_sale_id |
string |
原交易單號 (長度 1..40) |
| reverse_sale_id |
string |
還原/退貨交易單號 (長度 1..40) |
| vip_id |
string |
會員編號 (長度 1..20) |
| reverse_type |
string |
還原類型:full(全退/作廢)或 partial(部分退貨) |
| reverse_date |
string |
還原交易時間 (YYYY-MM-DD HH:MM:SS) |
| tot_sales |
number |
退貨金額 (≤ 0) |
| tot_pcs |
number |
退貨數量 (≤ 0) |
| tot_tips |
number |
退貨服務費 (≤ 0) |
| tot_extra |
number |
退貨溢收額 (≤ 0) |
| tot_discharge |
number |
(optional) 尾數折讓金額 (還原額 ≥ 0) |
| brand_id |
string |
(optional) 品牌編號 (未帶時自動取 token_brand_id 或集團範圍) |
| products |
Products[] |
(optional) 商品退貨明細清單 |
| tastes |
Tastes[] |
(optional) 商品加值退貨明細清單 |
| promotions |
Promotions[] |
(optional) 促銷退貨明細清單 |
| bonus_points |
integer |
(optional) 扣回/調整點數 |
| redeem_points |
integer |
(optional) 返還扣點 |
| vouchers |
Vouchers[] |
(optional) 票券反核銷清單 |
| card_no |
string |
(optional) 會員卡號 |
| sale_desc |
string |
(optional) 交易摘要說明 |
| remark |
string |
(optional) 備註說明 |
Request Body Parameters - Products
| Name |
Type |
Description |
| item_no |
integer |
品項序號 |
| prod_id |
string |
商品編號 |
| prod_name |
string |
商品名稱 |
| dep_id |
string |
類別編號 |
| dep_name |
string |
類別名稱 |
| tot_pcs |
number |
退貨數量 (≤ 0) |
| tot_sales |
number |
退貨金額 (≤ 0) |
| tot_disc |
number |
(optional) 退貨折扣金額 |
Request Body Parameters - Tastes
| Name |
Type |
Description |
| item_no |
integer |
品項序號 |
| taste_id |
integer |
加值類別代碼 |
| taste_name |
string |
加值類別名稱 |
| taste_item_no |
integer |
加值項目代碼 |
| taste_item_name |
string |
加值項目名稱 |
| tot_pcs |
number |
退貨數量 (≤ 0) |
| tot_sales |
number |
退貨金額 (≤ 0) |
Request Body Parameters - Promotions
| Name |
Type |
Description |
| prom_id |
string |
促銷活動編號 |
| prom_name |
string |
促銷活動名稱 |
| tot_pcs |
number |
退貨數量 (≤ 0) |
| tot_sales |
number |
退貨金額 (≤ 0) |
| tot_disc |
number |
(optional) 促銷折抵金額 |
| prom_scope |
integer |
(必填) 促銷範圍:1=整單促銷;2=商品促銷 |
Request Body Parameters - Vouchers
| Name |
Type |
Description |
| tk_no |
string |
欲反核銷之票券號碼 |
Request Example
{
"request_id": "550e8400-e29b-41d4-a716-446655440030",
"brand_id": "24436074",
"original_sale_id": "SALE20260624001",
"reverse_sale_id": "RTN20260630001",
"vip_id": "CM00000001",
"reverse_type": "full",
"reverse_date": "2026-06-30 10:00:00",
"tot_sales": -1500.0,
"tot_pcs": -2.0,
"tot_tips": 0.0,
"tot_extra": 0.0,
"bonus_points": 15,
"redeem_points": 0,
"products": [
{
"item_no": 1,
"prod_id": "P001",
"prod_name": "商品A",
"dep_id": "D001",
"dep_name": "類別A",
"tot_pcs": -2.0,
"tot_sales": -1500.0
}
],
"tastes": [
{
"item_no": 1,
"taste_id": 1,
"taste_name": "加料",
"taste_item_no": 1,
"taste_item_name": "加大杯",
"tot_pcs": -1.0,
"tot_sales": -20.0
}
],
"vouchers": [
{
"tk_no": "TK00000001"
}
]
}
Response Body Parameters
| Name |
Type |
Description |
| status |
integer |
HTTP 狀態碼 (例如: 200) |
| code |
string |
業務回應代碼 (成功為 "000000") |
| message |
string |
回應訊息 (例如: "Success") |
| data |
Data |
主要業務資料內容 |
Response Body Parameters - Data
| Name |
Type |
Description |
| reverse_sale_id |
string |
退貨交易單號 |
| vip_id |
string |
會員編號 |
| remaining_total_points |
integer |
還原後可用點數 |
| bonus_points |
integer |
實際扣回加點數 |
| redeem_points |
integer |
實際補回扣點數 |
| vouchers |
Vouchers[] |
票券核銷/反核銷結果清單 |
Response Body Parameters - Vouchers
| Name |
Type |
Description |
| tk_no |
string |
票券號碼 |
| status |
string |
反核銷後狀態 |
Response Example - Http Code = 200
{
"status": 200,
"code": "000000",
"message": "Success",
"data": {
"reverse_sale_id": "RTN20260630001",
"vip_id": "CM00000001",
"remaining_total_points": 490,
"bonus_points": 15,
"redeem_points": 0,
"vouchers": [
{
"tk_no": "TK00000001",
"status": "5"
}
]
}
}
Response Example 錯誤回應 - 400 Pydantic參數驗證(必填欄位缺漏)
{
"status": 200,
"code": "400",
"message": "缺少必填欄位:request_id(欄位代號:request_id);缺少必填欄位:original_sale_id(欄位代號:original_sale_id);缺少必填欄位:reverse_sale_id(欄位代號:reverse_sale_id);缺少必填欄位:vip_id(欄位代號:vip_id);缺少必填欄位:reverse_type(欄位代號:reverse_type);缺少必填欄位:reverse_date(欄位代號:reverse_date);缺少必填欄位:tot_sales(欄位代號:tot_sales);缺少必填欄位:tot_pcs(欄位代號:tot_pcs);缺少必填欄位:tot_tips(欄位代號:tot_tips);缺少必填欄位:tot_extra(欄位代號:tot_extra)",
"data": {
"errors_zh": [
"缺少必填欄位:request_id(欄位代號:request_id)",
"缺少必填欄位:original_sale_id(欄位代號:original_sale_id)",
"缺少必填欄位:reverse_sale_id(欄位代號:reverse_sale_id)",
"缺少必填欄位:vip_id(欄位代號:vip_id)",
"缺少必填欄位:reverse_type(欄位代號:reverse_type)",
"缺少必填欄位:reverse_date(欄位代號:reverse_date)",
"缺少必填欄位:tot_sales(欄位代號:tot_sales)",
"缺少必填欄位:tot_pcs(欄位代號:tot_pcs)",
"缺少必填欄位:tot_tips(欄位代號:tot_tips)",
"缺少必填欄位:tot_extra(欄位代號:tot_extra)"
],
"errors": [
{
"type": "missing",
"loc": [
"body",
"request_id"
],
"msg": "Field required",
"input": {}
},
{
"type": "missing",
"loc": [
"body",
"original_sale_id"
],
"msg": "Field required",
"input": {}
},
{
"type": "missing",
"loc": [
"body",
"reverse_sale_id"
],
"msg": "Field required",
"input": {}
},
{
"type": "missing",
"loc": [
"body",
"vip_id"
],
"msg": "Field required",
"input": {}
},
{
"type": "missing",
"loc": [
"body",
"reverse_type"
],
"msg": "Field required",
"input": {}
},
{
"type": "missing",
"loc": [
"body",
"reverse_date"
],
"msg": "Field required",
"input": {}
},
{
"type": "missing",
"loc": [
"body",
"tot_sales"
],
"msg": "Field required",
"input": {}
},
{
"type": "missing",
"loc": [
"body",
"tot_pcs"
],
"msg": "Field required",
"input": {}
},
{
"type": "missing",
"loc": [
"body",
"tot_tips"
],
"msg": "Field required",
"input": {}
},
{
"type": "missing",
"loc": [
"body",
"tot_extra"
],
"msg": "Field required",
"input": {}
}
]
}
}
Response Example 錯誤回應 - 4091 request_id重複但內容不一致
{
"status": 200,
"code": "4091",
"message": "request_id 重複但請求內容不一致"
}
Response Example 錯誤回應 - 400 request_id快取損毀
{
"status": 200,
"code": "400",
"message": "request_id 已完成但快取損毀,請確認後重試"
}
Response Example 錯誤回應 - 400 request_id處理中
{
"status": 200,
"code": "400",
"message": "相同 request_id 處理中,請稍後查詢"
}
Response Example 錯誤回應 - 500 查詢會員失敗
{
"status": 200,
"code": "500",
"message": "查詢會員失敗"
}
Response Example 錯誤回應 - 404 查無對應會員
{
"status": 200,
"code": "404",
"message": "查無對應會員"
}
Response Example 錯誤回應 - 400 會員交易處理中
{
"status": 200,
"code": "400",
"message": "會員交易處理中,請稍後再試"
}
Response Example 錯誤回應 - 500 查詢原交易失敗
{
"status": 200,
"code": "500",
"message": "查詢原交易失敗"
}
Response Example 錯誤回應 - 404 原交易單號不存在
{
"status": 200,
"code": "404",
"message": "原交易單號 SALE20260622001 不存在"
}
Response Example 錯誤回應 - 400 原交易單號已作廢
{
"status": 200,
"code": "400",
"message": "原交易單號 SALE20260622001 已作廢,不可重複還原"
}
Response Example 錯誤回應 - 500 查詢退貨單號失敗
{
"status": 200,
"code": "500",
"message": "查詢退貨單號失敗"
}
Response Example 錯誤回應 - 4092 退貨單號已存在
{
"status": 200,
"code": "4092",
"message": "退貨單號 RTN20260630001 已存在"
}
Response Example 錯誤回應 - 500 查詢票券失敗
{
"status": 200,
"code": "500",
"message": "查詢票券失敗"
}
Response Example 錯誤回應 - 400 票券查無或未透過此交易核銷
{
"status": 200,
"code": "400",
"message": "票券查無或未透過此交易核銷:TK00000001"
}
Response Example 錯誤回應 - 400 票券已反核銷無法再次反核銷
{
"status": 200,
"code": "400",
"message": "票券尚未核銷或已反核銷,無法再次反核銷:TK00000001"
}
Response Example 錯誤回應 - 500 查詢原交易票券失敗
{
"status": 200,
"code": "500",
"message": "查詢原交易票券失敗"
}
Response Example 錯誤回應 - 400 reverse_type=full票券未涵蓋全部
{
"status": 200,
"code": "400",
"message": "reverse_type=full 時 vouchers 須涵蓋原交易全部已核銷票券,缺漏:TK00000002"
}
Response Example 錯誤回應 - 400 還原業務錯誤(動態訊息)
{
"status": 200,
"code": "400",
"message": "還原金額超過原交易可退金額"
}
Response Example 錯誤回應 - 500 票券反核銷失敗
{
"status": 200,
"code": "500",
"message": "票券反核銷失敗,請稍後重試"
}
Response Example 錯誤回應 - 500 還原交易失敗
{
"status": 200,
"code": "500",
"message": "還原交易失敗"
}