Files
webman-buildadmin-mall/docs/PlayX-接口文档.md
2026-03-20 18:11:00 +08:00

15 KiB
Raw Blame History

PlayX 接口文档(按调用方向拆分)

说明:本文档严格依据当前代码 app/api/controller/v1/Playx.php 与定时任务 app/process/PlayxJobs.php 整理。

三类接口分别为:

  • 积分商城 -> PlayXPlayX 调用商城)
  • PlayX -> 积分商城(商城调用 PlayX
  • 积分商城 -> H5H5 调用商城)

1. 积分商城 -> PlayXPlayX 调用商城)

1.1 Daily Push API

  • 方法:POST
  • 路径:/api/v1/playx/daily-push

Header签名校验可选

playx.daily_push_secret 配置非空时,需要携带:

  • X-Request-Id:请求 ID
  • X-Timestamp:时间戳
  • X-Signature签名HMAC_SHA256

服务端签名计算:

  • canonical = X-Timestamp + "\n" + X-Request-Id + "\nPOST\n/api/v1/playx/daily-push\n" + sha256(json_body)
  • expected = hash_hmac('sha256', canonical, daily_push_secret)
  • 校验:hash_equals(expected, X-Signature)

Body

字段 类型 必填 说明
request_id string 外部推送请求号(原样返回)
date string(YYYY-MM-DD) 业务日期(入库到 mall_playx_daily_push.date
user_id string PlayX 用户 ID用于幂等
username string 展示冗余
yesterday_win_loss_net number 昨日净输赢(仅当 < 0 时计算新增保障金)
yesterday_total_deposit number 昨日总充值(用于计算今日可领取上限)
lifetime_total_deposit number 历史总充值
lifetime_total_withdraw number 历史总提现

幂等规则

  • 幂等键: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=0msg 为缺少字段错误
  • 当签名不正确HTTP 401code=0msg 为 INVALID_SIGNATURE

示例(未开启签名校验)

请求:

curl -X POST 'http://localhost:1818/api/v1/playx/daily-push' \
  -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
  }'

响应(首次):

{
  "code": 1,
  "msg": "",
  "data": {
    "request_id": "req_1001",
    "accepted": true,
    "deduped": false,
    "message": "ok"
  },
  "time": 0
}

