712 lines
21 KiB
Markdown
712 lines
21 KiB
Markdown
# playX 接口文档(按调用方向拆分)
|
||
|
||
说明:本文档严格依据当前代码 `app/api/controller/v1/Playx.php`、`app/api/controller/v1/Auth.php`(临时登录)、`config/playx.php` 与定时任务 `app/process/PlayxJobs.php` 整理。
|
||
|
||
按调用方向分为三类(避免与历史章节标题混淆):
|
||
|
||
| 方向 | 含义 | 本文位置 |
|
||
|------|------|----------|
|
||
| **playX → 积分商城** | playX(或上游批处理)**主动 HTTP 调用商城**开放接口 | **§1**(如 Daily Push) |
|
||
| **积分商城 → playX** | 商城 Worker / 后台 **主动 HTTP 调用 playX / Cash Market** 提供的接口 | **不展开于本文**;交付 playX 的说明见 **`docs/playX-接口待完善清单.md`** |
|
||
| **积分商城 → H5** | H5 / 内嵌页 **调用商城** 的会员与积分业务接口 | **§3** |
|
||
|
||
---
|
||
|
||
## 1. playX → 积分商城(外部系统调用商城开放接口)
|
||
|
||
### 1.1 Daily Push API
|
||
* 方法:`POST`
|
||
* 路径:`/api/v1/mall/dailyPush`
|
||
|
||
#### Header(多语言,可选)
|
||
- `lang`: `zh`/`zh-cn` 返回中文(默认);`en` 返回英文
|
||
|
||
#### Header(签名校验:HMAC 必填)
|
||
当 `playX.daily_push_secret` 配置非空时,需要携带(HMAC):
|
||
- `X-Request-Id`:请求 ID
|
||
- `X-Timestamp`:时间戳
|
||
- `X-Signature`:签名(HMAC_SHA256)
|
||
|
||
服务端签名计算:
|
||
- `canonical = X-Timestamp + "\n" + X-Request-Id + "\nPOST\n/api/v1/mall/dailyPush\n" + sha256(json_body)`
|
||
- `expected = hash_hmac('sha256', canonical, daily_push_secret)`
|
||
- 校验:`hash_equals(expected, X-Signature)`
|
||
|
||
说明:
|
||
- 本项目对接方案为 **仅启用 HMAC**,不使用 `Authorization` 头做校验。
|
||
|
||
#### Body
|
||
| 字段 | 类型 | 必填 | 说明 |
|
||
|------|------|------|------|
|
||
| `request_id` | string | 是 | 外部推送请求号(原样返回) |
|
||
| `date` | string(YYYY-MM-DD) | 是 | 业务日期(入库到 `mall_daily_push.date`) |
|
||
| `user_id` | string | 是 | playX 用户 ID(用于幂等;入库 `mall_daily_push.user_id` 等;服务端会按 `user_id`/`username` **确保存在** `mall_user_asset` 资产行) |
|
||
| `username` | string | 否 | 展示冗余(同步到商城用户侧逻辑时使用) |
|
||
| `yesterday_win_loss_net` | number | 否 | 昨日净输赢(仅当 `< 0` 时计算新增保障金) |
|
||
| `yesterday_total_deposit` | number | 否 | 昨日总充值(用于计算今日可领取上限) |
|
||
| `lifetime_total_deposit` | number | 否 | 历史总充值 |
|
||
| `lifetime_total_withdraw` | number | 否 | 历史总提现 |
|
||
|
||
##### 格式 B:新版批量上报(兼容你截图)
|
||
新版 body 形如:
|
||
```json
|
||
{
|
||
"report_date": "1700000000",
|
||
"member": [
|
||
{
|
||
"member_id": "123456",
|
||
"login": "john",
|
||
"lty_deposit": 15230.75,
|
||
"lty_withdrawal": 12400.50,
|
||
"yesterday_total_w": -320.25,
|
||
"yesterday_total_deposit": 500.00
|
||
}
|
||
]
|
||
}
|
||
```
|
||
|
||
字段映射(服务端内部会转换成旧字段再计算):
|
||
- `report_date` -> `date`(若为 Unix 秒则转为 `YYYY-MM-DD`)
|
||
- `member[].member_id` -> `user_id`
|
||
- `member[].login` -> `username`
|
||
- `member[].yesterday_total_w` -> `yesterday_win_loss_net`
|
||
- `member[].yesterday_total_deposit` -> `yesterday_total_deposit`
|
||
- `member[].lty_deposit` -> `lifetime_total_deposit`
|
||
- `member[].lty_withdrawal` -> `lifetime_total_withdraw`
|
||
|
||
返回补充:
|
||
- 批量模式会在 `data` 里增加 `results[]`,每个成员一条结果(是否 `deduped`)。
|
||
|
||
#### 幂等规则
|
||
* 幂等键:`user_id + date`
|
||
* 重复推送:不会重复入账,返回 `data.deduped=true`
|
||
|
||
#### 返回(Response)
|
||
外层通用返回结构:`{ code, msg, time, data }`
|
||
|
||
成功(首次入库):
|
||
| 字段 | 类型 | 说明 |
|
||
|------|------|------|
|
||
| `data.request_id` | string | 原样返回 |
|
||
| `data.accepted` | boolean | `true` |
|
||
| `data.deduped` | boolean | `false` |
|
||
| `data.message` | string | `ok` |
|
||
|
||
成功(重复推送):
|
||
| 字段 | 类型 | 说明 |
|
||
|------|------|------|
|
||
| `data.request_id` | string | 原样返回 |
|
||
| `data.accepted` | boolean | `true` |
|
||
| `data.deduped` | boolean | `true` |
|
||
| `data.message` | string | `duplicate input` |
|
||
|
||
失败:
|
||
* 当缺少必填字段:code=0,msg 为缺少字段错误
|
||
* 当签名不正确:HTTP 401,code=0,msg 为 `INVALID_SIGNATURE`
|
||
|
||
#### 示例(未开启签名校验)
|
||
请求:
|
||
```bash
|
||
curl -X POST 'http://localhost:1818/api/v1/mall/dailyPush' \
|
||
-H 'Content-Type: application/json' \
|
||
-d '{
|
||
"request_id":"req_1001",
|
||
"date":"2026-03-18",
|
||
"user_id":"U123",
|
||
"username":"demo_user",
|
||
"yesterday_win_loss_net":-120.5,
|
||
"yesterday_total_deposit":50,
|
||
"lifetime_total_deposit":5000,
|
||
"lifetime_total_withdraw":2000
|
||
}'
|
||
```
|
||
|
||
响应(首次):
|
||
```json
|
||
{
|
||
"code": 1,
|
||
"msg": "",
|
||
"data": {
|
||
"request_id": "req_1001",
|
||
"accepted": true,
|
||
"deduped": false,
|
||
"message": "ok"
|
||
},
|
||
"time": 0
|
||
}
|
||
```
|
||
|
||
#### 示例(新版批量上报)
|
||
请求:
|
||
```bash
|
||
curl -X POST 'http://localhost:1818/api/v1/mall/dailyPush' \
|
||
-H 'Content-Type: application/json' \
|
||
-d '{
|
||
"report_date": "1700000000",
|
||
"member": [
|
||
{
|
||
"member_id": "123456",
|
||
"login": "john",
|
||
"lty_deposit": 15230.75,
|
||
"lty_withdrawal": 12400.50,
|
||
"yesterday_total_w": -320.25,
|
||
"yesterday_total_deposit": 500.00
|
||
}
|
||
]
|
||
}'
|
||
```
|
||
|
||
返回(首次写入至少一个成员时的示例):
|
||
```json
|
||
{
|
||
"code": 1,
|
||
"msg": "",
|
||
"time": 0,
|
||
"data": {
|
||
"request_id": "report_2023-11-14",
|
||
"accepted": true,
|
||
"deduped": false,
|
||
"message": "Ok",
|
||
"results": [
|
||
{
|
||
"user_id": "123456",
|
||
"accepted": true,
|
||
"deduped": false,
|
||
"message": "Ok"
|
||
}
|
||
]
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 2. 积分商城 → playX(贵方需提供的 HTTP 接口)
|
||
|
||
商城在验 Token、红利发放、交易轮询、Angpow 导入等场景会 **主动请求 playX / Cash Market**。
|
||
**完整 URL、请求/响应字段、成功判定、与 Angpush 双路径关系、联调待办** 已单独整理,便于 **直接转发给 playX 平台**:
|
||
|
||
- **`docs/playX-接口待完善清单.md`**
|
||
|
||
本文 **§1** 仅描述「谁调用商城」;**§3** 描述「H5 调用商城」。
|
||
|
||
---
|
||
|
||
## 3. 积分商城 → H5(服务端提供给 H5 的接口)
|
||
|
||
### 3.0 数据模型说明(与代码一致)
|
||
|
||
* **积分商城用户资产主表**:`mall_user_asset`(账号、积分、`playx_user_id` 等;H5 临时登录 `temLogin` 直接创建/复用该表行,**不依赖**独立会员 `user` 表)。
|
||
* **会话缓存**:`mall_session`(字段含 `session_id`、`user_id`(此处存 **playX 侧用户标识字符串**,与 `mall_user_asset.playx_user_id` 一致)、`expire_time` 等)。
|
||
* **统一订单**:`mall_order`(红利/实物/提现订单;`user_id` 字段为 **`playx_user_id` 字符串**)。
|
||
* **对外业务 ID**:订单与推送中的 `user_id` 多为 **playX 用户 ID**(`playx_user_id`)。临时登录场景下,资产表会生成占位 ID,形如 **`mall_{mall_user_asset.id}`**(见 `MallUserAsset::ensureForUsername`)。
|
||
|
||
### 3.1 鉴权解析规则(`resolvePlayxAssetIdFromRequest`)
|
||
|
||
以下接口在服务端最终都会解析出 **`mall_user_asset.id`(整型,资产表主键)**,再按该 ID 加载资产与关联数据。
|
||
|
||
优先级(由高到低):
|
||
|
||
1. **`session_id`**(`post` 优先,`get` 兼容)
|
||
* 在 `mall_session` 中存在且未过期:用会话里的 `user_id`(`playx_user_id` 字符串)在 `mall_user_asset` 按 `playx_user_id` 查找,得到资产主键。
|
||
* 若会话无效:兼容把 `session_id` 参数误当作 **商城 token** 再试一次(UUID 形态 token)。
|
||
2. **`token`**(`post` / `get` 或请求头 **`ba-token`** / **`token`**)
|
||
* 校验 `token` 表:类型为会员 `user` 或商城临时 **`muser`**。未过期时,`user_id` 字段为 **`mall_user_asset.id`**(`muser`)或会员体系约定 ID(`user`)。
|
||
3. **`user_id`**(`post` / `get` 兼容)
|
||
* **纯数字**:视为 **`mall_user_asset.id`**。
|
||
* **非纯数字**:视为 **`playx_user_id`**,在 `mall_user_asset` 按该字段查找主键。
|
||
|
||
> 注意:请求参数的取值方式是 `post()` 优先,`get()` 兼容(即同字段既可传 post 也可传 get)。
|
||
|
||
---
|
||
|
||
### 3.2 临时登录(获取商城 token)
|
||
|
||
* 方法:`GET`(推荐)或 `POST`
|
||
* 路径:`/api/v1/temLogin`
|
||
* 开关:`config/buildadmin.php` → `agent_auth.temp_login_enable` 为 `true`;有效期 `agent_auth.temp_login_expire`(秒)。
|
||
|
||
#### 请求参数
|
||
|
||
| 字段 | 类型 | 必填 | 说明 |
|
||
|------|------|------|------|
|
||
| `username` | string | 是 | 登录名(唯一);不存在则自动创建 `mall_user_asset` 行 |
|
||
|
||
#### 行为说明
|
||
|
||
* 若用户名不存在:`MallUserAsset::ensureForUsername` 创建资产行(随机密码等),并将 `playx_user_id` 更新为 **`mall_{id}`** 形式(与真实 playX ID 区分)。
|
||
* 签发 **商城 token**(类型 **`muser`**,`token` 表内 `user_id` = **`mall_user_asset.id`**),并签发 `muser-refresh` 刷新令牌。
|
||
|
||
#### 返回(成功 data.userInfo)
|
||
|
||
| 字段 | 类型 | 说明 |
|
||
|------|------|------|
|
||
| `id` | int | **`mall_user_asset.id`** |
|
||
| `username` | string | 用户名 |
|
||
| `nickname` | string | 同 `username` |
|
||
| `playx_user_id` | string | 资产表中的 `playx_user_id`(如 `mall_12`) |
|
||
| `token` | string | 访问 H5 接口时携带 |
|
||
| `refresh_token` | string | 调用 `/api/common/refreshToken` 时使用(类型 `muser-refresh`) |
|
||
| `expires_in` | int | token 有效秒数 |
|
||
|
||
#### 示例
|
||
|
||
```bash
|
||
curl -G 'http://localhost:1818/api/v1/temLogin' --data-urlencode 'username=demo_h5'
|
||
```
|
||
|
||
用户名含 `+` 等号时需 URL 编码(如 `%2B60123456789`)。
|
||
|
||
---
|
||
|
||
### 3.3 Token 验证(换 session)
|
||
|
||
* 方法:`POST`(推荐 `GET` 传 `token` 亦可)
|
||
* 路径:`/api/v1/mall/verifyToken`
|
||
|
||
#### 配置:本地验证 vs 远程 playX
|
||
|
||
* 配置项:`config/playx.php` → **`verify_token_local_only`**(环境变量 **`PLAYX_VERIFY_TOKEN_LOCAL_ONLY`**,未设置时默认为 **`1` / 开启本地验证)。
|
||
* **`verify_token_local_only = true`(默认)**
|
||
* **不请求** playX HTTP。
|
||
* 仅接受商城临时登录 token(类型 **`muser`**),校验 `token` 表后写入 **`mall_session`**。
|
||
* 返回的 `data.user_id` 为 **`playx_user_id`**(与资产表一致)。
|
||
* **`verify_token_local_only = false`**(生产对接 playX)
|
||
* 需配置 **`playX.api.base_url`**,由商城向 playX 发起 `POST` 校验(请求/响应约定见 **`docs/playX-接口待完善清单.md`** 第一部分 §1)。
|
||
* 若未配置 `base_url`,返回 `playX API not configured`。
|
||
|
||
#### 请求参数
|
||
|
||
必填其一:
|
||
|
||
* `token`(Body 优先;`session` 兼容字段;Query 也可传 `token`)
|
||
|
||
#### 返回(成功 data)
|
||
|
||
| 字段 | 类型 | 说明 |
|
||
|------|------|------|
|
||
| `session_id` | string | 写入 `mall_session` |
|
||
| `user_id` | string | playX 用户 ID(即 `playx_user_id`,会话内与订单/推送一致) |
|
||
| `username` | string | 用户名 |
|
||
| `token_expire_at` | string | ISO 字符串(服务端 `date('c', expireAt)`) |
|
||
|
||
失败:
|
||
|
||
* token 为空:HTTP 401,msg=`INVALID_TOKEN`
|
||
* 远程模式且 playX 未配置:`msg=playX API not configured`
|
||
|
||
#### 示例(本地验证)
|
||
|
||
```bash
|
||
curl -X POST 'http://localhost:1818/api/v1/mall/verifyToken' \
|
||
-H 'Content-Type: application/x-www-form-urlencoded' \
|
||
--data-urlencode 'token=上一步TemLogin返回的token'
|
||
```
|
||
|
||
---
|
||
|
||
### 3.x 收货地址(`mall_address`)
|
||
|
||
> 下面接口用于 H5 维护收货地址。鉴权同本章其他接口:携带 `session_id` 或 `token` 或 `user_id`。
|
||
|
||
#### 3.x.1 地址列表
|
||
* 方法:`GET`
|
||
* 路径:`/api/v1/mall/addressList`
|
||
|
||
返回:`data.list` 为地址数组。
|
||
|
||
#### 3.x.2 添加地址
|
||
* 方法:`POST`
|
||
* 路径:`/api/v1/mall/addressAdd`
|
||
|
||
Body:
|
||
| 字段 | 必填 | 说明 |
|
||
|------|------|------|
|
||
| `receiver_name` | 是 | 收货人 |
|
||
| `phone` | 是 | 电话 |
|
||
| `region` | 是 | 地区(数组或逗号分隔字符串) |
|
||
| `detail_address` | 是 | 详细地址 |
|
||
| `default_setting` | 否 | `1` 设为默认地址 |
|
||
|
||
#### 3.x.3 修改地址(含设为默认)
|
||
* 方法:`POST`
|
||
* 路径:`/api/v1/mall/addressEdit`
|
||
|
||
Body:`id` 必填,其余字段按需传入更新。
|
||
|
||
#### 3.x.4 删除地址
|
||
* 方法:`POST`
|
||
* 路径:`/api/v1/mall/addressDelete`
|
||
|
||
Body:`id` 必填。若删除默认地址,服务端会自动挑选一条剩余地址设为默认(如存在)。
|
||
|
||
---
|
||
|
||
### 3.4 用户资产(Assets)
|
||
* 方法:`GET`
|
||
* 路径:`/api/v1/mall/assets`
|
||
|
||
#### 请求参数(鉴权)
|
||
|
||
以下任选其一即可(与 **3.1 鉴权解析规则** 一致):
|
||
|
||
* `session_id`
|
||
* `token`(或请求头 `ba-token` / `token`)
|
||
* `user_id`(纯数字为 **`mall_user_asset.id`**,否则为 **`playx_user_id`**)
|
||
|
||
#### 返回(成功 data)
|
||
若未找到资产:返回 0。
|
||
| 字段 | 类型 | 说明 |
|
||
|------|------|------|
|
||
| `locked_points` | int | 待领取积分 |
|
||
| `available_points` | int | 可用积分 |
|
||
| `today_limit` | int | 今日可领取上限 |
|
||
| `today_claimed` | int | 今日已领取 |
|
||
| `withdrawable_cash` | number(2) | `available_points * points_to_cash_ratio`(保留 2 位) |
|
||
|
||
#### 示例
|
||
```bash
|
||
curl -G 'http://localhost:1818/api/v1/mall/assets' --data-urlencode 'token=上一步temLogin返回的token'
|
||
```
|
||
|
||
响应(示例):
|
||
```json
|
||
{
|
||
"code": 1,
|
||
"msg": "",
|
||
"time": 1712345678,
|
||
"data": {
|
||
"locked_points": 100,
|
||
"available_points": 50,
|
||
"today_limit": 200,
|
||
"today_claimed": 80,
|
||
"withdrawable_cash": 5.2
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### 3.5 领取(Claim)
|
||
* 方法:`POST`
|
||
* 路径:`/api/v1/mall/claim`
|
||
|
||
#### 请求 Body
|
||
必填:
|
||
|
||
* `claim_request_id`:幂等键(string,唯一)
|
||
|
||
鉴权:同 **3.1**(`session_id` / `token` / `user_id`)
|
||
|
||
#### 返回(成功 data)
|
||
与 `用户资产` 返回字段一致(资产快照)。
|
||
|
||
幂等:
|
||
* `claim_request_id` 已存在:不会重复入账,直接返回当前资产快照
|
||
|
||
#### 示例
|
||
```bash
|
||
curl -X POST 'http://localhost:1818/api/v1/mall/claim' \
|
||
-H 'Content-Type: application/x-www-form-urlencoded' \
|
||
--data-urlencode 'claim_request_id=claim_001' \
|
||
--data-urlencode 'token=上一步temLogin返回的token'
|
||
```
|
||
|
||
响应(首次领取,示例):
|
||
```json
|
||
{
|
||
"code": 1,
|
||
"msg": "Claim success",
|
||
"time": 1712345679,
|
||
"data": {
|
||
"locked_points": 60,
|
||
"available_points": 90,
|
||
"today_limit": 200,
|
||
"today_claimed": 120,
|
||
"withdrawable_cash": 9.0
|
||
}
|
||
}
|
||
```
|
||
|
||
响应(幂等重复,示例:可能 msg 为空):
|
||
```json
|
||
{
|
||
"code": 1,
|
||
"msg": "",
|
||
"time": 1712345680,
|
||
"data": {
|
||
"locked_points": 60,
|
||
"available_points": 90,
|
||
"today_limit": 200,
|
||
"today_claimed": 120,
|
||
"withdrawable_cash": 9.0
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### 3.6 商品列表
|
||
* 方法:`GET`
|
||
* 路径:`/api/v1/mall/items`
|
||
|
||
#### 请求参数
|
||
* `type`(可选):`BONUS` | `PHYSICAL` | `WITHDRAW`
|
||
|
||
不传或空:返回 `mall_item.status=1` 且不过滤 type 的商品列表。
|
||
|
||
#### 返回(成功 data)
|
||
* `list`:商品列表(直接返回 `MallItem` 的字段数组;包含扩展字段:`amount/multiplier/category/category_title` 等)
|
||
|
||
#### 示例
|
||
请求:
|
||
```bash
|
||
curl -G 'http://localhost:1818/api/v1/mall/items' --data-urlencode 'type=WITHDRAW'
|
||
```
|
||
|
||
响应(示例):
|
||
```json
|
||
{
|
||
"code": 1,
|
||
"msg": "",
|
||
"time": 1712345685,
|
||
"data": {
|
||
"list": [
|
||
{
|
||
"id": 321,
|
||
"title": "提现档位A",
|
||
"type": 3,
|
||
"score": 1000,
|
||
"amount": 100.0,
|
||
"multiplier": 1,
|
||
"category": "withdraw",
|
||
"category_title": "提现"
|
||
}
|
||
]
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### 3.7 红利兑换(Bonus Redeem)
|
||
* 方法:`POST`
|
||
* 路径:`/api/v1/mall/bonusRedeem`
|
||
|
||
#### 请求 Body
|
||
必填:
|
||
* `item_id`:商品 ID(要求 `mall_item.type=BONUS` 且 `status=1`)
|
||
鉴权:同 **3.1**(`session_id` / `token` / `user_id`)
|
||
|
||
#### 返回(成功)
|
||
* `msg`:`Redeem submitted, please wait about 10 minutes`
|
||
* `data.order_id`:订单 ID
|
||
* `data.status`:`PENDING`
|
||
|
||
#### 示例
|
||
```bash
|
||
curl -X POST 'http://localhost:1818/api/v1/mall/bonusRedeem' \
|
||
-H 'Content-Type: application/x-www-form-urlencoded' \
|
||
--data-urlencode 'item_id=123' \
|
||
--data-urlencode 'session_id=7b1c....'
|
||
```
|
||
|
||
响应(示例):
|
||
```json
|
||
{
|
||
"code": 1,
|
||
"msg": "Redeem submitted, please wait about 10 minutes",
|
||
"time": 1712345686,
|
||
"data": {
|
||
"order_id": 456,
|
||
"status": "PENDING"
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### 3.8 实物兑换(Physical Redeem)
|
||
* 方法:`POST`
|
||
* 路径:`/api/v1/mall/physicalRedeem`
|
||
|
||
#### 请求 Body
|
||
必填:
|
||
* `item_id`:商品 ID(要求 `mall_item.type=PHYSICAL` 且 `status=1`)
|
||
* `address_id`:收货地址 ID(`mall_address.id`,须属于当前用户资产;下单时写入 `mall_order.mall_address_id`,并将该地址快照写入 `receiver_name` / `receiver_phone` / `receiver_address`)
|
||
鉴权:同 **3.1**(`session_id` / `token` / `user_id`)
|
||
|
||
#### 返回(成功)
|
||
* `msg`:`Redeem success`
|
||
* `data`:`null`
|
||
|
||
#### 示例
|
||
```bash
|
||
curl -X POST 'http://localhost:1818/api/v1/mall/physicalRedeem' \
|
||
-H 'Content-Type: application/x-www-form-urlencoded' \
|
||
--data-urlencode 'item_id=200' \
|
||
--data-urlencode 'address_id=10' \
|
||
--data-urlencode 'session_id=7b1c....'
|
||
```
|
||
|
||
响应(示例):
|
||
```json
|
||
{
|
||
"code": 1,
|
||
"msg": "Redeem success",
|
||
"time": 1712345687,
|
||
"data": null
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### 3.9 提现申请(Withdraw Apply)
|
||
* 方法:`POST`
|
||
* 路径:`/api/v1/mall/withdrawApply`
|
||
|
||
#### 请求 Body
|
||
必填:
|
||
* `item_id`:商品 ID(要求 `mall_item.type=WITHDRAW` 且 `status=1`)
|
||
鉴权:同 **3.1**(`session_id` / `token` / `user_id`)
|
||
|
||
#### 返回(成功)
|
||
* `msg`:`Withdraw submitted, please wait about 10 minutes`
|
||
* `data.order_id`:订单 ID
|
||
* `data.status`:`PENDING`
|
||
|
||
#### 示例
|
||
```bash
|
||
curl -X POST 'http://localhost:1818/api/v1/mall/withdrawApply' \
|
||
-H 'Content-Type: application/x-www-form-urlencoded' \
|
||
--data-urlencode 'item_id=321' \
|
||
--data-urlencode 'session_id=7b1c....'
|
||
```
|
||
|
||
响应(示例):
|
||
```json
|
||
{
|
||
"code": 1,
|
||
"msg": "Withdraw submitted, please wait about 10 minutes",
|
||
"time": 1712345688,
|
||
"data": {
|
||
"order_id": 789,
|
||
"status": "PENDING"
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### 3.10 订单列表
|
||
* 方法:`GET`
|
||
* 路径:`/api/v1/mall/orders`
|
||
|
||
#### 请求参数(鉴权)
|
||
|
||
同 **3.1**(`session_id` / `token` / `user_id`)。
|
||
|
||
#### 返回(成功 data)
|
||
|
||
* `list`:订单列表(最多 100 条),并包含关联的 `mallItem`(关系对象)
|
||
* 列表项中的 `user_id` 为 **playX 侧 `playx_user_id`**(字符串),与 `mall_order.user_id` 一致
|
||
|
||
#### 示例
|
||
请求:
|
||
```bash
|
||
curl -G 'http://localhost:1818/api/v1/mall/orders' --data-urlencode 'token=上一步temLogin返回的token'
|
||
```
|
||
|
||
响应(示例,简化):
|
||
```json
|
||
{
|
||
"code": 1,
|
||
"msg": "",
|
||
"time": 1712345689,
|
||
"data": {
|
||
"list": [
|
||
{
|
||
"id": 456,
|
||
"user_id": "U123",
|
||
"type": "BONUS",
|
||
"status": "PENDING",
|
||
"mall_item_id": 123,
|
||
"points_cost": 100,
|
||
"amount": 10.0,
|
||
"external_transaction_id": "BONUS_ORD2026....",
|
||
"grant_status": "NOT_SENT",
|
||
"mallItem": {
|
||
"id": 123,
|
||
"title": "每日红利",
|
||
"type": 1
|
||
}
|
||
}
|
||
]
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### 3.11 积分流水(Points Logs)
|
||
* 方法:`GET`
|
||
* 路径:`/api/v1/mall/pointsLogs`
|
||
|
||
#### 请求参数(鉴权)
|
||
同 **3.1**(`session_id` / `token` / `user_id`)。
|
||
|
||
#### Query 参数
|
||
| 字段 | 类型 | 必填 | 说明 |
|
||
|------|------|------|------|
|
||
| `limit` | int | 否 | 每页条数,默认 20,最大 100 |
|
||
| `cursor` | string | 否 | 游标(上一页返回 `next_cursor`) |
|
||
| `direction` | string | 否 | `IN` 仅入账 / `OUT` 仅扣减;不传返回全部 |
|
||
|
||
#### 返回(成功 data)
|
||
| 字段 | 类型 | 说明 |
|
||
|------|------|------|
|
||
| `data.list` | array | 流水数组(时间倒序) |
|
||
| `data.next_cursor` | string\|null | 下一页游标(本页最后一条记录的游标) |
|
||
|
||
`list` 每一项字段:
|
||
| 字段 | 类型 | 说明 |
|
||
|------|------|------|
|
||
| `biz_type` | string | `CLAIM`/`REDEEM_BONUS`/`REDEEM_PHYSICAL`/`REDEEM_WITHDRAW`/`REFUND` |
|
||
| `direction` | string | `IN`/`OUT` |
|
||
| `points` | int | 积分变动值(正数,方向由 `direction` 表示) |
|
||
| `ts` | int | Unix 秒 |
|
||
| `ref_id` | string | 领取为 `claim_request_id`;订单为 `external_transaction_id` |
|
||
| `order_no` | string | 订单号(非订单类为空) |
|
||
| `order_status` | string | 订单状态(非订单类为空) |
|
||
| `mallItem` | object\|null | 商品信息(非订单类为 null) |
|
||
| `item_id` | int | 兼容字段:商品ID(非订单类为 0) |
|
||
| `item_title` | string | 兼容字段:商品标题(非订单类为空) |
|
||
| `item_type` | int | 兼容字段:商品类型(非订单类为 0;`1=BONUS 2=PHYSICAL 3=WITHDRAW`) |
|
||
| `item_score` | int | 兼容字段:商品所需积分(非订单类为 0) |
|
||
| `cursor` | string | 当前记录游标 |
|
||
|
||
`mallItem` 字段(非隐私):
|
||
| 字段 | 类型 | 说明 |
|
||
|------|------|------|
|
||
| `id` | int | `mall_item.id` |
|
||
| `title` | string | 商品名 |
|
||
| `type` | int | 商品类型 |
|
||
| `score` | int | 所需积分 |
|
||
| `amount` | number | 现金面值 |
|
||
| `multiplier` | int | 流水倍数 |
|
||
| `category` | string | 红利业务类别 |
|
||
| `category_title` | string | 类别展示名 |
|
||
|
||
#### 示例
|
||
```bash
|
||
curl -G 'http://localhost:1818/api/v1/mall/pointsLogs' \
|
||
--data-urlencode 'token=上一步temLogin返回的token' \
|
||
--data-urlencode 'limit=20'
|
||
```
|
||
|
||
---
|
||
|
||
### 3.12 同步额度(可选)
|
||
当前代码未实现并未注册路由:`/api/v1/mall/syncLimit`。
|
||
|