微信支付收款开发备忘

2024 年 07 月 03 日

要为应用实现微信收款功能,因此忙了几天。感觉这件事技术本身不复杂,但微信支付在产品设计和文档上比较复杂,让人难以轻松上手。因此简单记录一下过程,作为备忘。

目标功能和方案

要实现微信收款,也就是要使用微信支付这个产品,完成以下功能:

  1. 允许用户使用微信支付。
  2. 根据用户支付的结果完成后续操作。

如果不需要功能 2,那么最简单的办法就是个人收款码。而且个人收款码可以生成固定金额的收款码。能够适应一些场景。所以不需要功能 2 的可以不用继续看了。

需要功能 2 的话,也有两个方案,即所谓的免签约支付和常规的方案。

关于免签约支付

免签约支付其实是不被国内支付提供商允许的一种服务,算是灰产。其原理是利用个人账号去进行收款。支付完成后,自动化的部分需要 hack 微信/支付宝,根据收到通知来触发后续动作。

我对这个方案没有深入研究,毕竟存在一些风险。一方面,你无法确定提供这项服务的供应商是否可信;另一方面,技术本身也有限制,比如支付频率受限的问题,还有支付后通知与支付请求的对应关系问题,都可能带来麻烦。

常规方案

要实现常规方案,就要在根据微信的要求:

  1. 提供资质证明,注册相关账号。
  2. 使用官方 SDK,或根据协议文档进行开发。

本文不讨论免签约支付,所以无法提供资质证明并注册微信相关账号的可以不用继续看了。顺便说一句,支付宝情况类似,也要提供各种资质证明。

开发准备

官方接入指引文档在这里。其实问题可以简化一下:

  1. 关于收款,你需要在微信支付的商户平台,注册一个商户账号。如果只是线下的支付,这一个账号就够了。
  2. 如果需要线上的支付渠道,这个渠道也需要在微信的开放平台上登记,公众号/小程序/网站/App 都是一样。

商户平台注册后,会获得一个超级管理员账号。注意,很多操作都是只能用超级管理员执行的。

开放平台需要登记你的线上支付渠道,获得 App ID,这是线上渠道需要的唯一标识。注意这里很多操作都需要资质认证,动不动就是 300 元。

从商户平台需要获得以下信息:

  1. MCHID,即微信支付商户号,在 账户中心 - 商户信息 - 基本账户信息 获得。
  2. API 证书 + 序列号,在 账户中心 - API 安全 - 申请 API 证书 获得。
  3. APIv3 密钥,在 账户中心 - API 安全 - 设置APIv3密钥 获得。

另外还需要一个域名和服务器,能够在公网访问到的。

所以开发前,应该准备好以下数据和文件:

  • 数据:App ID + MCHID + API 证书序列号 + APIv3 密钥。
  • 文件:API 证书文件,通常命名为 apiclient_key.pem。

商户平台还需要将 App ID 与商户关联,在 产品中心 - AppID 账号管理 填写。部分 API 可能需要在 产品中心 - 我的产品 调节配置。

API 接口概念说明

我是用 rust 开发的,虽然微信官方没有提供 rust 版本的 SDK,但有第三方开发人员做了实现,参考代码在这里,清晰简洁。

参考代码的 README 把使用方法写的很清楚了。因此这里只是把概念再整理一下。

首先是证书问题。证书有两套:

  • API 证书是商户持有的证书,此证书包含公钥和私钥。其中私钥的作用是用来给商户发出的请求签名。
  • 平台证书是平台持有的证书,商户只能下载到其公钥。用来对平台发出的请求或响应验证签名。

接下来是使用方式,基本思路就是按照如下顺序使用:

  1. 商户侧发起预支付请求,从微信服务器获取到目标链接或 prepay_id。对应预支付系列接口。
  2. 商户侧通过代码唤起微信,或者提示用户用微信扫码,也就是让微信来处理目标链接或 prepay_id。这里根据接口不同,处理方式不同,例如:
    1. native 请求获得的是 deeplink 地址,在手机端可以调用微信打开,或者生成二维码后用微信扫码。
    2. h5 请求获得的是 http 地址,在手机端可以调用浏览器打开。
    3. jsapi 请求获得的是 prepay_id,调用 WeixinJSBridge 接口打开。
    4. 小程序 请求获得的是 prepay_id,在小程序运行环境中调用 wx.requestPayment 打开。
    5. app 请求获得的是 prepay_id,调用微信 SDK 打开。
  3. 微信侧发起通知请求,商户侧接收通知并作对应处理。对应通知回调接口。

主要使用的接口包括以下几类:

  • 平台证书下载接口,从平台下载平台证书。这个 API 不需要 App ID,也不检查 notify url 是否可达,因此可以用来检测协议实现。
  • 预支付系列接口。由商户一侧主动发起,微信服务器响应。这一系列接口分为 native/h5/jsapi/app/小程序等多种类型,返回的数据有多种类型。可能是微信可以打开的链接,可能是浏览器可以打开的链接,也可能是在微信浏览器/小程序环境中可以通过 API 使用的 prepay_id。可以使用平台证书对服务器响应验证签名。
  • 通知回调接口。由微信一侧发起,商户侧的 notify url 接收请求并响应。这里必须要用平台证书验证签名(否则无法保证请求方是可信的)。然后根据通知的数据进行业务逻辑开发。

平台证书可以预先下载好,也可以在运行期下载。但无需经常更新。

感想

微信收款整体开发本身并不困难,麻烦仅在于繁琐的注册流程以及概念的梳理部分。但为什么没法简化呢?个人收款的二次开发需求本身其实很多,不然也不会有大量使用个人注册码收款的第三方方案。我猜大概是由于合规的问题,否则微信/支付宝这些大厂为什么自己不做这种功能呢?

Top