--- title: prop-acc · 场景 - 超时未付自动作废 aliases: - 场景 - 超时未付自动作废 - 场景-超时未付自动作废 tags: - 场景 - prop-acc - 一次性收费 - 业务场景 - 取消退款 audience: - 业户 - 业务人员 status: 已发布 last_review: 2026-05-25 code_version: 2026-05-22 --- # 场景:超时未付自动作废 业户在小程序下单后**没有及时付款**,系统在订单到期后**自动作废**。 > [!warning] 实现状态 > 后端 `VoidAdHocEventAction` 已就绪。**自动扫描 scheduled job 尚未实现**(预定与 payment-gateway webhook 同期上线)。本场景描述上线后体验。 ## 典型情境 > [!example] 真实情境 > 周三下午,陈先生在小程序上下单一张游泳卡 ¥200。下单完接了个电话,把这事忘了。 > > 30 分钟后他想起来,打开小程序"我的订单",订单已经变成 "已作废"。原因栏写着:**[订单超时作废] expires_at 已过**。 ## 业户视角 ### 您看到什么 下单后超时未付,小程序"我的订单"里: ``` 游泳卡(月卡) 订单号:CO-20260525-XXX 金额:¥200 状态:❌ 已作废 作废原因:订单超时未付款 ``` > [!info] 不影响后续 > 您可以**立即重新下一单**。新订单按当前价格冻结(如果项目涨价了,以新价为准)。 ### 为什么要超时? > [!tip] 业户视角:为什么超时设计? > 假设您下单不付款占着这个金额很久,后台一直把项目库存(比如装修证只有 100 张)留给您 —— 不公平。**超时机制让资源可循环**。 ## 业务人员视角 ### 业务人员一般不需要管 > [!success] 完全自动化 > Scheduled job 每隔一段时间(比如每小时)扫描全表,自动处理超时单。**前台不用做任何事**。 ### 业务人员能看到什么 每个超时作废的订单在 Filament 后台: - 状态:`Voided` - meta 字段记录:`voided_at` / `voided_reason: "[订单超时作废]"` / `voided_by: null`(系统自动,无操作员) ### 如果业户来问"我的订单怎么没了" ``` 1. 在 Filament 后台搜业户姓名 / 订单号 2. 找到 Voided 记录 3. 告诉业户:"您的订单在 X 月 X 日下午 X 点超时作废了,原因是没在 30 分钟内完成支付。请重新下单。" ``` ## 系统流程 ```mermaid sequenceDiagram participant 业户 participant 小程序 participant 系统 participant Scheduled Job 业户->>小程序: 下单游泳卡 ¥200 小程序->>系统: CreatePendingAdHocEventAction 系统->>系统: 建 AdHocEvent + CO,expires_at = now + 30min 系统-->>业户: 返订单号,等待支付 Note over 业户: 业户忘了付钱 Note over Scheduled Job: 每小时扫描一次 Scheduled Job->>系统: 查询 CO where status=pending AND expires_at < now() 系统-->>Scheduled Job: 返回所有超时 Pending 单 loop 对每个超时单 Scheduled Job->>系统: VoidAdHocEventAction 系统->>系统: 级联废 AdHocEvent + CO 系统->>系统: 写 meta.voided_reason = "[订单超时作废]" end 业户->>小程序: 想起来要付钱 小程序->>系统: 查询订单 系统-->>小程序: 状态 Voided 小程序-->>业户: 显示"订单已作废,请重新下单" ``` ## 几个常见超时周期(可配置) | 项目类型 | 推荐超时 | 理由 | |---|---|---| | **泳票 / 充电桩** | 30 分钟 | 业户高频下完即付 | | **IC 卡** | 2 小时 | 业户可能要查档案、对房号 | | **装修证(单张)** | 1 天 | 装修公司可能要走内部审批 | | **装修证(批量)** | 7 天 | 大公司付款流程长 | > [!warning] 跨渠道补缴场景请用长 expires_at > 跨渠道补缴([[场景-跨渠道补缴]])时,儿女线上下单、老人现场付款 —— 中间可能隔几天。**这种场景建议 expires_at 设 7 天**,避免老人到前台时单子已废。具体配置看每个 RatePlan 的设置。 ## 常见问题 > [!question] 我的订单超时了能恢复吗? > **不能**。超时作废是终态。直接重新下单。 > [!question] 重新下单价格会不会涨? > **可能**。系统按下单**当时的价格冻结**;如果上次下单到现在物业调价了,新订单按新价。 > [!question] 我付款的瞬间订单刚好超时,会重复扣款吗? > **不会**。系统在 `MarkAdHocEventPaidAction` 内部有事务保护:如果订单已被作废,支付回调会失败,微信会原路退回。 > [!question] 物业前台能"延长有效期"吗? > 当前**不支持**。要延长只能业户自己重新下单。是否要支持手动延长是个业务决策,等业务方反馈再加。 ## 系统配置(技术细节,业务人员可跳过) - 扫描 job 在 `app/Console/Kernel.php` 注册,每小时跑一次 - 查询语句:`SELECT * FROM acc_collection_orders WHERE status='pending' AND expires_at < NOW()` - 调用 `VoidAdHocEventAction::handle($event, '[订单超时作废] expires_at < now()')` ## 相关概念 - [[概念-AdHocEvent状态机]] — Pending → Voided 流转 - [[概念-CollectionOrder与Receipt]] — `expires_at` 字段挂在 CollectionOrder 上的设计原因 - [[场景-B流-小程序下单+微信支付]] — 业户下单的正向流程 - [[场景-跨渠道补缴]] — 长 expires_at 的典型用例