Coupon_API_Doc.md 7.5 KB

优惠券 (Coupon) API 文档

概述

优惠券功能允许用户在充值时获得额外的金币奖励。系统会根据配置的策略自动向符合条件的用户发放优惠券。

架构: 采用事件驱动模式 —— 订单支付成功后触发 OrderPaid 事件,由 ProcessCouponOnOrderPaid Listener 异步处理优惠券逻辑(验证、发放金币、标记已用),与订单核心流程完全解耦。

路由位置: routes/game.phpcheckGameLogin + mustGameLogin 中间件组)

优惠券类型

类型 type_id 说明
固定金额 1 充值后赠送固定金额金币(与充值额无关)
充值百分比 2 充值后按充值金额的百分比赠送金币,有上限

优惠券状态

状态 status 说明
未使用 0 可用
已使用 1 已绑定订单并发放金币
已过期 2 超过有效期

接口列表

1. 获取优惠券列表

获取用户当前可用的优惠券列表,同时触发自动发放逻辑。系统会根据 config/coupon.php 中的规则检查用户是否符合发放条件,符合则自动发放新券。

GET /game/coupon/list

鉴权: checkGameLogin + mustGameLogin 中间件(从 $request->globalUser->UserID 获取用户ID)

请求示例:

GET /game/coupon/list

成功响应:

{
    "code": 200,
    "msg": "success",
    "data": {
        "list": [
            {
                "id": 1,
                "name": "new_user_bonus",
                "type": "percent",
                "type_id": 2,
                "value": 50,
                "min_recharge": 10,
                "max_bonus": 50,
                "desc": "+50% bonus (max 50)",
                "status": 0,
                "expire_at": "2026-06-03 12:00:00",
                "issued_at": "2026-05-27 12:00:00"
            }
        ],
        "new_issued": [
            {
                "id": 1,
                "name": "new_user_bonus",
                "type": "percent",
                "type_id": 2,
                "value": 50,
                "min_recharge": 10,
                "max_bonus": 50,
                "desc": "+50% bonus (max 50)",
                "status": 0,
                "expire_at": "2026-06-03 12:00:00",
                "issued_at": "2026-05-27 12:00:00"
            }
        ]
    }
}

响应字段说明:

字段 类型 说明
list array 当前所有可用优惠券
new_issued array 本次请求新发放的优惠券(首次调用时可能非空)
id int 优惠券ID,充值下单时传入
name string 优惠券名称(标识)
type string fixed=固定金额, percent=百分比
type_id int 1=固定金额, 2=百分比
value float 优惠值(元 or %)
min_recharge float 最低充值门槛(元)
max_bonus float 最大赠送上限(元),百分比券有效
desc string 前端展示文案
status int 0=可用, 1=已用, 2=过期
expire_at string 过期时间
issued_at string 发放时间

2. 预估优惠券赠送金额

在用户选择优惠券后、发起支付前调用,用于向用户展示预计获得的额外金币。

POST /game/coupon/preview

鉴权: checkGameLogin + mustGameLogin 中间件

请求参数:

参数 类型 必填 说明
userID int 用户ID
coupon_id int 优惠券ID
payAmt float 充值金额(元)

请求示例:

POST /game/coupon/preview
Content-Type: application/json

{
    "userID": 123456,
    "coupon_id": 1,
    "payAmt": 50
}

成功响应:

{
    "code": 200,
    "msg": "success",
    "data": {
        "coupon_id": 1,
        "bonus_amount": 25.00,
        "bonus_coins": 2500,
        "total_amount": 75.00
    }
}

响应字段说明:

字段 类型 说明
coupon_id int 优惠券ID
bonus_amount float 预计赠送金额(元)
bonus_coins int 预计赠送金币(分,1元=100分)
total_amount float 预计到账总额(元)= 充值额 + 赠送额

失败响应:

{
    "code": 301,
    "msg": "Minimum recharge 10 required for this coupon",
    "data": []
}

3. 支付时使用优惠券

在支付接口中新增 coupon_id 参数,传入要使用的优惠券ID。

影响接口: POST /payment_entry/payroutes/game.php

新增参数:

参数 类型 必填 默认值 说明
coupon_id int 0 优惠券ID,0=不使用优惠券

请求示例:

{
    "payAmt": 50,
    "pay_type": 1,
    "pay_method": "2",
    "GiftsID": 0,
    "coupon_id": 1
}

处理流程(事件驱动):

  1. ProcessCouponOnOrderPaid Listener 异步处理:
    • 验证优惠券有效性(未使用、未过期、充值金额满足门槛)
    • 计算赠送金币
    • 标记优惠券为已使用,绑定订单号
    • 增加用户金币(Reason=55, 优惠券赠送)
  2. 如果优惠券使用失败(已过期/已使用/金额不满足),不影响正常充值流程,仅记录日志

自动发放策略

系统在用户调用 GET /game/coupon/list 时自动检查以下条件并发放优惠券。

配置文件: config/coupon.php

默认策略

策略名称 条件 券类型 优惠 最低充值 有效期
new_user_bonus 注册≤3天 + 从未充值 百分比 50% (上限50元) 10元 7天
comeback_bonus 最近充值≥14天前 百分比 30% (上限30元) 20元 3天
vip_recharge_bonus 累计充值≥500元 固定 20元 50元 14天

发放条件类型

条件类型 参数 说明
new_user days 注册天数 ≤ days 且从未充值
inactive_days days 最近一次充值距今 ≥ days(需有充值历史)
recharge_total amount 累计充值金额 ≥ amount(元)
vip_level level VIP等级 ≥ level

防重复机制

同一用户不会重复获得同名的有效优惠券。只有当前券过期或使用后,下次请求才会重新发放。


数据库表结构

agent.dbo.user_coupons

字段 类型 说明
id INT IDENTITY PK 主键
user_id INT NOT NULL 用户ID
coupon_name VARCHAR(50) 优惠券名称
coupon_type TINYINT 1=固定金额, 2=百分比
coupon_value DECIMAL(10,2) 优惠值
min_recharge DECIMAL(10,2) 最低充值门槛
max_bonus DECIMAL(10,2) 最大赠送上限
bonus_coins INT 实际赠送金币(分)
order_sn VARCHAR(64) 关联订单号
status TINYINT 0=未使用, 1=已使用, 2=已过期
issued_at DATETIME 发放时间
used_at DATETIME 使用时间
expire_at DATETIME 过期时间

优惠券-订单关联

优惠券通过 order_sn 字段关联订单,不在 order 表中新增字段,保持订单表结构不变。

coupon_id 在支付请求→回调之间通过 Redis 临时存储(key=coupon_{order_sn},TTL=24h)。


金币变更记录

使用优惠券后,金币增加记录写入 QPRecordDB.dbo.RecordUserScoreChange

字段 说明
Reason 55 优惠券赠送(与现有21/33/44/45/49/51/52/72/73不冲突)

可通过 config/coupon.php 中的 score_reason 配置修改。