From c3775b7708626442dab4781f46a1c3a92d76193e Mon Sep 17 00:00:00 2001 From: huanghaipeng Date: Tue, 8 Sep 2026 09:59:29 +0800 Subject: [PATCH] docs: add Postman collection for battle pass V2 --- .../battle-pass-v2.postman_collection.json | 827 ++++++++++++++++++ 1 file changed, 827 insertions(+) create mode 100644 laf-cloud/postman/battle-pass-v2.postman_collection.json diff --git a/laf-cloud/postman/battle-pass-v2.postman_collection.json b/laf-cloud/postman/battle-pass-v2.postman_collection.json new file mode 100644 index 0000000..b1ea87b --- /dev/null +++ b/laf-cloud/postman/battle-pass-v2.postman_collection.json @@ -0,0 +1,827 @@ +{ + "info": { + "_postman_id": "70189f40-22d4-4780-8411-5e9679999356", + "name": "战令 V2 · 三档购买与旧数据兼容", + "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json", + "description": "导入后在集合 Variables 填写 baseUrl(测试后端地址,不带末尾斜杠)、uid、token(现有游戏登录取得),保存后先单独执行新版 read。其余变量会按响应更新;level 可手动填写。没有内置账号、支付密钥或生产地址。请使用测试账号:read 可触发迁移,结算和领奖会修改服务端数据。不要对整个集合 Run:不同购买路径互斥。订单接口只生成签名与订单,不能在 Postman 内完成微信付款;不提供伪造支付回调。业务失败 code=0 仍可能 HTTP200,请检查 data.reason。功能开关默认关闭时 FEATURE_DISABLED 为预期结果;迁移异常返回 LEGACY_REWARDS_PENDING/LEGACY_PERIOD_INVALID,不应清空历史记录。已迁移用户旧接口返回 CLIENT_UPGRADE_REQUIRED。" + }, + "variable": [ + { + "key": "baseUrl", + "value": "", + "type": "string" + }, + { + "key": "uid", + "value": "", + "type": "string" + }, + { + "key": "token", + "value": "", + "type": "string" + }, + { + "key": "currentSeasonId", + "value": "", + "type": "string" + }, + { + "key": "seasonId", + "value": "", + "type": "string" + }, + { + "key": "roundId", + "value": "", + "type": "string" + }, + { + "key": "roundSeq", + "value": "0", + "type": "string" + }, + { + "key": "level", + "value": "1", + "type": "string" + }, + { + "key": "expectedLoopClaimed", + "value": "0", + "type": "string" + }, + { + "key": "outTradeNo", + "value": "", + "type": "string" + } + ], + "event": [ + { + "listen": "prerequest", + "script": { + "type": "text/javascript", + "exec": [ + "for (const key of [\"baseUrl\", \"uid\", \"token\"]) { const value = pm.variables.get(key); if (!value || !String(value).trim()) throw new Error(\"请先填写集合变量:\" + key); }" + ] + } + }, + { + "listen": "test", + "script": { + "type": "text/javascript", + "exec": [ + "pm.test(\"HTTP 200\", () => pm.response.to.have.status(200));", + "const result = pm.response.json();", + "pm.test(\"响应包含 code / data / msg\", () => { pm.expect(result).to.have.property(\"code\"); pm.expect(result).to.have.property(\"data\"); pm.expect(result).to.have.property(\"msg\"); });", + "if (result.code !== 1) console.warn(\"业务未成功:\", result.data && result.data.reason, result.msg);" + ] + } + } + ], + "item": [ + { + "name": "01 读取与迁移", + "item": [ + { + "name": "读取新版战令(先执行)", + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"uid\": \"{{uid}}\",\n \"token\": \"{{token}}\",\n \"action\": \"read\"\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/passCheckV2", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "passCheckV2" + ] + }, + "description": "首次成功 read 会迁移灰度用户。自动保存展示期次、当前期次和循环游标。LEGACY_REWARDS_PENDING 表示历史奖励待处理,原用户档案保持不变;不要清空旧数据绕过迁移。" + }, + "response": [], + "event": [ + { + "listen": "test", + "script": { + "type": "text/javascript", + "exec": [ + "const r = pm.response.json();", + "if (r.code === 1 && r.data.current) {", + " const d = r.data;", + " pm.collectionVariables.set(\"currentSeasonId\", d.current.id);", + " pm.collectionVariables.set(\"seasonId\", d.displaySeasonId);", + " const p = d.displaySeasonId === d.current.id ? d.current : d.previous;", + " pm.collectionVariables.set(\"expectedLoopClaimed\", p.loopClaimed);", + " console.log(\"展示期次/档位/未兑换次数\", p.id, p.tier, p.loopAvailable);", + " console.log(\"合法购买选项\", d.purchaseOptions);", + "}" + ] + } + } + ] + }, + { + "name": "读取旧版战令(兼容检查)", + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"uid\": \"{{uid}}\",\n \"token\": \"{{token}}\",\n \"action\": \"read\"\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/passCheck", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "passCheck" + ] + }, + "description": "未迁移用户可正常读取旧 passCheck;已迁移用户预期 CLIENT_UPGRADE_REQUIRED。只读,不调用旧 save。" + }, + "response": [] + } + ] + }, + { + "name": "02 单局进度", + "item": [ + { + "name": "开始一局,保存服务器编号", + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"uid\": \"{{uid}}\",\n \"token\": \"{{token}}\",\n \"action\": \"begin_round\"\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/passCheckV2", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "passCheckV2" + ] + }, + "description": "先 read。自动保存 roundId、roundSeq。未结算时重复调用返回原编号。" + }, + "response": [], + "event": [ + { + "listen": "test", + "script": { + "type": "text/javascript", + "exec": [ + "const r = pm.response.json();", + "if (r.code === 1 && r.data.round) {", + " pm.collectionVariables.set(\"roundId\", r.data.round.id);", + " pm.collectionVariables.set(\"roundSeq\", r.data.round.seq);", + "}" + ] + } + } + ] + }, + { + "name": "胜利结算", + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"uid\": \"{{uid}}\",\n \"token\": \"{{token}}\",\n \"action\": \"complete_round\",\n \"roundId\": \"{{roundId}}\",\n \"roundSeq\": {{roundSeq}},\n \"won\": true\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/passCheckV2", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "passCheckV2" + ] + }, + "description": "使用 begin 返回的编号。第一/二档增加1点,第三档增加2点。" + }, + "response": [] + }, + { + "name": "重复胜利结算(验证不重复加点)", + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"uid\": \"{{uid}}\",\n \"token\": \"{{token}}\",\n \"action\": \"complete_round\",\n \"roundId\": \"{{roundId}}\",\n \"roundSeq\": {{roundSeq}},\n \"won\": true\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/passCheckV2", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "passCheckV2" + ] + }, + "description": "紧接胜利结算调用,不重新 begin;预期 alreadyApplied:true,points 不增加。" + }, + "response": [] + }, + { + "name": "失败或退出结算", + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"uid\": \"{{uid}}\",\n \"token\": \"{{token}}\",\n \"action\": \"complete_round\",\n \"roundId\": \"{{roundId}}\",\n \"roundSeq\": {{roundSeq}},\n \"won\": false\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/passCheckV2", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "passCheckV2" + ] + }, + "description": "先开始一局,再使用这个请求;该局不会增加进度。不要将它当成撤销胜利接口。" + }, + "response": [] + } + ] + }, + { + "name": "03 领取奖励", + "item": [ + { + "name": "领取免费列", + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"uid\": \"{{uid}}\",\n \"token\": \"{{token}}\",\n \"action\": \"claim_level\",\n \"seasonId\": \"{{seasonId}}\",\n \"track\": \"free\",\n \"level\": {{level}}\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/passCheckV2", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "passCheckV2" + ] + }, + "description": "level 默认1,按实际解锁等级修改。seasonId 默认由 read 选中展示期次。重复调用不重复发奖。" + }, + "response": [] + }, + { + "name": "领取付费列", + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"uid\": \"{{uid}}\",\n \"token\": \"{{token}}\",\n \"action\": \"claim_level\",\n \"seasonId\": \"{{seasonId}}\",\n \"track\": \"paid\",\n \"level\": {{level}}\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/passCheckV2", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "passCheckV2" + ] + }, + "description": "必须已购买18元或30元档,免费档预期 TIER_REQUIRED。" + }, + "response": [] + }, + { + "name": "批量领取循环奖励 / 原游标重试", + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"uid\": \"{{uid}}\",\n \"token\": \"{{token}}\",\n \"action\": \"claim_loop\",\n \"seasonId\": \"{{seasonId}}\",\n \"expectedLoopClaimed\": {{expectedLoopClaimed}}\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/passCheckV2", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "passCheckV2" + ] + }, + "description": "仅第三档且满级进度足够。游标仅在 read 时刷新:直接重发本请求验证幂等;领取新积攒奖励之前重新 read。返回 resources 为服务端实际余额。" + }, + "response": [] + } + ] + }, + { + "name": "04 Android下单(选择一项单独执行)", + "item": [ + { + "name": "18元开通:battlepass", + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"uid\": \"{{uid}}\",\n \"token\": \"{{token}}\",\n \"passCheckVersion\": 2,\n \"itemid\": \"battlepass\",\n \"itemCount\": 1,\n \"itemPrice\": 1800\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/wx/orderPaySig", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "wx", + "orderPaySig" + ] + }, + "description": "先成功读取新版战令,确认 purchaseOptions 含此商品。会创建真实服务端待支付订单,但 Postman 不拉起微信支付,也不自动扣款。同用户只能有一个有效待支付订单,不要批量执行不同购买路径。订单号自动保存为 outTradeNo。实际支付需微信客户端;服务端礼包、循环和验签配置未齐时禁止下单。" + }, + "response": [], + "event": [ + { + "listen": "test", + "script": { + "type": "text/javascript", + "exec": [ + "const r = pm.response.json();", + "if (r.code === 1 && r.data.outTradeNo) pm.collectionVariables.set(\"outTradeNo\", r.data.outTradeNo);" + ] + } + }, + { + "listen": "prerequest", + "script": { + "type": "text/javascript", + "exec": [ + "if (!pm.collectionVariables.get(\"currentSeasonId\")) throw new Error(\"请先成功读取新版战令,避免走旧版18元下单逻辑\");" + ] + } + } + ] + }, + { + "name": "30元直接开通:battlepass_30", + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"uid\": \"{{uid}}\",\n \"token\": \"{{token}}\",\n \"passCheckVersion\": 2,\n \"itemid\": \"battlepass_30\",\n \"itemCount\": 1,\n \"itemPrice\": 3000\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/wx/orderPaySig", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "wx", + "orderPaySig" + ] + }, + "description": "先成功读取新版战令,确认 purchaseOptions 含此商品。会创建真实服务端待支付订单,但 Postman 不拉起微信支付,也不自动扣款。同用户只能有一个有效待支付订单,不要批量执行不同购买路径。订单号自动保存为 outTradeNo。实际支付需微信客户端;服务端礼包、循环和验签配置未齐时禁止下单。" + }, + "response": [], + "event": [ + { + "listen": "test", + "script": { + "type": "text/javascript", + "exec": [ + "const r = pm.response.json();", + "if (r.code === 1 && r.data.outTradeNo) pm.collectionVariables.set(\"outTradeNo\", r.data.outTradeNo);" + ] + } + }, + { + "listen": "prerequest", + "script": { + "type": "text/javascript", + "exec": [ + "if (!pm.collectionVariables.get(\"currentSeasonId\")) throw new Error(\"请先成功读取新版战令,避免走旧版18元下单逻辑\");" + ] + } + } + ] + }, + { + "name": "18元补12元升级:battlepass_12", + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"uid\": \"{{uid}}\",\n \"token\": \"{{token}}\",\n \"passCheckVersion\": 2,\n \"itemid\": \"battlepass_12\",\n \"itemCount\": 1,\n \"itemPrice\": 1200\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/wx/orderPaySig", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "wx", + "orderPaySig" + ] + }, + "description": "先成功读取新版战令,确认 purchaseOptions 含此商品。会创建真实服务端待支付订单,但 Postman 不拉起微信支付,也不自动扣款。同用户只能有一个有效待支付订单,不要批量执行不同购买路径。订单号自动保存为 outTradeNo。实际支付需微信客户端;服务端礼包、循环和验签配置未齐时禁止下单。" + }, + "response": [], + "event": [ + { + "listen": "test", + "script": { + "type": "text/javascript", + "exec": [ + "const r = pm.response.json();", + "if (r.code === 1 && r.data.outTradeNo) pm.collectionVariables.set(\"outTradeNo\", r.data.outTradeNo);" + ] + } + }, + { + "listen": "prerequest", + "script": { + "type": "text/javascript", + "exec": [ + "if (!pm.collectionVariables.get(\"currentSeasonId\")) throw new Error(\"请先成功读取新版战令,避免走旧版18元下单逻辑\");" + ] + } + } + ] + } + ] + }, + { + "name": "04 iOS(含客服预留订单)下单(选择一项单独执行)", + "item": [ + { + "name": "18元开通:battlepass", + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"uid\": \"{{uid}}\",\n \"token\": \"{{token}}\",\n \"passCheckVersion\": 2,\n \"itemid\": \"battlepass\",\n \"itemCount\": 1,\n \"itemPrice\": 1800\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/wx/iosorderPaySig", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "wx", + "iosorderPaySig" + ] + }, + "description": "先成功读取新版战令,确认 purchaseOptions 含此商品。会创建真实服务端待支付订单,但 Postman 不拉起微信支付,也不自动扣款。同用户只能有一个有效待支付订单,不要批量执行不同购买路径。订单号自动保存为 outTradeNo。实际支付需微信客户端;服务端礼包、循环和验签配置未齐时禁止下单。" + }, + "response": [], + "event": [ + { + "listen": "test", + "script": { + "type": "text/javascript", + "exec": [ + "const r = pm.response.json();", + "if (r.code === 1 && r.data.outTradeNo) pm.collectionVariables.set(\"outTradeNo\", r.data.outTradeNo);" + ] + } + }, + { + "listen": "prerequest", + "script": { + "type": "text/javascript", + "exec": [ + "if (!pm.collectionVariables.get(\"currentSeasonId\")) throw new Error(\"请先成功读取新版战令,避免走旧版18元下单逻辑\");" + ] + } + } + ] + }, + { + "name": "30元直接开通:battlepass_30", + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"uid\": \"{{uid}}\",\n \"token\": \"{{token}}\",\n \"passCheckVersion\": 2,\n \"itemid\": \"battlepass_30\",\n \"itemCount\": 1,\n \"itemPrice\": 3000\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/wx/iosorderPaySig", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "wx", + "iosorderPaySig" + ] + }, + "description": "先成功读取新版战令,确认 purchaseOptions 含此商品。会创建真实服务端待支付订单,但 Postman 不拉起微信支付,也不自动扣款。同用户只能有一个有效待支付订单,不要批量执行不同购买路径。订单号自动保存为 outTradeNo。实际支付需微信客户端;服务端礼包、循环和验签配置未齐时禁止下单。" + }, + "response": [], + "event": [ + { + "listen": "test", + "script": { + "type": "text/javascript", + "exec": [ + "const r = pm.response.json();", + "if (r.code === 1 && r.data.outTradeNo) pm.collectionVariables.set(\"outTradeNo\", r.data.outTradeNo);" + ] + } + }, + { + "listen": "prerequest", + "script": { + "type": "text/javascript", + "exec": [ + "if (!pm.collectionVariables.get(\"currentSeasonId\")) throw new Error(\"请先成功读取新版战令,避免走旧版18元下单逻辑\");" + ] + } + } + ] + }, + { + "name": "18元补12元升级:battlepass_12", + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"uid\": \"{{uid}}\",\n \"token\": \"{{token}}\",\n \"passCheckVersion\": 2,\n \"itemid\": \"battlepass_12\",\n \"itemCount\": 1,\n \"itemPrice\": 1200\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/wx/iosorderPaySig", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "wx", + "iosorderPaySig" + ] + }, + "description": "先成功读取新版战令,确认 purchaseOptions 含此商品。会创建真实服务端待支付订单,但 Postman 不拉起微信支付,也不自动扣款。同用户只能有一个有效待支付订单,不要批量执行不同购买路径。订单号自动保存为 outTradeNo。实际支付需微信客户端;服务端礼包、循环和验签配置未齐时禁止下单。" + }, + "response": [], + "event": [ + { + "listen": "test", + "script": { + "type": "text/javascript", + "exec": [ + "const r = pm.response.json();", + "if (r.code === 1 && r.data.outTradeNo) pm.collectionVariables.set(\"outTradeNo\", r.data.outTradeNo);" + ] + } + }, + { + "listen": "prerequest", + "script": { + "type": "text/javascript", + "exec": [ + "if (!pm.collectionVariables.get(\"currentSeasonId\")) throw new Error(\"请先成功读取新版战令,避免走旧版18元下单逻辑\");" + ] + } + } + ] + } + ] + }, + { + "name": "05 支付确认与补单", + "item": [ + { + "name": "已验证支付订单补单", + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"uid\": \"{{uid}}\",\n \"token\": \"{{token}}\",\n \"action\": \"reconcile_order\",\n \"outTradeNo\": \"{{outTradeNo}}\"\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/passCheckV2", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "passCheckV2" + ] + }, + "description": "只能补当前用户的、服务端已验证支付订单。未支付预期 ORDER_UNPAID;成功后再次 read 同步档位和资源。重复请求不重复发礼包。" + }, + "response": [] + }, + { + "name": "iOS客服支付查单", + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"uid\": \"{{uid}}\",\n \"token\": \"{{token}}\",\n \"outTradeNo\": \"{{outTradeNo}}\"\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/wx/iosgetPayInfo", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "wx", + "iosgetPayInfo" + ] + }, + "description": "用于经微信客服会话支付的商户订单;调用商户查单并核实付款,不可用于伪造成功。iOS虚拟支付使用前一个补单请求。" + }, + "response": [] + } + ] + } + ] +}