wechat
Wechat Pay

微信支付

微信订单的信息仅存在于支付阶段

微信支付指引文档 (opens in a new tab)

微信支付API参考 (opens in a new tab)

微信支付nodejs版sdk文档 (opens in a new tab)

微信支付模式

按商户角色分: 直连模式服务商模式, 其中服务商模式可调用分账功能 (opens in a new tab)

按客户端种类分: JSAPI支付 & APP支付 & H5支付 & Native支付 & 小程序支付 & 合单支付 & 付款码支付V2 & 刷脸支付

微信支付流程

支付流程

生成预付单 -> 调起支付 -> 微信返回支付结果 -> 查询判断支付结果

  • 表达: 时序图, 流程图, 状态图 微信支付时序图

前端通信

  • 公众号、小程序、APP支付
    • 前端返回“用户取消”的情况,则订单状态保持未支付状态,并提示用户支付未完成。
    • 前端返回“成功”或“报错”的情况,商户需要调用商户查单接口,确认订单状态。

后台同步微信订单

  • 回调通知
  • 定时轮询: 定时任务每隔30秒启动一次,找出最近10分钟内创建并且未支付的订单,调用《微信支付查单接口》核实订单状态。系统记录订单查询的次数,在10次查询之后状态还是未支付成功,则停止后续查询,并调用《关单接口》关闭订单。(轮询时间间隔和次数,商户可以根据自身业务场景灵活设置)
  • T+1日对账
    • 订单匹配成功,并且状态都是支付成功:正常情况,对账成功。
    • 订单匹配成功,但是商户侧状态非支付成功:商户根据自身业务情况,决定是否把订单状态更新为支付成功并给用户发货,或者是给用户发起退款。
    • 订单匹配失败,对账单中的单号在商户系统未找到记录:异常情况,需要商户排查系统是否出现数据异常。
    • 订单匹配失败,商户系统中成功的订单在对账单中未找到记录:异常情况,需要商户排查是否订单处理逻辑有bug。

微信支付安全

实现方式

  • 端点鉴别&完整性: 请求接口时进行商户私钥签名, 得到返回值时用微信平台公钥去验证微信平台的签名。
  • 保密性
    • 接口级别的保密: 需对平台证书下载接口的返回值以及回调接口的请求值通过AES-256-GCM对称加密算法用商户的APIv3密钥进行解密
    • 字段级别的保密: 需对敏感信息字段(如用户的住址、银行卡号、手机号码等)通过RSA公钥加解密算法使用微信平台证书的公钥进行加解密。

签名构造

每个支付接口的调用需提供 认证类型 (目前为WECHATPAY2-SHA256-RSA2048) & 签名信息 附加在Authorization头中, 格式为Authorization: 认证类型 签名信息, 其中签名信息由 mchid="<商户号>",serial_no="<商户API证书序列号>",nonce_str="<请求随机串>",timestamp="<时间戳>",signature="<签名值>"构成, 而 签名值 又由

HTTP请求方法\n
URL\n
请求时间戳\n
请求随机串\n
请求报文主体\n

签名串 经由SHA256散列加密后, 再经过RSA2048算法使用 商户API私钥 进行加密, 最后进行Base64编码得到。

验证签名

通过https://api.mch.weixin.qq.com/v3/certificates接口下载微信 平台证书 , 从中得到 公钥 , 从HTTP头中获取Wechatpay-Timestamp时间戳与Wechatpay-Nonce随机串头部, 并构造签名串

应答时间戳\n
应答随机串\n
应答报文主体\n

, 在Wechatpay-Signature头中获得签名值, 通过Base64解码以及平台证书的公钥解密后比对与签名串是否相同即可。

加解密基本概念

  • 对称加密算法: AES, DES, 3DES
  • 非对称加密算法: RSA, ECC, DSA
  • 散列加密算法: MD5, SHA1, SHA256, SHA512, HMAC
  • 构造签名基本流程: 签名串 -> 散列加密签名串 -> 私钥加密 -> base64编码 -> 签名
  • 验签基本流程: base64解码 -> 公钥解密 -> 散列加密的签名串, 签名串 -> 散列加密的签名串, 散列加密的签名串