Wixtar Member Points Status
Description
Wixtar 全通路會員中介平台 - 點數狀態/凍結 API。提供外部平台透過全通路 API 中介層發送點數狀態與凍結控制請求至 Wixtar 會員平台 (PUT /v1/public/members/points/status)。支援三種動作控制(action):
* freeze:點數凍結(預扣點數,需帶 vip_id 或查找鍵、points 等)
* commit:確認扣點(結帳成功正式扣點,需帶 freeze_id、source_id 等)
* release:釋放凍結(取消結帳釋放凍結,需帶 freeze_id)
Resource
PUT /v1/member/wixtar/points/status
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。
Request Headers
認證模式二擇一:若提供
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 格式,所有 action 必填) |
| action | string | 操作類型:freeze (凍結), commit (確認扣點), release (釋放凍結) |
| freeze_id | string | 凍結單號 (長度 1..40,所有 action 必填) |
| vip_id | string | (optional/條件必填) 會員編號 (action=freeze 時必填) |
| source_id | string | (optional/條件必填) 來源單號 / 銷貨單號 (action=freeze 與 commit 時必填) |
| points | integer | (optional/條件必填) 凍結點數 (action=freeze 時必填,正整數 > 0) |
| point_type | string | (optional/條件必填) 扣點類型代碼 (action=commit 時必填,例如 3=兌換扣點、7=活動扣點、A=人工扣點) |
| amount | number | (optional) 關聯交易金額 (數值 ≥ 0) |
| expire_minutes | integer | (optional) 凍結時效 (分鐘,預設 5 分鐘) |
| memo | string | (optional) 備註說明 |
| brand_id | string | (optional) 品牌編號 (未帶時自動取 token_brand_id 或集團範圍) |
Request Example
1. 凍結點數 (action=freeze)
{
"request_id": "550e8400-e29b-41d4-a716-446655440003",
"action": "freeze",
"vip_id": "CM00000001",
"points": 200,
"freeze_id": "FRZ202606040001",
"source_id": "POS20260604001",
"brand_id": "24436074"
}
2. 確認扣點 (action=commit)
{
"request_id": "550e8400-e29b-41d4-a716-446655440004",
"action": "commit",
"freeze_id": "FRZ202606040001",
"source_id": "POS20260604001"
}
3. 釋放凍結 (action=release)
{
"request_id": "550e8400-e29b-41d4-a716-446655440005",
"action": "release",
"freeze_id": "FRZ202606040001"
}
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 |
|---|---|---|
| freeze_id | string | 凍結單號 |
| status | string | 凍結狀態:F=凍結中;C=已確認扣點;R=已釋放;E=已逾期 |
| remaining_total_points | integer | 異動後可用點數(已扣除 active freeze) |
| freeze_end_at | string | 點數凍結預計失效時間 (格式: YYYY-MM-DD HH:mm:ss) |
Response Example - Http Code = 200
{
"status": 200,
"code": "000000",
"message": "Success",
"data": {
"freeze_id": "FRZ202606040001",
"status": "F",
"remaining_total_points": 300,
"freeze_end_at": "2026-06-04 10:30:00"
}
}
Response Example 錯誤回應 - 400 Pydantic參數驗證(必填欄位缺漏)
{
"status": 200,
"code": "400",
"message": "缺少必填欄位:action(欄位代號:action);缺少必填欄位:request_id(欄位代號:request_id);缺少必填欄位:freeze_id(欄位代號:freeze_id)",
"data": {
"errors_zh": [
"缺少必填欄位:action(欄位代號:action)",
"缺少必填欄位:request_id(欄位代號:request_id)",
"缺少必填欄位:freeze_id(欄位代號:freeze_id)"
],
"errors": [
{
"type": "missing",
"loc": [
"body",
"action"
],
"msg": "Field required",
"input": {}
},
{
"type": "missing",
"loc": [
"body",
"request_id"
],
"msg": "Field required",
"input": {}
},
{
"type": "missing",
"loc": [
"body",
"freeze_id"
],
"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 錯誤回應 - 400 action不合法
{
"status": 200,
"code": "400",
"message": "action 不合法,合法值為:freeze、commit、release"
}
Response Example 錯誤回應 - 400 brand_id無法確定
{
"status": 200,
"code": "400",
"message": "brand_id 未提供且 Token 無品牌歸屬,無法確定操作品牌"
}
Response Example 錯誤回應 - 400 freeze必填欄位缺失
{
"status": 200,
"code": "400",
"message": "freeze action 必填欄位缺失:vip_id, freeze_id, source_id, points"
}
Response Example 錯誤回應 - 400 commit必填欄位缺失
{
"status": 200,
"code": "400",
"message": "commit action 必填欄位缺失:freeze_id, source_id, point_type"
}
Response Example 錯誤回應 - 400 release必填欄位缺失
{
"status": 200,
"code": "400",
"message": "release action 必填欄位缺失:freeze_id"
}
Response Example 錯誤回應 - 403 無此凍結單品牌操作權限
{
"status": 200,
"code": "403",
"message": "無 24436074 品牌操作權限,不允許操作此凍結單"
}
Response Example 錯誤回應 - 404 查無對應會員
{
"status": 200,
"code": "404",
"message": "查無對應會員"
}
Response Example 錯誤回應 - 500 查詢凍結狀態失敗
{
"status": 200,
"code": "500",
"message": "查詢凍結狀態失敗"
}
Response Example 錯誤回應 - 400 點數凍結業務錯誤(動態訊息)
{
"status": 200,
"code": "400",
"message": "點數不足,無法凍結"
}
Response Example 錯誤回應 - 500 點數凍結操作失敗
{
"status": 200,
"code": "500",
"message": "點數凍結操作失敗"
}