前言
今天主要在继续完善电商项目的限时活动模块。
这部分看起来只是“秒杀、拼团、预售”几个入口,但真正做起来,会牵扯到库存、购物车、支付、订单状态、商家发货和消息提醒等多个模块。只要其中一个状态处理得不严谨,就容易出现未支付却显示成功、拼团未完成就能发货、重复点击导致重复购买等问题。
今天没有急着增加更多页面,而是围绕现有业务流程逐个检查,把几个比较明显的问题处理掉。
一、完善秒杀活动的限购和库存处理
秒杀场景最先需要解决的是重复购买问题。
当前项目中的秒杀商品要求每个账号只能购买一件,因此不能只在前端把按钮禁用。前端限制很容易被绕过,真正的校验必须放在后端。
现在的处理流程是:
把库存判断和扣减放进同一个 Lua 脚本,是为了避免并发情况下多个请求同时读取到相同库存。这样可以保证整个操作是原子的,减少超卖问题。
另外,用户秒杀成功后仍然可以再次点击按钮,但系统不会重复添加商品,而是提示:
本场秒杀每位用户限购 1 件,你已抢购成功,无需重复下单。
提示也没有继续使用页面顶部的大块警告,而是放到了商品操作区域,旁边提供“查看购物车”“查看订单”和“关闭”按钮,操作起来更顺手。
二、重新梳理拼团状态
拼团流程的问题主要出在“点击参团”和“完成支付”之间。
之前点击参团按钮后,页面可能直接显示已经参团,即使用户还没有完成支付。这种状态显然不合理,因为参团人数应该以实际支付结果为准。
调整后的流程是:
拼团商品也不会在支付后立即进入购物车,而是需要等待拼团成功。未达到成团人数时,商家端不能发货,后端发货接口同样会进行状态校验,不能只靠页面按钮限制。
这样处理后,拼团流程中的几个状态就比较清楚了:
- 未支付:未参团;
- 已支付但人数不足:拼团中;
- 达到成团人数:拼团成功;
- 拼团成功后:进入后续履约和发货流程。
三、修正预售定金支付逻辑
预售和普通商品最大的区别,是付款会被拆成定金和尾款两个阶段。
今天重点处理了“未支付却显示已付定金”的问题。现在用户点击支付按钮后,系统不会立刻修改预售状态,而是先创建一条待支付记录,然后跳转支付宝沙箱。
只有支付宝回调满足以下条件时,才会写入已付定金状态:
- 支付宝签名验证通过;
- 支付流水号能够匹配到待支付记录;
- 支付金额与订单金额一致;
- 交易状态符合支付成功条件。
支付定金成功后,系统会锁定用户的预售资格。后续还需要继续补充尾款支付时间、尾款提醒、超时关闭和退款等流程,不过今天先把定金阶段的状态处理完整了。
四、接入支付宝沙箱支付
今天把拼团参团款和预售定金统一接入了支付宝沙箱。
支付页面目前只保留支付宝沙箱,不再展示暂时无法使用的微信支付和银行卡支付,避免用户看到按钮后却无法完成操作。
整个支付流程大致如下:
用户提交支付
↓
后端创建待支付记录
↓
生成支付宝沙箱收银台地址
↓
用户使用沙箱买家账号支付
↓
支付宝同步回跳和异步通知
↓
后端进行 RSA2 验签
↓
校验支付金额与支付流水号
↓
更新拼团或预售状态
活动支付使用单独的支付流水号,例如:
CMP-用户ID-时间戳
这样可以和普通订单支付区分开。待支付记录暂存在 Redis 中,并设置有效期,避免无效数据长期堆积。
这次调整后,页面点击只能代表“发起支付”,不能代表“支付成功”。最终结果必须以支付宝验签后的回调为准。
五、补充活动成功后的消息提醒
之前秒杀成功或者支付定金后,虽然业务状态发生了变化,但顶部铃铛没有新消息,用户很难确认操作到底有没有成功。
今天把活动模块和站内消息中心连接了起来,目前会自动生成以下消息:
- 秒杀抢购成功;
- 拼团支付成功;
- 预售定金支付成功。
消息中会记录活动结果和对应的跳转地址。例如秒杀成功后可以直接进入购物车,拼团和预售支付成功后可以返回对应的活动详情页。
消息默认是未读状态。用户返回商城页面后,右上角铃铛会显示未读数量,进入消息中心后可以查看具体内容。
支付成功后的处理顺序现在是:
支付宝验签成功
↓
更新活动参与状态
↓
生成站内消息
↓
返回活动详情页
↓
顶部铃铛显示未读数量
六、清理旧版本留下的错误状态
业务逻辑修改完成后,还需要处理旧版本已经写入 Redis 的错误数据。
测试账号之前出现过以下情况:
- 没有付款却显示正在拼团;
- 没有支付定金却显示已付定金;
- 活动参与状态与销量统计不一致。
这次清理了测试账号对应的拼团和预售参与记录,同时检查活动销量。只有确定旧参与记录被删除,并且销量大于零时,才会递减销量,避免出现负数。
这一步虽然不属于新功能,但如果不处理,页面仍然会读取旧数据,看起来就像代码没有生效。
七、页面交互调整
除了后端业务,今天也顺手调整了活动页面的交互。
支付确认页现在会明确展示:
- 本次支付金额;
- 活动价格;
- 拼团所需人数;
- 预售定金和尾款;
- 支付成功后的状态变化;
- 支付宝验签规则。
支付按钮的文字也改成了“前往支付宝沙箱支付”,避免“确认支付”这种容易引起误解的说法。
重复参与秒杀时,错误提示改到了商品卡片内部,不再使用占据整行的全局警告。提示出现后还会自动清理地址栏中的错误参数,刷新页面不会反复弹出同一条提示。
八、测试情况
功能修改完成后,执行了前端模块的完整测试:
go test ./app/frontend/…
测试已经全部通过。
另外还检查了以下内容:
- 拼团支付能够生成支付宝沙箱地址;
- 预售定金支付能够生成支付宝沙箱地址;
- 未支付时不会提前写入参团状态;
- 未支付时不会提前写入已付定金状态;
- 支付页面不再显示微信和银行卡入口;
- 秒杀重复购买提示正常显示;
- 活动错误不再使用顶部全局警告;
- 本地服务和公网穿透地址都能正常访问。
当前项目运行地址:
本地:http://127.0.0.1:8091
公网:https://1b6b8d8e.r3.cpolar.top
总结
今天这部分工作最大的感受是,电商业务不能只看页面有没有跳转成功,更重要的是状态什么时候写入、由谁确认,以及多个模块之间能不能保持一致。
例如“点击参团”并不等于“参团成功”,“跳转收银台”也不等于“支付成功”。如果这些状态没有分清楚,后面接购物车、订单、发货和退款时就会越来越乱。
目前秒杀、拼团和预售定金的主流程已经基本跑通,下一步准备继续处理:
先把每一条业务链路跑顺,再逐步补充更多活动类型,比单纯堆页面更重要。




