diff --git a/.obsidian/workspace.json b/.obsidian/workspace.json index 412892f..5f9b3ae 100644 --- a/.obsidian/workspace.json +++ b/.obsidian/workspace.json @@ -186,6 +186,10 @@ }, "active": "b06ed69835363258", "lastOpenFiles": [ + "prop-acc/一次性收费/场景-异常-同业户跨社区Pending单.md", + "prop-acc/一次性收费/场景-异常-支付分账失败.md", + "prop-acc/一次性收费/场景-异常-业户重复下单.md", + "prop-acc/一次性收费/场景-异常-微信支付回调延迟.md", "prop-acc/一次性收费/场景-审计-月底现金对账.md", "prop-acc/一次性收费/场景-收据-重打丢失收据.md", "prop-acc/一次性收费/场景-异常-支付完成但实物发不出.md", diff --git a/prop-acc/一次性收费/场景-异常-业户重复下单.md b/prop-acc/一次性收费/场景-异常-业户重复下单.md new file mode 100644 index 0000000..a11900c --- /dev/null +++ b/prop-acc/一次性收费/场景-异常-业户重复下单.md @@ -0,0 +1,163 @@ +--- +title: 场景 - 异常 - 业户重复下单 +tags: + - prop-acc + - 一次性收费 + - 业务场景 + - 异常故障 +audience: + - 业户 + - 业务人员 +status: stable +last_reviewed: 2026-05-25 +code_version: 2026-05-22 +--- + +# 场景:业户重复下单 + +业户在小程序里**同一项目下了多笔订单**,可能是误操作、可能是网络不畅以为没下成功。 + +## 典型情境 + +> [!example] 情境 1:网络卡顿 +> 周三下午,陈先生小程序下单游泳卡 ¥200。点完"下单"按钮后**页面卡了 5 秒没反应**,他不耐烦又点了一次。 +> +> 5 秒后,**系统里有两笔 Pending 订单**。 + +> [!example] 情境 2:误操作 +> 王女士下单后,**手机退到后台又重新打开**,看到一笔"待付款"以为是上次没付的旧单,又点了"重新下单"。 +> +> 实际上系统里**第一笔单还在 Pending**,她又下了第二笔。 + +> [!example] 情境 3:批量场景 +> 装修公司下单 8 张装修证,然后**忘了已经下过**,5 分钟后又下了 8 张。 +> +> 系统里现在有 16 张待付款的装修证 + 16 个 CollectionOrder。 + +## 业户视角 + +### 您看到什么 + +打开小程序"我的订单 → 待付款": + +``` +🟡 待付款 +├── 游泳卡 × 1 ¥200 +│ 下单于 10:05 +│ [立即支付] [取消订单] +│ +└── 游泳卡 × 1 ¥200 ← 重复的! + 下单于 10:05 + [立即支付] [取消订单] +``` + +### 您应该怎么办 + +> [!tip] 简单选择 +> - **只付 1 笔**(选你认为有效的那笔,通常是早的) +> - **取消另 1 笔**(走 [[场景-取消-业户改主意主动撤单]]) +> - 另 1 笔不取消也行,**30 分钟后系统自动作废** + +> [!warning] 千万不要"为了保险都付了" +> 都付了 → 系统记两笔有效订单 → 你被扣两次钱。要退款要联系物业,流程慢。**只付 1 笔 + 取消另 1 笔** 最干净。 + +## 业务人员视角 + +### 业户来问"我下了几个订单不知道是不是都有效" + +``` +1. Filament 后台 → 搜业户姓名 / 手机号 +2. 切到"待付款 (Pending)" tab +3. 看是否有同一项目的多笔 Pending 单 +4. 与业户确认: + ├── 想要 1 笔 → 留 1 笔,作废其余 + └── 全部要 → 不动,让业户每笔单独支付 +5. 作废多余的 Pending 单(走 [[场景-取消-业户改主意主动撤单|主动撤单流程]]) +``` + +### 如果业户已经把多笔都付了 + +``` +1. 确认哪几笔是"真的要"、哪几笔是"重复多余的" +2. 多余的走 [[场景-已收款作废]] + ├── 作废订单 + 收据 + └── 退款(微信 / 现金 / POS) +3. 给业户确认"已退 X 元到您原微信账户" +``` + +## 系统视角:为什么没自动防重? + +> [!info] 系统**故意不防** +> 原因:**有些业务场景就是要重复下单**!例如: +> - 业户买 3 张游泳卡分给家人,**故意拆 3 笔**(便于送人时给收据) +> - 业户买 IC 卡当礼物,要拿 5 张不同收据 +> +> **系统无法判断**"这是误操作的重复" vs "故意拆笔",所以**不做自动拦截**。 + +### 前端小程序的弱防护 + +> [!tip] 建议小程序层做防抖 +> 业户连点 "下单" 按钮,小程序应该: +> - 第一次点击后**禁用按钮 2 秒** +> - 显示 loading,防止重复点 +> - 但不做"15 秒内不允许同样订单"硬性限制(会误伤合理场景) + +## 系统流程 + +```mermaid +sequenceDiagram + participant 业户 + participant 小程序 + participant 系统 + + 业户->>小程序: 第 1 次点"下单" + 小程序->>系统: POST /api/ad-hoc-events + Note over 系统: 网络卡顿,响应延迟 + 系统-->>小程序: ✅ 订单 1 创建 + + 业户->>小程序: 第 2 次点"下单" (误以为第一次没成功) + 小程序->>系统: POST /api/ad-hoc-events + 系统-->>小程序: ✅ 订单 2 创建 + + Note over 业户: 业户切到"我的订单" + + 业户->>小程序: 看到 2 笔 Pending + 业户->>业户: 困惑 + + Note over 业户: 推荐:取消 1 笔 + + 业户->>小程序: 取消订单 2 + 小程序->>系统: DELETE /api/ad-hoc-events/{order-2} + 系统->>系统: VoidAdHocEventAction + 业户->>小程序: 支付订单 1 + 小程序->>系统: 完成订单 1 +``` + +## 常见问题 + +> [!question] 系统能不能做"30 秒内不允许同一业户下同样订单"? +> 技术上可以加。但会误伤"故意拆笔"的场景(业户为家人买、要多张收据)。**当前选择不做硬限制**,靠 UI 弱防护(按钮防抖)+ 业务人员人工处理已经够。 + +> [!question] 一个业户最多能有多少笔 Pending 单? +> **无上限**。但**单超过 100 笔的业户**会触发反爬虫(虽然当前没装) —— 这种通常是 API 误用 / 攻击场景,与正常业户无关。 + +> [!question] 业户重复下单影响库存吗? +> 当前**系统不管物理库存**(IC 卡库存盒、装修证存货数)。库存管理是物业内部独立流程。重复下单只是**数据库里多了几笔记录**,实物没消耗。 + +> [!question] 业户付了 2 笔重复订单,2 笔都生成了收据,财务对账时会发现吗? +> 会发现 —— 月底对账时,**同一业户同一时段 2 笔同样金额** 会引起注意。建议: +> - 业务人员主动联系业户确认 +> - 不论是否重复都按收据数对账 +> - **物业可以发起退款**(走 [[场景-已收款作废]] 作废其中 1 笔) + +## 相关概念 + +- [[概念-AdHocEvent状态机]] — 每笔订单独立的状态 +- [[场景-取消-业户改主意主动撤单]] — 撤销多余订单 +- [[场景-已收款作废]] — 已付款的多余订单怎么退 +- [[场景-超时未付自动作废]] — 未付款的多余订单会自动废 + +## 异常分支 + +- 全部都付了 → [[场景-已收款作废]] 退多余的 +- 业户坚持要全部 → 系统照单处理,留每笔独立收据 diff --git a/prop-acc/一次性收费/场景-异常-同业户跨社区Pending单.md b/prop-acc/一次性收费/场景-异常-同业户跨社区Pending单.md new file mode 100644 index 0000000..f62d69f --- /dev/null +++ b/prop-acc/一次性收费/场景-异常-同业户跨社区Pending单.md @@ -0,0 +1,177 @@ +--- +title: 场景 - 异常 - 同业户跨社区 Pending 单 +tags: + - prop-acc + - 一次性收费 + - 业务场景 + - 异常故障 +audience: + - 业务人员 +status: stable +last_reviewed: 2026-05-25 +code_version: 2026-05-22 +--- + +# 场景:同业户跨社区 Pending 单 + +业户在**多个社区**(物业项目)都有房子,小程序里能下单**任一社区**的一次性收费。可能产生跨社区的待付单 + 跨渠道补缴的复杂场景。 + +> [!info] 不算 bug,但需要业务人员理解 +> 本系统天然按**社区(community_id)隔离数据**。但同一个业户在多社区有不同房子时,他/她的订单分布在不同社区的数据空间。 + +## 典型情境 + +> [!example] 真实情境 +> 周先生是连锁老板,**北京有住宅、上海有公寓**,两个小区都是同一物业公司"鸿基物业"管理。 +> +> 一个周末他在北京住宅的小程序下单 IC 卡 ¥30(没付),又在上海公寓的小程序下单装修证 ¥150(没付)。 +> +> 第二天他到**北京物业前台**问"我下了什么订单都还没付的?",职员只能查到**北京小区**的 1 笔。 + +## 业务人员视角 + +### 关键约束:**Filament 默认只显示当前社区** + +``` +登录 Filament → 切换社区(顶栏选择器) +├── 北京小区 → 看到周先生的 IC 卡订单 +├── 上海小区 → 看到周先生的装修证订单 +└── 切换社区 → 看不到另一社区的订单 +``` + +### 如何帮业户查全部跨社区订单 + +**步骤 1:理论上的全局视角** + +```sql +-- 数据库查询(超级管理员视角) +SELECT + ahe.id, + ahe.community_id, + c.name AS 社区名, + rp.name AS 项目, + ahe.amount, + ahe.status, + ahe.created_at +FROM acc_ad_hoc_events ahe +JOIN community_communities c ON ahe.community_id = c.id +JOIN acc_rate_plans rp ON ahe.rate_plan_id = rp.id +WHERE ahe.community_user_profile_id = ( + SELECT id FROM community_community_user_profiles + WHERE user_id = (SELECT id FROM users WHERE phone = '13800138000') +) + AND ahe.status = 'pending'; +``` + +**步骤 2:实际操作** + +> [!warning] 普通业务人员通常无法跨社区查询 +> 物业前台员工只能登录自己负责的社区。**跨社区查询需要总部管理员**。 +> +> 业务流程上的应急方案: +> - 业户在哪个社区前台,就办哪个社区的订单 +> - 让业户**自己去另一个社区的小程序入口**查另一笔订单 +> - 集团总部如有需要可以**总部协调跨社区客服** + +### 数据隔离的好处和代价 + +> [!success] 好处:数据干净 +> - 北京小区的财务对账只看北京数据 +> - 上海小区的财务对账只看上海数据 +> - 互不影响 = 各社区独立运营 + +> [!warning] 代价:跨社区业户体验差 +> - 跨社区业户感受不到"统一" +> - 前台无法跨社区帮业户查订单 +> - 需要业户**自己记得在哪个社区下了什么单** + +## 数据库设计的隔离机制 + +```mermaid +graph TD + A[全国业户档案
users 表] -->|user_id| B[业户在北京
CUP id=100] + A -->|user_id| C[业户在上海
CUP id=200] + + B -->|community_user_profile_id| D[北京 IC 卡订单
community_id=1] + C -->|community_user_profile_id| E[上海 装修证订单
community_id=2] + + F[北京前台
登录到 community_id=1] -.->|看不到| E + G[上海前台
登录到 community_id=2] -.->|看不到| D + + classDef user fill:#fef3c7 + classDef profile fill:#dbeafe + classDef order fill:#dcfce7 + classDef frontdesk fill:#fee2e2 + + class A user + class B,C profile + class D,E order + class F,G frontdesk +``` + +## 系统流程 + +```mermaid +sequenceDiagram + participant 业户 + participant 北京小程序 + participant 北京前台 + participant 上海小程序 + participant 上海前台 + participant 系统 + + 业户->>北京小程序: 下单 IC 卡 + 北京小程序->>系统: 建 Pending 单 (community_id=1) + 业户->>上海小程序: 下单装修证 + 上海小程序->>系统: 建 Pending 单 (community_id=2) + + Note over 业户: 第二天到北京前台 + + 业户->>北京前台: 我的所有待付单是? + 北京前台->>系统: 查 community_id=1 + 系统-->>北京前台: 只返回北京 IC 卡单 + 北京前台-->>业户: 您有 1 笔待付:IC 卡 + + Note over 业户: 业户困惑:"我记得还有一笔啊" + + 业户->>业户: 想起来 → 去上海小程序查 + 业户->>上海小程序: 查我的订单 + 上海小程序-->>业户: 找到上海装修证单 +``` + +## 常见问题 + +> [!question] 业户能在北京小程序里看到上海订单吗? +> **不能**。小程序默认按当前社区隔离。业户切换社区才能看另一社区的订单。 + +> [!question] 如果是集团连锁物业,有"统一业户视图"吗? +> 当前**没有**。如果业务方明确需要,可以挂 TODO 做一个"业户中心"页面,跨社区聚合该业户的所有订单。**优先级看实际需求**。 + +> [!question] 跨社区补缴可以吗? +> **不能**。北京 Pending 单**只能在北京前台**用现金补缴。上海前台搜不到这笔订单。 + +> [!question] 业户回家发现两笔都到期了,怎么办? +> 两笔都自动作废,业户**重新在对应社区下单**即可。详见 [[场景-超时未付自动作废]]。 + +> [!question] 同一业户在 5 个社区都有房,管理上会乱吗? +> 业户需要**自己管理**(记录每个社区的房号、订单)。这是"多社区业户"的固有复杂性,不只是本系统的问题 —— 物业管理本质如此。 + +## 跨社区业户的常见需求与方案 + +| 需求 | 当前方案 | 长期方案 | +|---|---|---| +| 跨社区查所有订单 | 业户自己切社区查 | 业户中心(挂 TODO)| +| 跨社区合并支付 | 不支持 | 支付聚合(技术复杂,挂 TODO)| +| 跨社区合并发票 | 不支持(发票本来就独立)| 发票合并(财务侧支持)| +| 跨社区免重复绑定 | 系统已支持(同 user_id 自动关联)| 已实现 ✅ | + +## 相关概念 + +- [[概念-CollectionOrder与Receipt]] — 每笔订单绑定 community_id +- [[场景-跨渠道补缴]] — 同社区内的跨渠道场景 +- [[场景-超时未付自动作废]] — Pending 单的统一生命周期 + +## 异常分支 + +- 业户记不清在哪个社区下的单 → 集团总部协助查询 +- 业户希望取消所有未付单 → 在各社区小程序逐一取消 diff --git a/prop-acc/一次性收费/场景-异常-微信支付回调延迟.md b/prop-acc/一次性收费/场景-异常-微信支付回调延迟.md new file mode 100644 index 0000000..174d9a1 --- /dev/null +++ b/prop-acc/一次性收费/场景-异常-微信支付回调延迟.md @@ -0,0 +1,192 @@ +--- +title: 场景 - 异常 - 微信支付回调延迟 +tags: + - prop-acc + - 一次性收费 + - 业务场景 + - 异常故障 +audience: + - 业户 + - 业务人员 +status: stable +last_reviewed: 2026-05-25 +code_version: 2026-05-22 +--- + +# 场景:微信支付回调延迟 + +业户**在微信里付款成功**,但**系统订单还停在 Pending 状态**。等几分钟才更新,业户和业务人员都可能误以为出问题了。 + +## 典型情境 + +> [!example] 真实情境 +> 周日晚上李太太在小程序下单充电桩电费 ¥200,微信支付成功 —— 微信弹窗"已付款"、扣款记录里也看到了。 +> +> 但她切回小程序"我的订单",订单状态还是"待付款"。等了 1 分钟没变化,她以为没成功,**又点了一次"立即支付"**。 +> +> 微信弹"您已支付过该订单,无需重复支付",这才放心。3 分钟后小程序终于刷新为"已完成"。 + +## 为什么会延迟? + +> [!info] 微信回调链路 +> 业户支付 → 微信服务器 → 物业服务器 webhook → 系统更新订单状态。 +> +> 任何一步**网络慢、服务器忙、回调队列堆积**,都可能让"系统知道你付款了"晚几秒到几分钟。**99% 的回调在 10 秒内到达**,**1% 可能要 30 秒~5 分钟**,极少数(0.01%)**完全丢失**。 + +## 业户视角 + +### 您可能看到的几种状态 + +| 时间 | 微信侧 | 小程序订单状态 | 您的感觉 | +|---|---|---|---| +| 0-3 秒 | 支付完成 | 仍然显示"待付款" | 正常,刷新一下 | +| 3-30 秒 | 支付完成 | 已变"已完成" | 完美 | +| 30 秒-5 分钟 | 支付完成 | 仍然"待付款" | 怀疑没成功 | +| > 5 分钟 | 支付完成 | 一直"待付款" | 真的有问题 | + +### 您应该怎么办 + +> [!warning] 不要重复支付! +> 微信有重复支付防护(同一订单只能付一次),但万一系统出问题,**重复支付的钱可能很难退**。 + +**正确步骤**: + +1. 看微信"账单 / 钱包"里是否有这笔扣款记录 + - ✅ 有 → **钱已经付了**,不要再付 + - ❌ 无 → 钱没出去,可以放心重新支付 + +2. 钱已付但小程序不更新: + - 等 5 分钟 + - 下拉刷新小程序订单页 + - 还不更新 → 联系物业前台 + +3. 联系物业前台: + - 告诉他们订单号 + 微信扣款截图 + - 物业能在 Filament 后台**手动核实并标记完成** + +### 别担心,钱不会丢 + +> [!success] 双向保障 +> - 微信侧:确认扣款,有微信账单为证 +> - 物业侧:即使回调彻底丢失,微信商户后台**能看到这笔交易**,物业人工核对后手动入账 + +## 业务人员视角 + +### 业户来问"我付了但显示没付"怎么处理? + +``` +1. 让业户出示微信扣款记录(截图 / 商家订单号) + +2. Filament 后台搜业户订单号(CO-xxx) + ├── 状态显示 Pending → 回调真的没到 + └── 状态已是 Completed → 回调刚到,提示业户刷新页面 + +3. 状态 Pending 且业户确认已付: + ├── 在微信商户后台查这笔交易 + │ └── 找到 transaction_id (微信侧订单号) + ├── 与系统 CO-xxx 的 order_no 核对 + └── 如确认是同一笔:手动标记完成 +``` + +### 手动标记完成 + +> [!warning] 当前 UI 没有直接的"标记完成"按钮 +> 当前只能通过 `MarkAdHocEventPaidAction` 业务方法调用。临时方案: +> - 走 Tinker:`app(MarkAdHocEventPaidAction::class)->handle($event, [...])` +> - 或者在 Filament 后台为业户**重新建一笔**(走 A 流即收即付),把原 Pending 单走作废 +> +> 长期方案:**给 ViewAdHocEvent 加一个"手动标记已付款"Action**,挂 TODO。 + +### 后台技术细节 + +```mermaid +sequenceDiagram + participant 业户 + participant 微信 + participant 微信服务器 + participant 物业 webhook + participant 系统 + participant 业务人员 + + 业户->>微信: 付款 ¥200 + 微信->>业户: 弹窗"已付款" + 微信->>微信服务器: 入账 + + Note over 微信服务器: 网络/服务器繁忙 + + 微信服务器-->>物业 webhook: ⏳ 延迟 30s ~ 5min ⏳ + + Note over 业户: 业户看小程序仍显示待付款 + + 业户->>业务人员: 询问"我付了为什么还是待付款" + 业务人员->>微信商户后台: 查 transaction_id + 业务人员->>系统: 手动 MarkAsPaid + 系统->>系统: CollectionOrder + AdHocEvent → Completed + 系统-->>业户: 推通知"已付款" + + Note over 微信服务器: 几分钟后,延迟回调终于到了 + 微信服务器->>物业 webhook: 现在才到 + 物业 webhook->>系统: 检查订单已 Completed → 跳过 (幂等) +``` + +## 几个关键设计决策 + +### 1. 回调幂等 + +> [!info] 系统设计 +> webhook 处理时**先查订单状态**: +> - 若是 Pending → 走 MarkAdHocEventPaidAction 完成流程 +> - 若已是 Completed → 直接返回成功,不做任何事 +> - 若是 Voided → 退回退款流程(钱原路退回业户) +> +> 这样**不论回调到达多少次**,系统都保持一致状态。 + +### 2. 业户重复支付的处理 + +如果业户没看到状态更新而**重复点了"立即支付"**: +- 微信端会拦截(同一订单只能付一次) +- 系统侧**不会收到第二笔扣款** + +但万一某些渠道允许重复支付(罕见): +- 系统会收到**两笔 transaction_id 不同的回调** +- 第一笔正常处理 → 翻 Completed +- 第二笔到达时 → 系统发现订单已 Completed,**直接对第二笔发起原路退款** + +### 3. 超时 vs 回调延迟的竞争 + +> [!warning] 一个微妙的边界情况 +> 业户付款的瞬间正好是订单 expires_at,超时 job 同时跑: +> +> - 超时 job 拿到锁先把订单 → Voided +> - 微信回调晚 1 秒到 → 看到 Voided,触发**原路退款**(钱退回业户) +> +> 业户此时看到"扣款 + 几小时后退款"。这是正常容错行为,不是 bug。 + +## 常见问题 + +> [!question] 业户已经离开了,但延迟回调到了,会怎样? +> 系统正常翻 Completed,生成 Receipt。业户**下次打开小程序**就能看到状态更新和收据。无需联系物业。 + +> [!question] 5 分钟还没到回调,但业户急着要 IC 卡怎么办? +> 走业务人员的"手动标记完成"路径(见上)。**信任微信侧扣款记录优先**。 + +> [!question] 同一笔订单回调收到 2 次怎么办? +> 幂等设计 → 第二次直接返回成功。详见上述设计决策 1。 + +> [!question] 物业怎么知道是不是真的"回调丢了"? +> 监控 + 报警: +> - 每天对账微信商户后台 vs 系统订单总数 +> - 差额 > 阈值(比如 5 笔)发警报 +> - 人工补单(查商户后台 → 手动标记) + +## 相关概念 + +- [[概念-CollectionOrder与Receipt]] — Pending → Completed 流转 +- [[概念-AdHocEvent状态机]] +- [[场景-B流-小程序下单+微信支付]] — 正向流程 +- [[场景-超时未付自动作废]] — 时间竞争场景 + +## 异常分支 + +- 业户付了款但物业拒绝处理 → 走 [[场景-已收款作废]] 退款给业户 +- 回调收到但金额对不上 → 数据问题,技术介入 diff --git a/prop-acc/一次性收费/场景-异常-支付分账失败.md b/prop-acc/一次性收费/场景-异常-支付分账失败.md new file mode 100644 index 0000000..eabfdcf --- /dev/null +++ b/prop-acc/一次性收费/场景-异常-支付分账失败.md @@ -0,0 +1,134 @@ +--- +title: 场景 - 异常 - 支付分账失败 +tags: + - prop-acc + - 一次性收费 + - 业务场景 + - 异常故障 +audience: + - 业务人员 +status: draft +last_reviewed: 2026-05-25 +code_version: 2026-05-22 +--- + +# 场景:支付分账失败 + +业户付款成功,但**物业商户号到结算账户的分账失败**。属于支付平台异常,本系统侧只能等通知 + 人工干预。 + +> [!warning] 进阶场景,本系统弱介入 +> 分账是**微信/支付宝商户后台**的功能,本系统侧基本看不到这一步。本文档仅作为应急参考。 + +## 什么是"分账"? + +> [!info] 一图看懂 +> ``` +> 业户付款 → 微信支付收钱 → 微信商户号(物业)→ 分账到物业银行账户 +> ✅ 这一步是支付 ✅ 这一步是分账(本场景关心) +> ``` +> +> 大多数小型物业**不需要分账**(钱直接从微信结算到对公账户)。**需要分账的场景**: +> - 物业方 + 物业服务集团 + 项目方三家**按比例分钱** +> - 上市物业集团 + 全国各分公司**按地域分账** +> - 委托管理模式(开发商 vs 物业公司 二八分) + +## 典型情境 + +> [!example] 真实情境 +> 鸿基物业管理集团旗下小区,业户用小程序付了 ¥3000 装修押金。 +> +> 微信支付成功 → 钱进鸿基物业商户号。商户号配置了分账规则: +> - 70% 给小区项目方 +> - 30% 给鸿基集团运营费 +> +> 第二天集团财务发现:小区项目方收到 ¥2100 ✅,**集团运营费 ¥900 没有收到** ❌。 + +## 业务人员视角 + +### 这种问题怎么发现? + +业务人员**不会主动发现** —— 通常是: +- 集团财务月底对账 → 发现少了一部分 +- 微信商户后台**邮件通知**"分账失败" + +> [!warning] 关键 +> 系统侧的 `CollectionOrder` **状态依然是 Completed** —— 因为业户支付的钱**确实进了商户号**,只是后续分账失败。系统层面无错。 + +### 处理流程 + +``` +1. 登录微信支付商户后台 → 分账记录 +2. 找到失败的分账记录,看失败原因: + ├── 接收方账户冻结 + ├── 分账方金额不足(剩余金额已分完) + └── 接收方未签约接收能力 +3. 联系微信客服 / 修复配置 +4. 重试分账 (通常 30 天内可重试) +``` + +### 本系统侧需要做什么? + +**几乎不用** —— 本系统已经"收到了钱"(从业户视角钱付完了)。分账是物业内部账务问题。 + +> [!info] 但如果分账失败导致需要"全单退款给业户": +> - 业务人员走 [[场景-已收款作废]] 标记订单作废 +> - 微信商户后台**手动发起退款**给业户 +> - 业户拿回钱,后续物业再处理内部账务 + +## 系统流程 + +```mermaid +sequenceDiagram + participant 业户 + participant 微信支付 + participant 物业商户号 + participant 项目方账户 + participant 集团账户 + participant 系统 + + 业户->>微信支付: 付款 ¥3000 + 微信支付->>物业商户号: ¥3000 入账 + 微信支付->>系统: webhook → MarkAsPaid + 系统-->>业户: 订单 Completed,收据生成 + + Note over 业户,系统: 业户视角:一切正常 + + Note over 物业商户号: 系统自动触发分账 + 物业商户号->>项目方账户: 分账 ¥2100 ✅ + 物业商户号->>集团账户: 分账 ¥900 ❌ (接收方账户冻结) + + Note over 业务人员: 第二天集团对账才发现 +``` + +## 常见问题 + +> [!question] 业户会感知到分账失败吗? +> 不会。从业户视角,**钱付完订单完成**,完美无瑕。 + +> [!question] 财务多久能发现? +> 取决于对账频率。建议物业**至少每周对一次分账记录**,而不是等月底。 + +> [!question] 系统能监控分账状态吗? +> 当前**没有集成**。可以挂 TODO: +> - 微信商户号开放分账状态查询 API +> - 系统每天定时查最近 7 天的分账状态 +> - 失败的发警报到物业财务 + +> [!question] 分账失败 30 天没解决,钱会怎样? +> 微信会**原路退回给业户**(钱回到业户原微信)。这种情况业户会突然收到一笔退款,**联系不上业户解释** = 麻烦。所以**分账失败 30 天前必须处理**。 + +## 简化场景:不需要分账的物业 + +> [!success] 大多数小型物业:跳过本场景 +> 单一物业公司,微信商户号直绑对公账户,**无需分账配置**。本场景对你们不适用。 + +## 相关概念 + +- [[概念-CollectionOrder与Receipt]] — 系统侧"收钱"的语义边界 +- [[场景-B流-小程序下单+微信支付]] — 业户付款正向流程 +- [[场景-审计-月底现金对账]] — 多渠道对账 + +## 待补 + +- **系统集成分账状态监控**:挂 TODO,等真正出现分账失败客诉再做 +- **多商户/多账户场景的会计科目对接**:超出一次性收费模块范围,与凭证模块相关(待补)