Skip to content

安全设计

支付链路的安全防线依次为:渠道验签 → 幂等防重 → 资金一致性 → 规则中心风控与人工审批 → 投诉分流 → 权限、数据权限与审计。

安全矩阵

风险防线
伪造回调微信平台证书、支付宝 RSA2/RSA、银联 SHA256+RSA 验签;验签失败只记日志并返回 401
重复回调 / 重复事件订单/退款状态条件更新 + Outbox 至少一次投递 + 订阅者幂等
重复提交下单、退款、转账等写接口使用 idempotencyGuard;业务活跃单复用;唯一索引兜底
并发超退退款事务内锁单校验可退余额
转账双付(channel, out_transfer_no) 唯一;只有渠道未受理且尝试次数未达上限的失败单可重试
重复记账台账唯一索引限制同订单收款/手续费、同退款退款/手续费冲销重复入账
密钥泄露渠道密钥 AES-256-GCM 加密落库,API 只返回 hasXxx 布尔位
大额误退退款审批阈值链路
欺诈交易payment_risk 决策表 + 原生名单/限额规则双层裁决
投诉处理不一致dispute_triage 分流建议、SLA 收紧、时间线留痕;资金动作仍需人工确认
越权操作19 个支付页面权限码、服务端 guard()、数据权限与租户隔离
争议无凭据回调日志、风控命中、规则执行记录、投诉时间线、Open Platform Webhook 投递日志

密钥与证书存储

payment_channel_configs 的敏感字段使用 encryptField 加密存储:

渠道加密字段明文字段
微信APIv3 Key、商户私钥AppID、商户号、证书序列号、平台证书
支付宝应用私钥AppID、支付宝公钥、签名类型、网关
云闪付商户私钥商户号、证书序列号、银联公钥、网关
  • 字段加密密钥来自 FIELD_ENCRYPTION_KEY,未配置时由 JWT_SECRET 派生。
  • 查询接口返回 hasWechatApiV3KeyhasWechatPrivateKeyhasAlipayPrivateKeyhasUnionpayPrivateKey,不返回明文或掩码内容。
  • 编辑渠道时密钥字段留空表示保留原值。
  • 适配器调用期间通过 AdapterContext.secrets 临时解密。
  • 微信平台证书可通过 /v3/certificates 自动下载、解密并按序列号缓存 12h。

回调验签与防伪

公开回调端点:

text
POST /api/public/payment/notify/{channel}

安全行为:

  1. 遍历同渠道所有启用配置逐个验签;
  2. 全部失败时写 payment_notify_logs(signatureValid=false) 并返回 401;
  3. 验签通过后校验订单号、金额、状态;
  4. 使用条件更新推进状态,重复回调不产生重复事件或重复履约;
  5. 业务处理失败时返回渠道失败 ACK,等待渠道重试。

幂等与防重

层次机制
HTTPidempotencyGuard 支持 X-Idempotency-Key,否则按用户、方法、路径与请求体指纹生成 15s 幂等键
业务订单同一 bizType + bizId 的 pending/paying 订单复用;payment_orders_active_biz_uq 兜底
渠道单号out_trade_noout_refund_noout_transfer_no、确定性分账单号作为渠道侧幂等键
事件payment_events at-least-once;订阅者用条件更新或业务唯一键幂等
记账Journal 来源作用域唯一键、借贷平衡约束与 reservation 版本 CAS 兜底重复过账与并发超支

资金一致性

  • 金额全链路使用整数分。
  • 退款在事务内锁定订单并计算可退余额,审批中的退款不占用订单 refunding 状态。
  • 支付成功后内置订阅者写收款双分录凭证、计算手续费、回写 feeAmount / netAmount
  • refund.succeeded 订阅者写退款双分录凭证,并按退款比例冲销手续费;全额退款末笔补差以消除舍入残差。
  • 订单 feeAmount 保持下单/成功时手续费快照;资金事实以台账流水为准。
  • Journal 是资金唯一事实来源;账户、凭证和 reservation 按应用/商户配置/币种隔离,所有资金流出通过版本化 reservation 防并发超支。
  • 结算确认写 type=settlement 台账,将待结算划转到可用余额。
  • 投诉退款复用统一退款链路与审批阈值,不由分流规则直接执行资金动作。

退款审批

