ChatGPT Plus 自动发货后的交互设计:卡密复制、激活与状态核验
自动发货页面需要回答两个问题:当前完成到了哪一步,接下来该做什么。
以 ChatGPT Plus 的卡密交付为例,“付款成功”“卡密已发放”和“订阅已生效”分别对应不同结果。如果页面只放一段发货文本和一个网址,用户就需要自己判断操作顺序。
这份笔记来自我们维护 AIXiamo(AI夏末)自动发货页面时的整理,主要讨论状态提示、复制反馈和激活入口的衔接。
一、先区分业务状态和页面动作
付款、交付、激活可以分别记录状态。前端根据已经确认的结果展示下一步,避免用一个“成功”覆盖整条流程。
| 已确认的结果 | 页面提示 | 下一步动作 |
|---|---|---|
| 支付状态尚未确认 | 原订单正在核对付款情况 | 查看订单状态 |
| 付款已确认,发货处理中 | 卡密尚未就绪 | 查看发货进度 |
| 卡密已交付 | 可以领取本单卡密 | 复制卡密,打开对应激活入口 |
| 激活请求处理中 | 当前兑换请求正在处理 | 查看请求进度 |
| 激活页面返回完成结果 | 可以核验目标账号套餐 | 查看账号订阅状态 |
| 账号显示与预期不一致 | 需要核对账号与处理结果 | 返回原订单排查 |
复制成功、打开新页面和刷新浏览器属于页面动作。例如,writeText() 执行成功后可以显示“已复制”,但不能据此把业务状态更新为“已激活”。
同样,支付页面是否成功跳回,只能说明浏览器导航的结果。订单的支付状态仍要根据服务端确认的信息展示。
二、把发卡后的操作串起来
卡密交付后的操作可以按四步安排:
- 查看原订单。 展示支付状态、发货进度和本单交付内容。用户刷新或重新进入时,仍能找到已经确认的结果。
- 复制完整卡密。 把卡密与商品名称、说明文字分开显示,提供复制按钮,也保留手动选择文本的方式。
- 打开对应激活入口。 在卡密区域附近说明这个入口对应什么操作,用户核对后再打开。不同商品的入口应与本单交付信息对应。
- 核验目标账号。 激活处理完成后,确认登录的是本次操作对应的 ChatGPT 账号,再查看订阅状态。首次开通关注套餐是否更新;续费还需要有效期证据,不能只看已有的 Plus 标识。
账号核对方法可参考 OpenAI 的 ChatGPT Plus 说明。
复制按钮和激活入口可以相邻放置,但保持为两个独立动作。这样,复制失败时用户可以继续手动处理,也能在离开当前页面前核对目标。
三、复制按钮要有成功和失败两条路径
下面用一个无效的示例卡密演示交互。真实系统应先在服务端完成订单归属和访问权限校验,再向有权限的用户返回交付内容。
<label for="cdk">本单卡密</label>
<input id="cdk" value="DEMO-CDK-NOT-FOR-REDEMPTION" readonly>
<button id="copy-cdk" type="button">复制卡密</button>
<p id="copy-status" role="status" aria-live="polite"></p>
<script>
const field = document.querySelector('#cdk');
const button = document.querySelector('#copy-cdk');
const status = document.querySelector('#copy-status');
button.addEventListener('click', async () => {
const cdk = field.value;
if (!cdk.trim()) {
status.textContent = '卡密尚未就绪,请查看订单发货状态。';
return;
}
button.disabled = true;
status.textContent = '正在复制……';
try {
await navigator.clipboard.writeText(cdk);
status.textContent = '已复制。下一步:打开本单充值入口。';
} catch {
field.focus();
field.select();
status.textContent = '请长按卡密,或选中完整内容后手动复制。';
} finally {
button.disabled = false;
}
});
</script>
这里有几个实现细节:
- 等
writeText()的 Promise 完成后,再提示“已复制”。 - 在复制过程中临时禁用按钮,完成后恢复,避免连续触发。
- 剪贴板写入失败时选中文本,并提示手动复制;不要只弹一个“操作失败”。
- 使用原生
button和aria-live状态区域,保留键盘操作及辅助技术的反馈。
Clipboard.writeText() 需要安全上下文,线上通常使用 HTTPS。浏览器也可能拒绝剪贴板写入,所以代码需要处理异常。MDN 文档说明了返回值和拒绝行为。
卡密文本只用于当前交互,不应拼到网址参数、统计事件或控制台日志里。页面可以统计“复制按钮被点击”,但不需要记录被复制的内容。
四、验收时检查这些边界
| 场景 | 预期表现 |
|---|---|
| 卡密还未返回 | 提示查看发货状态,不显示复制成功 |
| 正常写入剪贴板 | 显示已复制,并说明下一步 |
| 浏览器拒绝写入 | 保留完整卡密,允许手动选择复制 |
| 浏览器没有 Clipboard API | 进入手动复制路径,不中断页面其他操作 |
| 连续点击复制按钮 | 当前操作期间不重复发起复制 |
| 打开激活页后返回 | 可以重新查看原订单和交付信息 |
| 激活页提示完成,账号状态未更新 | 核对目标账号和处理结果,不把页面提示当作最终套餐证据 |
刷新页面时,可以重新获取有权限查看的订单状态。复制成功提示属于临时界面反馈,不需要持久化成订单状态,也不应让刷新页面自动重复提交激活请求。
五、相关示例
gpt-daichong 资料仓库中的 examples/subscription-reconciliation 目录提供了可离线运行的 SQLite 示例,用构造数据演示付款、交付和套餐观察结果的分别核对。它适合用来理解上面的状态区分;本文的 HTML 片段则单独演示复制按钮的交互。
更多推荐



所有评论(0)