作者:BluffKing · · 更新
Telegram 测试误扣款
一次 Telegram 测试发生 1,077 新币真实充值。区分订单与充值账本,说明当前初始订单 1 XTR 限制、余额声明与明确授权例外。
2026 年 7 月 15 日,我们在 Telegram 官方测试环境(Bot API 地址加 /test)里测 Stars 订阅。bot 一侧完全正常:1,000 XTR 的测试订单被创建、付款、开通,最后被全额退回。但付款用的是 App Store 下载的稳定版 Telegram,测试账号没有 Stars 余额,客户端就弹出了普通的 Apple 内购面板:先花 S$29 买了 1,000 Stars 付掉测试订单,测试栈关停后又为第二天的续期测试买了 35,000 Stars,花了 S$1,048,合计 1,077 新币真钱。
根因是一笔 Stars 付款要穿过三套账本:bot 订单、账号里的 Stars 余额、给余额充值的 Apple 内购。/test 只隔离第一套;稳定版客户端不会因此变成 StoreKit 沙盒,而 refundStarPayment 只能退回 Stars,碰不到 Apple 收走的现金。我们的测试手册写着「Test Server 流程不会扣真钱」,这句话对订单成立、对充值不成立,而且从没有人在真实付款面板前验证过。
Apple 在 7 月 16 日批准了两笔全额退款。我们没有花掉或删掉这 36,000 Stars,把 Telegram 里「via App Store」的充值记录和 Apple 的扣款对齐到分钟,把两笔放进同一个工单申请人工例外审查,并如实说明是测试误购而不是盗刷;退不退由 Apple 决定,这只是走通过一次的路径。
现在这条规则不再只写在文档里,而是服务端的 fail-closed 防护(server/src/handlers/billing_configuration.rs 中的 enforce_telegram_test_server_money_guard)。非生产环境走真实 provider 的订单必须由专用受限运行时发起;初始订单金额只能是 1 XTR,每次运行只能有一笔初始订单,预算在数据库事务里与订单一起消耗;操作者必须声明测试账号里已有的余额,并确认它是非商店测试余额,唯一例外是附有效授权 ID、明确授权且已退款的商店余额。这些声明由操作者提供,代码无法核实,防护也拦不住有人在 Telegram 客户端里手动充值,所以测试中一旦出现真实购买面板就取消,没有可信余额就停止真实 provider 测试。复盘时还修了两个 bug:过期订阅因 SUBSCRIPTION_NOT_ACTIVE 被当成硬失败而无法取消或退款,以及订阅周期写死 30 天、无法做续期测试。
教训是:测试模式是每套账本各自的属性,付款链路穿过几套账本,「这是假钱」就要在几套上分别验证。任何「先充值、再消费」的系统,比如游戏币、平台积分或代币钱包,都有同一条缝;测试中弹出的任何购买面板,都应当按真钱处理。