Skip to content

安心支付技术链路与排障

本页面向开发和运维,记录支付宝安心生活、外部桥接服务、金刚后端、云平台和易宝之间的接口、数据、幂等与异常边界。接口密钥、企业微信机器人密钥、证书和数据库口令只保存在受控配置中,不进入知识库。

系统边界

text
支付宝安心生活
  -> 外部桥接服务 orther_api.py
  -> storeapi 外部需求接口
  -> jingangdata 家政人广场和订单
  -> storeui 员工履约
  -> 外部桥接服务调用支付宝履约/核销/取消
  -> 支付宝核销通知
  -> storeapi 员工钱包
  -> storeui 员工申请提现
  -> yunui/yunapi 财务审核
  -> storeapi 预检并调用易宝直接分账

外部桥接服务还把支付宝原始通知写入 SQL Server;金刚业务数据和员工钱包位于 jingangdata MySQL。

接口清单

系统方法与路径作用
外部桥接POST /axzf接收支付宝预约、订单和核销扣款通知,验签后转发金刚
外部桥接POST /axzf_cancel调用支付宝预约同步,动作支持 fulfillcancel
外部桥接POST /axzf_hx调用支付宝核销使用接口
外部桥接POST /axzf_hx_cancel对已核销扣款单执行退款
storeapiPOST /api/v1/external/demand/publish接收预约,创建或取消安心需求
storeapiPOST /api/v1/external/demand/hx_notify保存核销扣款单并推进安心钱包入账
storeapiPOST /api/v1/demand-square/grab门店人工抢单并创建金刚订单
storeapiPOST /api/v1/order/cancelOrder金刚门店端取消,按核销事实分流渠道操作
storeapiPOST /api/v1/staff-order/startService状态 50 -> 60,事务提交后同步 fulfill
storeapiPOST /api/v1/staff-order/endService状态 60 -> 80,判断钱包条件并在提交后发起核销
storeapiGET/POST /api/v1/staff-wallet/*员工钱包总览、流水、提现记录和提现申请
yunapiGET /merchant/standard-staff/withdrawals财务查询提现单及关联订单收入
yunapiPOST /merchant/standard-staff/withdrawals/{no}/review代理调用金刚内部审核和易宝打款
storeapiPOST /api/v1/internal/standard-order-ops/withdrawals/{no}/review余额预检、审核、提交易宝和返回结果

yunui 普通订单页使用的是 PUT /order/cancel/{ids}。该接口在 yunapi 中直接更新订单状态,不会调用上表中的安心渠道取消逻辑。

通知解析和 SQL Server 日志

orther_api.py/axzf 支持:

支付宝消息方法处理
预约或安心订单通知解析预约信息并调用金刚放单
核销扣款单通知提取 card_iddeduction_order_idopen_id 并调用金刚核销通知
其他消息记录后返回成功,不进入放单

SQL Server dbo.AlipayAxzfNotifyLog 保存通知 ID、消息方法、预约单号、安心订单 ID、服务 ID、用户、支付宝门店、门店名称、预约状态、扣款状态、核销卡 ID、扣款单号、验签结果、处理状态、业务原文、表单原文、通知次数和时间。

幂等规则:

  1. 同一 NotifyId 更新原记录并增加通知次数。
  2. 同一非空 OrderId 已有日志时不再插入第二条日志。
  3. shop_id 通过 SQL Server alipay_shopshop_name
  4. 日志去重不替代金刚业务去重;重复请求仍由金刚按预约和安心订单 ID 返回幂等成功。

扩展属性脚本重复执行出现 MS_Description already exists 只表示备注已经存在。后续维护脚本应先判断扩展属性是否存在,存在时使用更新,不应反复无条件新增。

放单和建单幂等

storeapi 放单采用两层检查:

规则
booking_id + source_platform已存在即返回原需求
安心 order_id状态为待抢或已抢的有效需求只允许一条

预约确认只写 demand_squaredemand_channel_datacreated_order_number 为空时,订单列表查不到是预期行为。

人工抢单和 30 分钟自动接单都会:

  1. 锁定待抢需求,防止并发抢单。
  2. 更新需求的抢单门店和人员。
  3. 创建客户、地址、金刚订单、支付记录和订单日志。
  4. 回写 created_order_number
  5. 提交事务后发送企业微信机器人消息。

机器人地址从 ANXIN_LIFE_ORDER_WEBHOOK_URL 读取。代码中不得保存默认密钥;部署时通过受控环境变量注入并定期轮换。

30 分钟自动接单

主路径使用 Redis 过期键:放单成功写入 30 分钟 TTL,监听到期后调用自动接单任务。服务启动时会扫描仍在待抢的安心需求并重建计时器,超过 30 分钟的记录立即触发。

定时任务 AnxinLifeAutoGrabTask.run 也能扫描超时需求作为补偿。当前目标配置为交付用户和全国交付门店。修改目标时必须同时核对用户、门店主键、UUID 和名称,避免订单归属不一致。

履约和核销时序

开始服务

员工开始服务先更新本地状态和开工资料,提交后调用预约同步 fulfill。渠道失败只记录,不回滚状态。

结束服务

员工结束服务的顺序:

text
更新订单为 80
  -> 完成档期和派发记录
  -> 调用结算入口识别安心渠道
  -> 无 deduction_order_id 时返回 WAITING_DEDUCTION
  -> 提交本地事务
  -> 调用 /axzf_hx 发起支付宝核销
  -> 支付宝异步通知 /axzf
  -> 转发 /hx_notify
  -> 保存 deduction_order_id 并尝试钱包入账

支付宝先通知核销时,hx_notify 保存核销数据并返回 WAITING_SERVICE_COMPLETION。本地服务完成后,结算入口再次调用同一个钱包入账函数。

钱包入账

核心表:

作用
demand_square需求状态、承接门店和金刚订单号
demand_channel_data预约、安心订单、支付宝门店、核销扣款单和渠道结果
order金刚履约主订单
order_waiter实际服务员工和安心佣金 service_personal
staff_wallet_account员工钱包可用、冻结、累计收入和已提现
staff_wallet_ledger安心佣金和提现账本
staff_withdrawal_application提现审核和易宝打款状态
standard_order_settlement_task全国标准单任务;用于阻止安心订单重复走标准单分账

安心佣金幂等键为“金刚订单号 + 员工”。入账前检查是否已有成功的全国标准单易宝分账;已有成功记录时转人工,未成功的标准单任务则改为 ANXIN_WALLET/CANCELLED

提现审核和易宝打款

员工申请提现时:

  1. 校验最低金额和易宝个人入网。
  2. 锁定钱包账户并检查可用余额。
  3. 限制同一员工只有一笔处理中申请。
  4. 可用余额转冻结余额,创建提现单和提现流水。

财务点击通过时:

  1. preflight_withdrawal 检查真实模式、二级开关、出账商户配置和迁移字段。
  2. 解析员工 micro_staff 易宝商户并检查可用状态。
  3. 查询出账商户可用余额,余额小于提现金额直接失败,且不修改审核或钱包状态。
  4. 预检通过后把提现单改为 APPROVED,再复用 YeepayDivideService.apply_divide_balance_direct 提交单笔分账。
  5. 易宝同步成功或异步回调成功后,调用钱包完成逻辑扣减冻结余额并改为 COMPLETED
  6. 明确失败时保留失败原因并进入 MANUAL_REVIEW;网络异常按 5、15、60 分钟重试。

部署变量:

变量作用
STANDARD_WITHDRAWAL_PAYOUT_MODE钱包提现运行模式
STANDARD_WITHDRAWAL_PAYOUT_LIVE_ENABLED真实打款二级开关
STANDARD_WITHDRAWAL_SOURCE_MERCHANT_NO平台出账商户号
STANDARD_ORDER_SETTLEMENT_MODE全国标准单服务奖金运行模式
STANDARD_ORDER_SETTLEMENT_LIVE_ENABLED全国标准单真实分账二级开关

钱包提现和全国标准单服务奖金是两套独立开关。配置了钱包提现真实打款,不会自动开启全国标准单服务奖金分账。

取消链路

storeapi 取消订单会在本地提交后查询安心渠道数据:

条件外部调用
deduction_order_id预约同步 cancel
deduction_order_id核销扣款单 REFUND

当前实现中第三方调用失败不影响本地取消,必须以 demand_channel_data.callback_response 和支付宝最终状态做补偿对账。

支付宝主动发送 status=canceled 时:

  • 待抢需求改为过期;
  • 已抢需求改为取消,并尝试取消未完成金刚订单;
  • 已完成需求拒绝自动取消;
  • 已取消或过期请求幂等返回。

已知技术风险

风险代码事实建议
放单金额被固定为 199外部请求包含金额,但需求服务当前固定 commission_amount=199.00改为校验后的请求金额或产品映射金额,并补非 199 用例
云平台取消绕过渠道yunapi 只批量更新 order_status=99代理调用 storeapi 取消服务,或对安心订单禁用该按钮
本地取消先于渠道结果storeapi 提交本地事务后调用支付宝增加补偿任务和醒目的渠道失败状态
渠道回调失败不阻断履约开始、完成和机器人通知均是提交后调用增加失败任务扫描、告警和手工重试入口
桥接日志使用拼接 SQL依赖手工转义改为 SQL Server 参数化执行,并为 NotifyIdOrderId 建唯一或过滤索引
机器人密钥存在代码默认值密钥轮换和泄露风险删除默认值,只允许受控环境变量配置

排障顺序

有预约但无需求

  1. 查 SQL Server 通知日志的验签、消息方法和原始业务内容。
  2. 查桥接服务转发结果。
  3. booking_id 或安心 order_id 是否已命中幂等。
  4. 查产品映射或生产测试数据拦截。

有需求但无金刚订单

  1. 查需求是否仍为待抢。
  2. created_order_number 是否为空。
  3. 查人工抢单事务和 Redis 自动接单计时器。
  4. 超过 30 分钟时查自动接单任务、交付目标配置和数据库锁结果。

服务完成但未入钱包

  1. 查金刚订单是否为 80/90
  2. deduction_order_id
  3. order_waiter.service_personal 和员工手机号。
  4. 查安心佣金幂等流水。
  5. 查是否已有全国标准单成功分账导致人工复核。

提现通过但未到账

  1. 查提现单状态和 payout_status
  2. 查预检是否通过及出账余额查询结果。
  3. 查易宝分账记录、请求号和回调。
  4. PROCESSING 等回调或补偿;MANUAL_REVIEW 按最后错误处理。
  5. 禁止直接把状态改为完成,也不要创建新的请求号重复打款。

代码定位

逻辑文件
支付宝通知和四个桥接接口D:/python/mypython/公司工具/家姐培训创建订单/orther_api.py
放单、抢单和外部取消storeapi/module_admin/service/demand_square_service.py
自动接单storeapi/module_task/anxin_life_auto_grab_task.pystoreapi/module_admin/service/anxin_life_auto_grab_listener.py
建单群通知storeapi/module_admin/service/anxin_life_order_notify_service.py
渠道履约、核销和取消storeapi/module_admin/service/channel_callback_service.py
员工履约storeapi/module_admin/service/staff_order_service.py
安心佣金和钱包storeapi/module_admin/service/staff_wallet_service.py
提现打款storeapi/module_admin/service/staff_withdrawal_payout_service.py
云平台提现代理yunapi/module_admin/controller/standard_staff_controller.py
云平台普通取消yunapi/module_admin/service/order_service.py

用于金刚项目内部协作、运营培训和客户说明。