2. PlayX -> 积分商城(商城调用 PlayX

下面这些接口由 PlayX 提供。商城侧仅按“请求参数 + 期望返回判定条件”发起调用与处理结果。

2.1 Token Verification API

  • 方法:POST
  • URL${playx.api.base_url}${playx.api.token_verify_url}
    • 默认:/api/v1/auth/verify-token

请求 Body商城侧发送

字段 类型 必填 说明
request_id string 形如 mall_{uniqid}
token string 前端传入的 PlayX token

返回(期望)

商城侧校验:

  • HTTP 状态码必须为 200
  • 且响应体中必须包含 user_id

期望字段(示例):

字段 类型 说明
user_id string 必选
username string 可选
token_expire_at string 可选(能被 strtotime 解析)

示例(成功):

{
  "user_id": "U123",
  "username": "demo_user",
  "token_expire_at": "2026-04-01T12:00:00Z"
}

示例(失败):

{
  "message": "invalid token"
}

2.2 Bonus Grant API

  • 方法:POST
  • URL${playx.api.base_url}${playx.api.bonus_grant_url}
    • 默认:/api/v1/bonus/grant

请求 Body商城侧发送

字段 类型 必填 说明
request_id string 形如 mall_bonus_{uniqid}
externalTransactionId string MallPlayxOrder.external_transaction_id
user_id string PlayX 用户 ID
amount number MallPlayxOrder.amount
rewardName string mall_item.title
category string mall_item.category(默认 daily
categoryTitle string mall_item.category_title
multiplier int MallPlayxOrder.multiplier

返回(期望)

商城侧判定:

  • HTTP 状态码 200
  • data.status === "accepted"

成功时读取:

  • data.playx_transaction_id

失败时读取:

  • data.message 写入订单 fail_reason

示例accepted

{
  "status": "accepted",
  "playx_transaction_id": "PX_TX_001"
}

示例rejected

{
  "status": "rejected",
  "message": "insufficient balance"
}

2.3 Balance Credit API

  • 方法:POST
  • URL${playx.api.base_url}${playx.api.balance_credit_url}
    • 默认:/api/v1/balance/credit

请求 Body商城侧发送

字段 类型 必填 说明
request_id string 形如 mall_withdraw_{uniqid}
externalTransactionId string MallPlayxOrder.external_transaction_id
user_id string PlayX 用户 ID
amount number MallPlayxOrder.amount
multiplier int MallPlayxOrder.multiplier

返回(期望)

与 Bonus Grant 一致:

  • data.status === "accepted" -> 读取 playx_transaction_id
  • 否则 -> 读取 message 写入 fail_reason

示例accepted

{
  "status": "accepted",
  "playx_transaction_id": "PX_TX_002"
}

示例rejected

{
  "status": "rejected",
  "message": "insufficient balance"
}

2.4 Transaction Status Query API交易终态查询

  • 方法:GET
  • URL${playx.api.base_url}${playx.api.transaction_status_url}
    • 默认:/api/v1/transaction/status

Query 参数

字段 类型 必填 说明
externalTransactionId string 订单幂等键 external_transaction_id

返回(期望)

定时任务读取 data.status

  • COMPLETED:商城将订单 status 更新为 COMPLETED
  • FAILEDREJECTED:商城将订单 status=REJECTEDgrant_status=FAILED_FINAL,并退回积分
  • 失败信息取 data.message 写入订单 fail_reason

示例completed

{ "status": "COMPLETED" }

示例failed

{ "status": "FAILED", "message": "grant rejected by PlayX" }

3. 积分商城 -> H5服务端提供给 H5 的接口)

说明:鉴权与用户解析规则由 resolveUserIdFromRequest() 决定。

  • 优先使用 session_id(在 mall_playx_session 查到且未过期)
  • 其次使用 user_id

公共鉴权字段:

  • session_id:字符串
  • user_id:字符串

注意:请求参数的取值方式是 post() 优先,get() 兼容(即同字段既可传 post 也可传 get


3.1 Token 验证

  • 方法:POST
  • 路径:/api/v1/playx/verify-token

请求 Body

必填其一:

  • token(优先读取)
  • session(兼容字段,当 token 为空时会被当作 token

返回(成功 data

字段 类型 说明
session_id string 写入 mall_playx_session
user_id string PlayX 用户 ID
username string 用户名
token_expire_at string ISO 字符串(服务端 date('c', expireAt)

失败:

  • token 为空HTTP 401msg=INVALID_TOKEN
  • PlayX 未配置msg=PlayX API not configured

示例

请求:

curl -X POST 'http://localhost:1818/api/v1/playx/verify-token' \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  --data-urlencode 'token=PLAYX_TOKEN_XXX'

响应(成功示例):

{
  "code": 1,
  "msg": "",
  "data": {
    "session_id": "7b1c....",
    "user_id": "U123",
    "username": "demo_user",
    "token_expire_at": "2026-04-01T12:00:00+00:00"
  }
}

3.2 用户资产

  • 方法:GET
  • 路径:/api/v1/playx/assets

请求参数(鉴权)

  • session_id(优先)
  • 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 位)

示例

curl -G 'http://localhost:1818/api/v1/playx/assets' --data-urlencode 'session_id=7b1c....'

响应(示例):

{
  "code": 1,
  "msg": "",
  "time": 1712345678,
  "data": {
    "locked_points": 100,
    "available_points": 50,
    "today_limit": 200,
    "today_claimed": 80,
    "withdrawable_cash": 5.2
  }
}

3.3 领取Claim

  • 方法:POST
  • 路径:/api/v1/playx/claim

请求 Body

必填:

  • claim_request_id幂等键string唯一 鉴权:
  • session_iduser_id

返回(成功 data

用户资产 返回字段一致(资产快照)。

幂等:

  • claim_request_id 已存在:不会重复入账,直接返回当前资产快照

示例

curl -X POST 'http://localhost:1818/api/v1/playx/claim' \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  --data-urlencode 'claim_request_id=claim_001' \
  --data-urlencode 'session_id=7b1c....'

响应(首次领取,示例):

{
  "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 为空):

{
  "code": 1,
  "msg": "",
  "time": 1712345680,
  "data": {
    "locked_points": 60,
    "available_points": 90,
    "today_limit": 200,
    "today_claimed": 120,
    "withdrawable_cash": 9.0
  }
}

3.4 商品列表

  • 方法:GET
  • 路径:/api/v1/playx/items

请求参数

  • type(可选):BONUS | PHYSICAL | WITHDRAW

不传或空:返回 mall_item.status=1 且不过滤 type 的商品列表。

返回(成功 data

  • list:商品列表(直接返回 MallItem 的字段数组;包含扩展字段:amount/multiplier/category/category_title 等)

示例

请求:

curl -G 'http://localhost:1818/api/v1/playx/items' --data-urlencode 'type=WITHDRAW'

响应(示例):

{
  "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.5 红利兑换Bonus Redeem

  • 方法:POST
  • 路径:/api/v1/playx/bonus/redeem

请求 Body

必填:

  • item_id:商品 ID要求 mall_item.type=BONUSstatus=1 鉴权:
  • session_iduser_id

返回(成功)

  • msgRedeem submitted, please wait about 10 minutes
  • data.order_id:订单 ID
  • data.statusPENDING

示例

curl -X POST 'http://localhost:1818/api/v1/playx/bonus/redeem' \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  --data-urlencode 'item_id=123' \
  --data-urlencode 'session_id=7b1c....'

响应(示例):

{
  "code": 1,
  "msg": "Redeem submitted, please wait about 10 minutes",
  "time": 1712345686,
  "data": {
    "order_id": 456,
    "status": "PENDING"
  }
}

3.6 实物兑换Physical Redeem

  • 方法:POST
  • 路径:/api/v1/playx/physical/redeem

请求 Body

必填:

  • item_id:商品 ID要求 mall_item.type=PHYSICALstatus=1
  • receiver_name:收货人
  • receiver_phone:收货电话
  • receiver_address:收货地址 鉴权:
  • session_iduser_id

返回(成功)

  • msgRedeem success
  • datanull

示例

curl -X POST 'http://localhost:1818/api/v1/playx/physical/redeem' \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  --data-urlencode 'item_id=200' \
  --data-urlencode 'receiver_name=张三' \
  --data-urlencode 'receiver_phone=18800001111' \
  --data-urlencode 'receiver_address=北京市朝阳区XX路XX号' \
  --data-urlencode 'session_id=7b1c....'

响应(示例):

{
  "code": 1,
  "msg": "Redeem success",
  "time": 1712345687,
  "data": null
}

3.7 提现申请Withdraw Apply

  • 方法:POST
  • 路径:/api/v1/playx/withdraw/apply

请求 Body

必填:

  • item_id:商品 ID要求 mall_item.type=WITHDRAWstatus=1 鉴权:
  • session_iduser_id

返回(成功)

  • msgWithdraw submitted, please wait about 10 minutes
  • data.order_id:订单 ID
  • data.statusPENDING

示例

curl -X POST 'http://localhost:1818/api/v1/playx/withdraw/apply' \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  --data-urlencode 'item_id=321' \
  --data-urlencode 'session_id=7b1c....'

响应(示例):

{
  "code": 1,
  "msg": "Withdraw submitted, please wait about 10 minutes",
  "time": 1712345688,
  "data": {
    "order_id": 789,
    "status": "PENDING"
  }
}

3.8 订单列表

  • 方法:GET
  • 路径:/api/v1/playx/orders

请求参数

  • session_iduser_id

返回(成功 data

  • list:订单列表(最多 100 条),并包含关联的 mallItem(关系对象)

示例

请求:

curl -G 'http://localhost:1818/api/v1/playx/orders' --data-urlencode 'session_id=7b1c....'

响应(示例,简化):

{
  "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.9 同步额度(可选)

当前代码未实现并未注册路由:/api/v1/playx/sync-limit