2. 医疗支付核心领域建模
医疗支付平台最怕的一件事,是把“钱、单据、机构、人”混成一张大表。一旦混在一起,退费时找不到原支付、对账时对不上明细、结算时算不清医保与自费的分摊。领域建模要解决的,正是把业务中真正独立变化的概念拆成清晰的领域对象,并划出它们各自的边界与协作关系。
一、先识别核心领域对象及其身份
领域对象的第一要素是“身份标识”,即它靠什么被唯一确定。医疗支付场景中,以下六类对象最值得优先建模:
- 参保人(Insured):以参保人ID为身份,关联医保电子凭证、证件号、参保地、险种类型。它是支付与结算的权益主体,不随单次就诊变化。
- 医疗机构(MedicalInstitution):以机构编码为身份,含定点等级、所属医保区划、结算协议、银行账户。它是费用发生地与结算发起方。
- 支付订单(PaymentOrder):以支付单号为身份,记录一次收款的金额、渠道、状态、时间。它是资金动作的最小单元,一次就诊可产生多笔(如医保统筹+个人自费)。
- 结算单(Settlement):以结算单号为身份,描述医保基金与个人之间的费用分摊结果,含统筹支付、个人账户、现金自付等明细。
- 对账单(Reconciliation):以对账批次+机构+账期为身份,是平台与机构或医保之间的账务核对结果,关注“总额是否一致、差异在哪”。
- 退费单(Refund):以退费单号为身份,必须关联原支付订单,记录退款金额、原因、状态,是资金的反向动作。
识别时可用一个判断标准:如果两个概念的生命周期、变更频率、责任方不同,就应拆成不同领域对象。例如支付订单关注“钱有没有到”,结算单关注“钱该谁出”,二者变化原因不同,不能合并。
二、划分领域边界:聚合与限界上下文
识别出对象后,要确定谁和谁必须强一致。支付订单与退费单之间存在“退款不得超过原支付金额”的强约束,适合放在同一聚合,以支付订单为聚合根。结算单与支付订单之间是“先结算、后支付”的协作关系,通过结算单号关联,但不必强一致,可分属不同聚合。
据此可划出四个限界上下文:
- 参保权益上下文:管理参保人、险种、待遇资格,对外提供“该参保人本次可报销比例”查询。
- 支付交易上下文:管理支付订单与退费单,负责资金收付与状态机。
- 医保结算上下文:管理结算单,负责费用分摊计算与结算规则。
- 对账清算上下文:管理对账单,负责账期核对与差异处理。
边界划分的核心是上下文映射:明确谁调用谁、以什么数据契约交互。例如支付交易上下文在收款前,需调用参保权益上下文校验资格;医保结算上下文生成结算单后,向支付交易上下文发出“待支付金额”指令。跨上下文只传标识与必要字段,不共享数据库表。
三、用状态机约束支付订单与退费单
支付订单不是一张静态记录,它有明确的状态流转。建议定义如下状态:CREATED → PAYING → PAID → REFUNDING → REFUNDED,并允许 PAYING → FAILED、PAID → CLOSED(超时未退)。退费单状态为 APPLIED → APPROVED → REFUNDED,其中 APPROVED 前必须校验原支付订单处于 PAID 且可退金额充足。
状态机的价值在于把“能不能退”变成可判断的条件,而不是靠人工记忆。例如某笔支付订单金额 300 元,已退 100 元,则剩余可退 200 元;若新退费单申请 250 元,系统应在 APPROVED 前直接拒绝,并记录拒绝原因。
四、上下文映射的三种典型关系
结合医疗支付实际,上下文之间主要有三种映射关系:
- 客户-供应商:支付交易上下文依赖参保权益上下文提供资格结果。权益方是上游,支付方是下游,接口契约由下游提出。
- 发布-订阅:支付订单支付成功后发布
PaymentPaid事件,对账清算上下文订阅该事件生成对账明细,避免实时强耦合。 - 共享内核:金额、币种、参保人ID等基础类型可在多个上下文共享,但仅限值对象,不共享实体与聚合。
五、一个可落地的建模检查清单
完成建模后,可用以下清单自查,确保边界清晰、协作可执行:
| 检查项 | 判断标准 | 示例 |
|---|---|---|
| 身份是否唯一 | 每个对象有全局唯一标识 | 支付单号、结算单号、退费单号 |
| 聚合边界是否合理 | 强一致约束在同一聚合内 | 退费单与支付订单同聚合 |
| 跨上下文是否只传标识 | 不直接引用对方实体 | 结算单只存支付单号,不存支付对象 |
| 状态是否可判断 | 每个状态有明确进入/退出条件 | PAID 才可发起退费 |
| 事件是否可追溯 | 关键动作有事件记录 | PaymentPaid、RefundCompleted |
领域建模不是一次画完就结束的文档,而是随着业务规则变化持续调整的边界约定。只要坚持“身份唯一、聚合内强一致、上下文间松耦合”三条原则,参保人、机构、支付订单、结算单、对账单、退费单就能各归其位,后续的支付、结算、对账、退费流程才有稳定的结构支撑。