微信支付的不完整接入指南
这篇文章最后更新的时间在六个月之前,文章所叙述的内容可能已经失效,请谨慎参考!
仅适用于 微信支付 v3
微信支付的文档真的很混乱,而且还经常更新,下文提及的链接可能会失效
[TOC]
1. 申请各种账号
1.1 域名
- 需要有一个域名
- 域名需要有 https 证书
- 域名要 实名认证、工信部备案、公安部备案
- 实名认证和备案的主体要一致
1.2 微信支付的账号
需要申请三个账号,且都需要通过认证
公众平台: 服务号,小程序
商户平台: 支付相关
开放平台: app,网站
- 要在开放平台里,绑定 服务号或小程序的 appid
- 还需要设置各种授权域名
- 微信公众号后台设置
- 业务域名
- JS接口安全域名
- 授权域名
- 商户平台后台设置
- jsapi支付授权目录
- h5支付域名
- 微信公众号后台设置
- 申请这三个账号时的主体最好是一致的
- 域名的主体和那些微信账号的主体最好也一致
- 域名最好只用一个
- 好像还有一个什么 api 的白名单
账号相关文档 https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/pages/ico-guide/chapter1_1.shtml
商户平台绑定 appid https://pay.weixin.qq.com/static/pay_setting/appid_protocol.shtml
2. 获得各种凭据
需要提供的凭据
- appid
- 公众号的 AppSecret (如果不需要微信内网页支付或没有绑定公众号则不需要这个)
- 商户号
- 商户 API 证书 (需要使用证书工具生成,不能从后台里获取,生成了要妥善保管不然只能重新生成)
- 商户私钥 (和 API 证书一起生成的)
- APIv3 密钥 (不能从后台里获取,生成了要妥善保管不然只能重新生成)
凭据 | 获取途径 | 来源平台 |
---|---|---|
商户号 | 从商户平台的开户邮件中获取 | 商户平台 |
appid | 可以是公众平台里的服务号,小程序的appid,也可是开放平台里的app,网站的appid,反正就是和商户平台那个账号绑定了的就可以 | 公众平台 , 开放平台 |
公众号的 AppSecret | 在公众号后台设置,主要用在网页授权,因为微信内支付需要网页授权 | 公众平台 |
商户 API 证书 | 商户平台设置,需要使用证书工具生成(共包含三个文件: 证书 pkcs12 格式、证书 pem 格式、证书密钥 pem 格式) | 商户平台 |
商户 API 证书序列号 | 从商户 API 证书( pem 格式的证书)中获取 openssl x509 -in apiclient_cert.pem -noout -serial | 商户平台 |
APIv3 密钥 | 商户平台设置 | 商户平台 |
商户私钥 | 申请商户 API 证书后,保存在文件 apiclient_key.pem 中 | 商户平台 |
微信支付平台证书 | 通过 api 接口获取,这个要定时更新的 | 商户平台 |
微信支付平台平台公钥 | 从平台证书中获取 | 商户平台 |
必要的工具
下载证书工具
https://kf.qq.com/faq/161222NneAJf161222U7fARv.html
openssl
- 一般的 Linux 发行版里会带有
openssl
- git 的 Windows 版里的
git bash
已经带有openssl
- Windows10 1809 及以上版本也带有
openssl
- 如果真的没有就去百度然后下载一个
商户号
从商户平台的开户邮件中获取,商户平台的开户邮件大概是这样的
https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=3_1
appid
在公众平台或开放平台的后台用心找一下就能找到了,因为当前系统是用公众号的,所以一般是在公众平台的后台找
商户 API 证书 和 商户私钥
私钥和证书
https://wechatpay-api.gitbook.io/wechatpay-api-v3/ren-zheng/zheng-shu
如何申请api证书
https://kf.qq.com/faq/180824JvUZ3i180824YvMNJj.html (技术人员看这个)
https://kf.qq.com/faq/161222NneAJf161222U7fARv.html
https://kf.qq.com/faq/180824BrQnQB180824m6v2yA.html
- 使用 pem 格式的证书和密钥,就是 .pem 后缀的文件
- 一般证书的文件名里会有 cret 这个单词
- 一般密钥的文件名里会有 key 这个单词
商户 API 证书序列号
从证书中获取证书序列号
openssl x509 -in 证书路径 -noout -serial
APIv3 密钥
配置路径:【登录商户平台—>账户中心—>API安全—>APIv3密钥】
https://wechatpay-api.gitbook.io/wechatpay-api-v3/ren-zheng/api-v3-mi-yao
https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/pages/ico-guide/chapter1_2.shtml
微信支付平台证书
下载平台证书
第一次下载平台证书
java
https://github.com/wechatpay-apiv3/CertificateDownloader
java -jar CertificateDownloader.jar \
-k APIv3密钥 \
-m 商户号 \
-f 私钥路径 \
-s 商户API证书序列号 \
-o 下载平台证书的保存目录
php
https://github.com/wechatpay-apiv3/wechatpay-guzzle-middleware/tree/master/tool
php vendor/wechatpay/wechatpay-guzzle-middleware/tool/CertificateDownloader.php \
-k APIv3密钥 \
-m 商户号 \
-f 私钥路径 \
-s 商户API证书序列号 \
-o 下载平台证书的保存目录
- 平台证书是需要定时更新的
微信支付平台平台公钥
从平台证书获取平台公钥
openssl x509 -in 平台证书路径 -pubkey -noout > XX.pem
- 官方的 sdk 能自动获取的,一般不用理
其它
查看证书有效日期
openssl x509 -in 证书路径 -noout -dates
查看证书内容
openssl x509 -in 证书路径 -noout -text
查看 sdk 文档并开始接入
微信支付v3版的文档 https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/pages/index.shtml
- 文档里有相当多的时序图和流程图,这些图最好认真看一下,对理解微信支付的流程很有帮助的
微信支付有好多种,但只需要关注 普通直接模式 下的 Native支付 , h5支付 , jsapi支付 , 小程序支付
- 微信支付 Native支付 https://pay.weixin.qq.com/wiki/doc/apiv3/open/pay/chapter2_7_2.shtml
- 微信支付 h5支付 https://pay.weixin.qq.com/wiki/doc/apiv3/open/pay/chapter2_6_2.shtml
- 微信支付 jsapi支付 https://pay.weixin.qq.com/wiki/doc/apiv3/open/pay/chapter2_3.shtml
- 微信支付 小程序支付 https://pay.weixin.qq.com/wiki/doc/apiv3/open/pay/chapter2_8_2.shtml
- app内的支付可以使用内嵌网页然后调用h5支付,虽然微信的文档不建议这样做,而是使用微信支付的app支付,但理论上是可行的
开发工具
https://wechatpay-api.gitbook.io/wechatpay-api-v3/kai-fa-gong-ju
- php 一定要使用 composer 来安装 sdk
Native支付
就是扫码支付。接口返回的是一个用来生成二维码的字符串
h5支付
在手机浏览器调起微信支付。接口返回的是一个链接,让浏览器 302 转跳就好
jsapi支付
在手机微信里支付。全程都在微信浏览器里,但需要有 oauth2 那个登录的 code
大致的流程
- 获取 oauth2 的 code (后端实现)
- 通过 code 获取 opneid (后端实现)
- 通过 sdk 的接口获取 prepayid (后端实现)
- 使用 prepayid 生成签名 (后端实现)
- 把 appid , prepayid , 签名 和 生成签名时的时间戳,随机字符串 传给前端
- 前端在微信浏览器里调起微信支付
https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_1_4.shtml
小程序支付
和 jsapi支付 基本一致,只少了 appid 这个字段 https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_5_4.shtml
微信公众号网页授权
这个是用在 jsapi支付 里的,主要是获取 oauth2 那个登录的 code
https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/Wechat_webpage_authorization.html
大致的流程
- 打开页面
- 判断是否在微信内
- 在微信内就用js转跳到授权的url
- 用静默授权
- 授权完成后带着 code 回到原本的页面
- 用静默授权,是因为代码写起来比较简单,但只能获取到 openid
回调
这是 Native支付 支付回调的文档,每种支付方式的回调文档都有点不一样,但因为都很相似,所以实际代码是写得一样
https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_4_5.shtml
- 回调接收的是 json 字符串
php 里的代码大概写成这个样子,只是示例代码,实际代码千万不要写成这样
$input = file_get_contents("php://input");
$input = json_decode($input, true);
- 需要经过解密才能获取详细的回调内容
php 里的代码大概写成这个样子,只是示例代码,实际代码千万不要写成这样
$resourceJson = $input['resource']; // input 是上一步获取的变量
$associatedData = $resourceJson['associated_data'];
$nonceStr = $resourceJson['nonce'];
$ciphertext = $resourceJson['ciphertext'];
$aesUtil = new \WechatPay\GuzzleMiddleware\Util\AesUtil($aesKey); // aesKey 是 APIv3 密钥
$resource = $aesUtil->decryptToString($associatedData, $nonceStr, $ciphertext);
$resource = json_decode($resource, true); // 这是详细的回调内容
- 如果太久都没接收到回调结果,应该调用订单查询的接口查询
同样地每种支付方式的订单查询文档都有点不一样,但因为都很相似,所以实际代码是写得一样
https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_4_2.shtml