{ "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": [] } ] } ] }