yeg
2 天以前 3773bc4f2d966fb248f96c7e5cedce58c91df689
CONTEXT.md
@@ -1,3 +1,130 @@
# 项目领域上下文
(按需补充。)
## 资金流
支付成功时钱不会直接进商户账户:商户开通了延迟入账,先付钱后核销的订单资金进入斗拱的**延迟户**
(官方定义:不可结算、不可取现),核销成功后才调用**交易确认**把资金分账到商户**基本户**,
再由斗拱按 **D1 结算周期自动结算到商户绑定的结算银行卡**。
支付即核销的到店消费订单不走延迟,支付成功即分账给商户。
## 支付尝试与预支付单
**预支付单**:向通道发起一次支付请求后,通道侧生成的一张**可被付款的凭证**——人才端拉起微信收银台就是凭它。
它有有效期,过期即不能再付;未过期的预支付单可以被反复拉起收银台。
_Avoid_: 预订单、支付单(会与本地订单混同)
**支付尝试**:一笔订单向通道发起的一次支付请求。一笔订单可以有多次支付尝试,但**同一时刻最多只有一张活着的预支付单**:
先复用已有的,复用不了先关单,都走不通才新建;否则同一笔订单可能被付两次。
_Avoid_: 支付流水(那是记账视角,不是业务含义)
**关单**:把一张未付款的预支付单在通道侧作废。它是「这张单子还能不能被付款」的**唯一**判定手段——
本地把流水标成已关闭不算数,用户手上的预支付单照样能付进来。关单回执说原交易已经成功,就说明钱已经被收下。
_Avoid_: 取消、关闭订单(那些是订单的事,不是预支付单的事)
**支付结果不确定**:本地问不出「这笔钱到底有没有收下」的状态——通道答「处理中」、查询本身失败、
或通道说成功而本地规则核对不上,都算。它描述的是**一次支付尝试**的悬而未决,不是整笔订单的状态。
_Avoid_: 支付中、支付确认中(听起来像有进度,实际是没结论)
**关单中**:一次支付尝试已经叫了关单,但通道只回「处理中」,于是「这张预支付单还能不能付款」暂时没有结论。
它必须能被重试到有结论为止,期间不能当成「已经关掉」。
_Avoid_: 取消失败
**关单查询**:向通道追问一次已发出的关单**有没有生效**的独立接口。关单是异步的,关单接口返回不代表关掉了,
所以「关单中」的结论只能由它给出:问出来已关闭才算 `CLOSED`,通道明确说这次关单没生效才算 `CANCEL_UNCONFIRMED`。
它是关单在查询侧的对等物——没有它,关单就成了一个只发不问、永远收不了尾的动作。
_Avoid_: 查单(那是查支付,不是查关单)
**悬账**:通道确认收到、但本地订单已经取消或关闭的钱。它必须要么自动退回付款人,要么有一条明确的人工兜底,
不能只留在对账页上等人看见。
**差错台账**:把「本地状态与通道不一致、且不能自动收敛」的每一笔记下来等人工处理的地方,
每条有自己的类型、状态与唯一标识,允许重复出现(同一条能被结掉又再开出)。它不是给运营看的报表,
而是**程序化出口走不通时的唯一去处**——记进去就说明这件事必须有人管。
_Avoid_: 对账问题列表、异常流水(听起来像展示页面,实际是待办)
## 延迟入账与交易确认
商户进件时即配好延迟入账能力(`delay_flag=Y`、`forced_delay_flag=N`)。是否延迟由下单参数
`delay_acct_flag` 按订单类型决定:只有 `STORE_CONSUME` 不延迟,其它订单(含以后新增的类型)
一律延迟,这样未核销的钱默认被扣在通道。
核销成功时触发交易确认。资金确认状态记在 `payment_transaction.funds_confirmation_status`:
`NULL` 表示未走延迟入账,`pending` 表示钱还在延迟户,`confirmed` 表示已分账到商户基本户。
撤销核销必须走反方向:调用通道的**交易确认退款**把已确认的金额退回延迟户,状态回到 `pending`,
商户重新核销时会再确认一次。回退期间状态是 `reverting`(钱在哪一边未定),此时不允许撤销核销。
钱被 D1 结算划到商户银行卡之后就退不回来,撤销核销只能被拒绝——所以撤销窗口实际上止于下一次自动结算。
## 结算
出款由斗拱按结算周期自动完成,平台**不生成提现记录**,也不再发起主动取现。商户进件时通过
`settle_config` 打开自动结算(批次结算、不设起结金额与留存金额),商户和平台都不需要手工出款。
后台的「结算记录」页直接查询斗拱的结算流水,用于监控每天自动结算了多少到银行卡。
## 结算银行卡
商户绑定的银行卡是自动结算的到账目标。商户可以查看和更换结算银行卡,但不能发起提现或选择金额。
## 进件与微信支付
**人才端**:人才用户购买商品并完成微信付款的小程序,也是商户发起到店消费订单后的付款端。
**商户端**:商户办理进件、扫描人才码创建到店消费订单,以及扫描预购订单核销码完成核销的小程序;付款由人才用户在人才端完成。
**商户进件**:商户提交主体、经营和结算资料,申请成为汇付商户的过程。主体分企业(含个体工商户)
与个人(小微)两种:企业交营业执照与法人资料,个人交身份证、**经营详细地址**。
**门店材料**是一组三张——**店铺门头照**(线下报备口径下是实体门头照)、**店内环境照**、**店铺收银台**,
**企业与个人主体都要交**:通道在进件这一步就按 F-code 逐张核对,缺一张整笔驳回。
基本资料审核通过后,微信支付仍可能处于开通中或开通失败。
**自助进件**:商户在我们商户端自己提交上一条**商户进件**的路径。相对的是**外部进件**。
_Avoid_: 线上进件(那是「进件场景」,与谁发起无关)
**外部进件**:商户**已在汇付侧完成进件**,我们把它接进某个商家。两条路径收敛到同一套进件记录、
分阶段进度与**收款就绪**判定,只有来源不同(进件记录的 `source`:`self` 自助进件 / `managed` 纳管)。
接进来的动作叫**纳管**:后台选定我方商家 + 填汇付商户号与入驻申请单号,先只读核验通道,再建结算卡与
进件记录并跑一次进度刷新。**纳管全程只查询、不下发**——外部商户的口径已由业务要求与自助进件保持一致,
只需核实;而补开微信、绑人才端 AppID、改支付场景、开启延迟入账都不幂等(改支付场景会重建微信子商户号),
连锁多店共用一个汇付商户号时各自下发还会重复下发。防绑错靠**主体名人工核对 + 显式确认 + 留痕 + 可解绑**,
不做「名称对不对得上」的字符串判定(我们只有一个商家名,通道那边是工商全称加简称,形态不对应)。
一个汇付商户号可以被多个商家分别纳管(连锁各门店共用一个收款主体)。
_Avoid_: 迁管、挂靠(会让人以为是一份收款主体 + N 个引用的模型)
**渠道商**:汇付里位于我们平台之上、**直属**管辖我们名下商户的那一层主体。平台的每一次通道调用都以它(或它的下级身份)
签名,因此「谁能查到哪个商户」由**签名身份本身的数据权限**决定,与商户在通道里挂在谁下面无关——
把商户改成挂在平台自己名下既解除不了数据权限失败,还会平白多出材料要求。
_Avoid_: 上级商户、代理、平台商户号(那些会与商户自己的号混同)
**微信支付开通**:商户取得在平台小程序内接受微信付款所需业务能力的过程。开通失败可以单独重试,不否定已经通过的基本资料审核。
**微信待实名**:微信支付开通过程中,仍需完成微信实名认证与授权的阶段,不属于开通失败。实名认证走法人(`contact_type=LEGAL`),申请以法人信息发起;申请单审核通过(`APPLYMENT_STATE_PASSED`)不等于授权完成,还要由本人扫描通道回传的小程序码、并满足 `authorize_stat=1`。这是**收款就绪**的真实缺项,不是可以忽略的合规补课。
**收款能力**:通道侧对这家子商户当下是否可用的判定事实,即通道商户状态(`merchant_stat`)与取现、结算开关。它不由平台决定,会随汇付控台的操作随时改变——进件通过不代表它一直正常,商户被通道停用后它会变成异常。它**不等于**收款就绪:这里只描述通道侧的事实,不含我们要求的微信支付开通与实名等前提,也不等同于进件阶段。
**收款就绪**:商户可以接受微信付款的状态,是某一时点的判定结果,不是进件的终态。除基本进件通过、结算银行卡可用、延迟入账与自动结算已核实、**收款能力**正常外,还必须已开通微信支付业务并完成微信实名认证与授权;未完成实名前不允许收款。收款能力一旦异常,收款就绪随之回退,所以它的对外可信度以最近核实时间为准。
## 微信支付口径
三个都叫「场景/scene」的东西是**三件不同的事**,混起来会把支付配瘸,因此各给一个名字:
**支付场景(pay_scene)**:这笔微信支付在通道侧按哪一档**支付能力**受理——线下(反扫、公众号、小程序)
与线上(公众号、小程序、反扫)是两组独立的报备与费率,不是同一件事的两种叫法。平台统一走线下。
_Avoid_: 场景、支付方式(会与下面两个混)
**业务开通类型(fee_type)**:商户微信业务按线上标准费率还是线下这一档开通。它决定三件事:人才端
AppID 绑在哪一组配置下、实名与实名查询用哪一档、通道回执里按哪一档匹配。与**支付场景**不是同一个字段。
_Avoid_: 费率类型、pay_scene(同名字段、不同含义)
**进件场景(scene_type)**:商户的**主体资料**按线上经营还是线下经营场所报备,决定通道索要哪些经营场所
材料。它与支付场景相互独立:一家商户的进件场景与它开通的支付场景可以不同,也不要求相同。
_Avoid_: 经营场景、业务场景(都会与上面两个混)
**费率规则号(CID)**:通道按「支付场景 × 业务开通类型 × 主体类型」三维定位的结算规则编号,费率与它一体。
选错号不是「费率算错」而是直接被拒,所以主体类型不同、场景不同就不能共用一个号。
_Avoid_: 费率号、规则 ID(听起来像一个可以随便配的数)
**经营详细地址**:商户实际经营场所的地址,线下报备下是必填项。它与**证件地址**(身份证/营业执照上的住址)
是两回事,不能互相顶替——线上口径下曾经用证件地址顶替它,线下会被通道驳回或留下错误的报备信息。
_Avoid_: 注册地址、门店地址(前者是执照住址,后者是门店这一维度的地址)