awesome-gpt-image-2退款流程设计:全额退款与积分预扣机制详解
【免费下载链接】awesome-gpt-image-2Prompt as Code | GPT-Image2 工业级提示词引擎与模板库,530+ 个案例逆向工程,20+ 套工业级模板,并提炼出Skills,持续更新中项目地址: https://gitcode.com/GitHub_Trending/awe/awesome-gpt-image-2
awesome-gpt-image-2是一个 GPT-Image2 工业级提示词引擎与模板库(530+ 案例、20+ 套模板)。除了生成图片,它还是一套完整的付费应用:积分用于生成、¥9.90 购买付费交流群资格。本文带你读懂它的退款流程与积分预扣机制——为什么生成失败会自动退积分?¥9.90 的全额退款是如何做到资金安全、幂等且不重不漏的?
两大退款场景:先看全貌
项目中的"退款"分两类,机制完全不同:
| 场景 | 退的是什么 | 触发方式 | 结果 |
|---|---|---|---|
| 图片生成失败 | 已预扣的 1 个积分 | 系统自动 | 秒级自动退回 |
| 付费交流群 | ¥9.90 全额现金 | 人工审核 + 支付宝退款 | 原路全额退回 |
积分流水在数据库中明确区分类型,purchase、refund、generation各有独立记录(见 202605090001_user_credits.sql 中的credit_transactions表),任何一笔积分变动都可追溯。
积分预扣机制:先扣后用,失败即退
生成图片走的是经典的"预扣(Reservation)→ 成功确认 / 失败释放"三段式流程,源码在 reserve_generation_usage:
- 预扣阶段:调用
reserve_generation_usage数据库函数,先对用户的 profile 行加锁(for update),判断用免费额度还是扣 1 个积分,同时写入一条generation类型的扣减流水。此时积分"冻结"掉了。 - 成功阶段:图片生成成功后调用
complete_generation_reservation,把预扣记录标记为succeeded。 - 失败阶段:一旦上游生成报错(含限流 429),调用
release_generation_reservation,积分原路加回,并写入一条type = 'refund'、source = 'generation_failed'的退款流水。
这个设计的两个好处:
- 超卖防护:行级锁保证并发请求下积分不会被扣成负数;余额不足会抛出
CREDITS_REQUIRED,接口返回 402(见 generate-image.js)。 - 失败必退:释放函数本身也是幂等的——只对
pending状态的预扣生效,重复调用不会产生重复退款。
也就是说,积分层面的退款完全自动化:用户不用申请,生成失败积分立即回到账户,流水留痕可查。
全额退款流程:¥9.90 如何安全退回
付费交流群是一次性 ¥9.90(990 分,数据库层面硬约束amount_cents = 990,见 20260722090000_paid_community.sql)购买长期资格,涉及真实资金,退款链路明显更重。
第一步:稳定退款请求号,保证幂等
退款入口是管理员接口 refund.js。核心动作是prepare_community_refund(SQL 实现):
- 只有
PAID状态的订单可退,已REFUNDED的订单直接返回"已退",天然幂等; - 为每笔订单生成固定的退款请求号(
refund_request_no)并入库,重复请求同一请求号不会发起第二笔退款; - 订单同时标记
refund_status = PROCESSING。
💡 退款请求号是支付宝
out_request_no参数,这是整条链路"不重复退款"的基石。
第二步:调用支付宝原路全额退款
确认准备完成后,接口以order.amount_cents(即全额)调用alipay.trade.refund:
refund_amount= 订单全额(分);fund_change = 'Y'表示资金当场变动,直接走第三步"落定";- 资金未立即变动则保持
PROCESSING,等待查询确认。
第三步:查询落定 + 四重校验
管理员可通过 refund-query.js 查询退款结果,且内置了10 秒冷却(防频繁查单)。落定前做四重一致性校验:out_trade_no、out_request_no、支付宝交易号、退款金额必须与订单完全匹配,任一不符即抛出COMMUNITY_REFUND_RESULT_MISMATCH拒绝落库。
校验通过后调用finalize_community_refund(SQL 实现),订单进入终态REFUNDED。
资格状态机:退款中不断群,退款后失效
状态设计很讲究(见 paid-community.md):
PENDING → PAID → REFUNDED ↘ CLOSED / REVOKED- 退款处理中(PROCESSING):订单仍是
PAID,用户资格保留——避免"钱还没退、人先被踢"的体验问题; - 退款成功后(REFUNDED):群二维码接口 qr.js 判定资格失效,返回 403;
- 撤销(REVOKED)≠ 退款:人工撤销资格不会自动退钱,文档明确要求"需要退款时使用退款流程,不用撤销代替退款",两条路径互不混淆。
Stripe 订阅:另一种"退款"思路
积分包与会员走 Stripe(见 billing.js 与 webhook.js)。订阅制不做"自动退款",而是通过 portal.js 生成Billing Portal链接,让用户在 Stripe 官方页面自助管理/取消订阅;Webhook 端以invoice.payment_succeeded、subscription.updated等事件驱动积分发放,且用"已存在同 metadata 流水则跳过"(hasTransactionWithMetadata)保证事件重复推送不会重复发积分。
设计要点总结
- 自动退款靠幂等函数:积分释放函数只对
pending预扣生效,重复调用无副作用。 - 现金退款靠固定请求号:
refund_request_no唯一索引 + 支付宝out_request_no,双重防重。 - 落库前四重校验:订单号、请求号、交易号、金额全部核对,防止串单。
- 状态机分离处理:
PROCESSING期间资格保留,REFUNDED终态才收回访问权。 - 全链路留痕:积分流水、支付宝通知事件表(
community_alipay_notify_events)逐笔存档。
对新手来说,这套"预扣 + 失败释放 + 幂等终态"的模式,是构建任何积分/支付系统的优秀模板,建议直接参考 supabase/migrations/ 下的迁移文件源码学习。
【免费下载链接】awesome-gpt-image-2Prompt as Code | GPT-Image2 工业级提示词引擎与模板库,530+ 个案例逆向工程,20+ 套工业级模板,并提炼出Skills,持续更新中项目地址: https://gitcode.com/GitHub_Trending/awe/awesome-gpt-image-2
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考