支付表单是整站最容易出事故的一处,因为它同时连接着用户的钱、外部服务商和内部订单系统。验收时只点一遍成功路径,等于什么都没测。下面这份支付表单测试清单按「状态、提示、重试、退款、跳转、体验」六个方向整理,每一项都可以直接拿去当勾选条目使用。
先画出状态矩阵
测试开始之前,先把状态定义清楚。宽泛地说,一笔支付请求会落在四种终局:成功、已拒绝、待处理、未知。前三种容易理解,第四种才是问题的来源——它指的是请求发出去了,但没有拿到明确结果。
把「字段校验结果」与「支付终局」交叉起来,就得到一张值得逐格验证的矩阵:
| 字段情况 | 预期结果 | 要确认什么 |
|---|---|---|
| 全部合法 | 进入支付流程 | 请求只发出一次 |
| 卡号校验位错误 | 前端拦下,不发起请求 | 提示指向卡号字段 |
| 有效期已过期 | 前端提示,或服务端拒绝 | 两处判断结果一致 |
| 安全码位数不符 | 按卡组织提示 | 运通卡走四位分支 |
| 必填项为空 | 阻止提交 | 焦点落在第一个错误字段 |
| 金额为零或超出上限 | 拒绝并说明原因 | 不在支付环节才失败 |
矩阵的价值在于它逼你写出「预期结果」。没有预期结果的测试执行一百遍也不会发现问题。
校验与提示是否自洽?
这一部分最容易出现「前后端不一致」。前面拦下了、后面放过了,或者反过来,都会带来难以定位的故障。要确认的点:
- 前端与服务端使用同一套长度与前缀规则,不存在一处更新、另一处忘记。
- 提示语区分「格式不对」与「无法完成支付」,不把校验问题说成卡片问题。
- 校验失败不清空用户已经填好的其他字段。
- 失焦后再提示,不在用户逐字输入时报错。
- 界面上显示的卡号做了掩码,只保留首段与末段。
最后一条属于安全要求而不只是体验。相关约定见信用卡号格式。
哪一类问题最容易造成重复扣款?
重复提交与重试,是重复扣款的主要来源,值得单独一轮测试:
- 用户连点两次提交按钮,只应产生一笔请求。
- 网络超时后用户刷新页面重新提交,不应产生第二笔支付。
- 服务商的异步结果通知重复到达两次,订单状态不应被改两次。
- 用户在等待期间关闭页面,回来时能看到上一笔的真实状态。
判断的方法是看订单侧的结果,而不是看请求次数。一个可复用的原则是:为每笔支付生成一个唯一的请求标识,同一标识重复到达时按同一笔处理。这样无论是用户重试还是通知重发,结果都稳定。
失败、退款与部分请款
非成功路径需要分开来看:既有支付结果本身的失败,也有外部跳转验证带来的分支。
成功路径之外,这几类必须覆盖:
- 同步拒绝:用户当场看到失败,订单没有被标记为已支付。
- 异步失败:先进入待处理,稍后转为失败,且通知用户。
- 全额退款:订单状态与金额都正确回退。
- 部分退款:剩余金额可再次退款,累计不超过原额。
- 部分请款:授权金额与实际请款金额不同时,账面处理正确。
- 撤销授权:未请款的授权被正确释放。
退款与请款的测试要点是「可重复操作」和「金额守恒」。建议准备一个能核对金额的小账本,逐笔累加后与订单总额比对,比逐条看状态更能发现偏差。
如果支付流程包含外部跳转验证,它自带一组独立的失败分支:
- 跳转成功后正常回跳并完成支付。
- 用户跳转后直接关闭页面,再回到站内时的状态正确。
- 验证失败后能重试,且不会生成第二笔支付。
- 验证已完成但回跳地址没有收到结果——这一种必须有服务端兜底查询。
- 回跳地址被重复访问,不会重复处理。
最后两种在真实用户那里并不罕见,而且是最容易留下「订单永远停在未完成」状态的原因。测试时应当用服务商公开的测试号码主动触发验证流程,具体分类见Stripe 测试卡怎么用。
有效期与安全码的边界
这两个字段的边界值值得单独列一行,因为它们出错的概率远高于卡号:
- 当月到期的卡,在当月最后一天仍然有效。
- 已过期一个月的卡被正确拒绝。
- 跨年时月份比较不出现异常。
- 服务端判断使用的参照时间明确,不因时区差异在月底最后几个小时出现分歧。
- 安全码四位的卡组织走的是另一条输入分支。
有效期那一条的细节值得单独读一遍,见信用卡有效期格式。
常被漏掉的体验与无障碍
下面这些不会造成扣款错误,但会让一部分用户根本提交不了:
- 键盘可以完成全部填写与提交,不需要鼠标。
- 输入框有可被读屏软件识别的标签,而不是只用占位文字当标签。
- 错误提示与具体字段关联,读屏时能知道是哪一个字段出错。
- 密码管理器与浏览器自动填充能正确填入,且不会把卡号填进有效期框。
- 支持粘贴带空格的完整卡号。
- 移动端数字键盘直接弹出,不需要用户切换。
- 页面放大到两倍时布局不遮挡提交按钮。
自动填充这一条尤其值得实测。它常常绕过你的输入事件,导致「用户看到填写成功但校验状态没有更新」这类问题,而这在正常手工输入时完全不会出现。
给开发者:自查清单的用法
把这份清单变成一个可执行的文件,而不是一篇读完就忘的文章。几点建议:
- 每条都写预期结果,并在清单里留一列记录实际结果与时间。没有预期结果的条目会被执行者随手勾掉。
- 把固定的测试数据写进仓库。号码固定、有效期固定、参照时间固定,任何人执行都得到同一结论。挑选数据的方法见测试信用卡号是什么。要注意这些固定数据只能是合成的:它们结构上合法,但从未发行给任何人,用于本地校验与界面测试可以,对真实支付网关发起请求则不会成立。
- 区分「每次发布的回归项」与「一次性的集成项」。重复提交、异步失败、回跳兜底属于必须每轮回归的项;无障碍检查可以按季度过一遍。
- 把失败过的条目留在清单里。修好之后不要删除,它是将来最容易再坏的地方。
- 对数金额单独过一次。用一笔小额、一笔带小数的金额各跑一遍流程,确认小数位处理没有偏差。
另外建议固定一条纪律:任何涉及金额与状态的改动,都必须重新跑一遍状态矩阵,而不是只跑改动到的那一格。支付系统的问题几乎都出在分支之间的相互作用上。
下一步
先从状态矩阵开始,把每一格的预期结果写下来,再逐条执行。清单不需要一次全覆盖,但要保证「重复提交」和「回跳兜底」这两类每轮都在。
需要一批固定的测试号码来填充数据文件,用信用卡号生成器,并把生成结果保存下来作为版本受控的固定装置;校验逻辑本身的顺序问题,见校验信用卡号。