# layer_3 商城 A/B 接入 客户端读取登录返回的 layer_3:A 使用 shop,B 使用 shop2;无有效 B 分组时使用 A。首页和关卡共用同一选择规则,临时全部首充双倍的预览开关已关闭。月卡、战令、新手礼包的商品与奖励不随商城分组改变。 ## B 商品配置 金额单位为元;客户端、服务端下单金额使用分。 | 商品 ID | 价格 | 金币 | 锤子 / 冻结 / 魔法棒 | 无限体力 | | --- | ---: | ---: | --- | --- | | new_gold_1 | 6 | 1200 | — | — | | new_gold_2 | 30 | 6800 | — | — | | new_gold_3 | 68 | 16000 | — | — | | new_gold_4 | 128 | 32000 | — | — | | new_gold_5 | 328 | 84000 | — | — | | new_gold_6 | 648 | 168000 | — | — | | new_unlimited_health_bundle_8 | 8 | 1500 | 2 / 2 / 2 | 无 | | new_unlimited_health_bundle_18 | 18 | 3000 | 5 / 5 / 5 | 30 分钟 | | new_unlimited_health_bundle_36 | 36 | 6000 | 10 / 10 / 10 | 2 小时 | | new_unlimited_health_bundle_68 | 68 | 10000 | 20 / 20 / 20 | 6 小时 | | new_unlimited_health_bundle_98 | 98 | 20000 | 25 / 25 / 25 | 12 小时 | new_gold_1~6 共用原 gold_1~6 的首充记录,不重置资格。礼包没有金币首充翻倍。补单按原订单商品 ID 发奖,不按补单时的 A/B 分组切换奖励。 ## 发布依赖 本次只修改本地文件,未部署、未修改微信商品后台。 1. 先发布公共函数模块 `shopConfig`(包含 YAML),再发布引用它的 `wx/orderPaySig`、`wx/iosorderPaySig`、`wx/KeFuInfo`。 2. 核对微信商品后台是否已配置上述 11 个新 ID 及对应价格。旧商品保留以支持 A 组和旧订单。 3. 发布包含 ShopCatalog、shop2 和 A/B 加载修改的客户端。不要先给仍不识别新商品的旧客户端开放新商城订单。 4. 微信真机分别验证 A/B 首页与关卡入口、首充已用/未用、8 元无无限体力、98 元加 12 小时、支付返回与重登补单。真机支付本次未执行。 服务端固定新商品的价格和数量 1;旧商品保持原路径。客户端新商品使用订单号做本地去重,支付轮询固定对应订单号,不依赖其他窗口可能改写的全局订单号。此机制不等于跨设备的服务端奖励账本。 ## 本地验证 在仓库根目录运行(Node 24,已安装项目 TypeScript): ```text node --test tools/test-shop-ab.cjs server/laf-cloud/tests/shop-ab.test.cjs tools/test-starter-pack.cjs tools/test-shop-activity-carousel.cjs tools/test-monthly-card-lifecycle.cjs ``` 覆盖商城路由、缓存复用、节点切换、全部新商品数值、首充共用、补单去重和安卓/iOS/客服支付金额。支付接口测试均使用桩,不调用真实支付。 扩大检查时发现以下既有问题,未纳入本次商城修改: - `tools/test-reborn-gift.cjs` 的未支付订单断言失败:`wx/getOrderReward.ts` 在校验前更新订单状态。 - `jungle-treasure.test.mjs` 有 6 项配置/活动期/订单状态相关失败;`payment-routing.test.mjs` 有 1 项失败,测试期望固定转发 URL,但当前实现读取 `TEST_WX_PAY_NOTIFY_URL` 环境变量。 - 全项目 `tsc --noEmit` 被 `functions/drawHead.ts:35` 的 TS1128 语法错误阻断。本次修改的 TypeScript 文件单独转译无语法诊断。