审批阈值单位为分,来源优先级:系统配置 payment_refund_approval_threshold → 环境变量 PAYMENT_REFUND_APPROVAL_THRESHOLD0 或未设置表示不启用审批。

  • refundAmount ≥ 阈值 的退款进入 approvalStatus=pending
  • payment:refund:approve 权限可审批通过或驳回;
  • 审批通过后执行渠道退款;驳回置 failed 并记录 refund.failed
  • 申请人、审批人、审批时间与意见留痕。

支付风控

下单前调用 evaluateRisk(),执行两层裁决:

L2:规则中心决策表

  • 规则引用:decide({ kind: 'table', key: 'payment_risk' }, facts, { caller: 'payment.risk' })
  • 决策表发布后优先裁决,输出 action=block/review/pass 与可选 reason
  • pass 是显式放行,直接跳过 L1;blockreviewpayment_risk_hits,其中 dimension=decisionruleName='决策表 payment_risk'
  • 决策表未发布、未命中或输出无效时回退 L1。
  • 可用事实包括 order.*today.*hit.*subject.*;执行记录可在 /rules/evaluation 追溯。

L1:原生维度规则

payment_risk_rules 支持以下维度:

维度说明
blocklist黑/灰名单库 key 命中 openid、用户 ID 或客户端 IP
single_limit单笔金额上限
daily_limit当日累计已支付金额上限
daily_count当日已支付笔数上限

规则作用域为 globalchannelbizTypeallowListKeys 只能引用白名单库,命中后跳过该规则;blockListKeys 可引用黑/灰名单库。名单批量判定由规则中心名单库提供。

动作:

  • block:落渠道单前拦截;
  • review:先落挂起订单与 payment_risk_reviews,渠道侧不下单;审核放行后重新发起支付复用该订单,审核拒绝则本地关单。

交易投诉分流

新投诉工单创建后调用:

ts
decide({ kind: 'table', key: 'dispute_triage' }, facts, { caller: 'payment.dispute' })

决策表按投诉类型、涉诉金额、投诉人 90 天投诉数输出:

输出说明
routeurgent / manual / auto_refund_suggest
priority分流优先级,数值越大越紧急
slaHours建议处理时效,写入 deadline 时只收紧不放松

auto_refund_suggest 只作为 UI 徽标与预填退款建议;退款必须由具备 payment:dispute:handle 权限的人员确认,最终仍走统一退款与审批链路。每次命中会写入 system 时间线,规则执行记录可在 /rules/evaluation 追溯。

权限与数据权限

页面权限码
支付渠道payment:channel:list / create / update / delete
支付订单payment:order:list / create / close / refund
退款记录payment:refund:list / approve
回调日志payment:log:list
对账中心payment:recon:list / create / delete / handle
资金凭证与预占payment:ledger:listpayment:ledger:postpayment:ledger:reversepayment:ledger:reserve
Open Platform Webhookopen-platform:webhook:list / manage
支付 Webhook 视图payment:webhook:list / manage
支付事件payment:ops:manage
费率管理payment:fee:list / create / update / delete
结算管理payment:settlement:list / generate / settle
分账管理payment:sharing:list / manage / dispatch
支付链接payment:link:list / create / update / delete
风控中心payment:risk:list / create / update / delete / review
支付方式payment:method:list / update
财务报表payment:report:view
转账管理payment:transfer:list / create
应用管理payment:app:list / manage
签约代扣payment:contract:list / manage / plan
交易投诉payment:dispute:list / handle
预授权payment:preauth:list / manage
  • 支付订单列表按部门与创建人的数据权限范围过滤。
  • 支付表带 tenant_id,查询按租户隔离。
  • 渠道配置、支付/退款、关单、审批、调账、转账、差异处理、风控审核、投诉处理等敏感操作写操作日志。

相关环境变量

变量说明
FIELD_ENCRYPTION_KEY字段级 AES-256-GCM 加密密钥;未配置时回退 JWT_SECRET 派生
PAYMENT_NOTIFY_BASE_URL / PUBLIC_BASE_URL渠道回调地址基址
PAYMENT_REFUND_APPROVAL_THRESHOLD退款审批阈值兜底,单位分
PAYMENT_MOCK_DISPUTEStrue 时定时任务为沙箱成功订单生成模拟投诉;手动模拟接口不受该变量限制

Built with VitePress for local documentation preview.