使用指南
此开发包承载了三部分内容,1、CLI:用符合官方开发规范的方式,获取微信支付平台证书,支持以命令行的方式,与服务端接口交互;2、CLIENT:通过链接相对路径(pathname),用HTTP METHOD作为驱动执行函数,发起HTTP请求;3、SERVER:提供简单易用的方法,支持应用级快速集成。
CLI 模式
在试用微信支付APIv3
初始阶段,获取微信支付平台证书一直是件即简单又麻烦的过程,PHP
环境也鲜有一键获取的解决方案。本包在1.0版本的时候即提供了与Java版参数语义一致的下载方案(并且原生支持应答验签功能),使用composer
命令,像安装依赖包一样下载平台证书文件。
composer exec CertificateDownloader.php -- --help
Usage: 微信支付平台证书下载工具 [-hV]
-f=<privateKeyFilePath> -k=<apiv3Key> -m=<merchantId>
-s=<serialNo> -o=[outputFilePath] -u=[baseUri]
Options:
-m, --mchid=<merchantId> 商户号
-s, --serialno=<serialNo> 商户证书的序列号
-f, --privatekey=<privateKeyFilePath>
商户的私钥文件
-k, --key=<apiv3Key> APIv3密钥
-o, --output=[outputFilePath]
下载成功后保存证书的路径,可选,默认为临时文件目录夹
-u, --baseuri=[baseUri] 接入点,可选,默认为 https://api.mch.weixin.qq.com/
-V, --version Print version information and exit.
-h, --help Show this help message and exit.
快速开始的起始部分,即使用此模式先行下载微信支付APIv3
平台证书。
CLIENT 模式
大体上来说,一个URL可分为如下三部分:
https://api.mch.weixin.qq.com/v3/certificates?algorithm_type=RSA
└──────────────┬─────────────┴───────┬──────┘ └────────┬───────┘
endpoint pathname querystring
- 接入点(endpoint):
https://api.mch.weixin.qq.com/
- 相对路径(pathname):
v3/certificates
- 查询参数(querystring):
algorithm_type=RSA
微信支付当前已知的OpenAPI接入点(endpoint)有:
https://api.mch.weixin.qq.com/
默认https://api2.mch.weixin.qq.com/
https://fraud.mch.weixin.qq.com/
https://payapp.mch.weixin.qq.com/
https://apihk.mch.weixin.qq.com/
https://pay.wechatpay.cn/
本开发包在初始化阶段,内置了默认的接入点(endpoint),在特殊接口,如付款到银行卡获取加密敏感信息的RSA公钥,就需要显式声明所对应的接入点(endpoint); 在构造请求链时,把 相对路径(pathname) 以/
做切分,取出 segments
映射成实例对象属性,接口支持的HTTP METHOD即作为末尾驱动执行函数,按需代入 查询参数(querystring),发起HTTP请求。
编码书写方式有如下约定:
请求
segments
按照顺序作为级联对象,例如v3/pay/transactions/native
即链接成v3->pay->transactions->native
;每个
segments
所支持的HTTP METHOD
,即作为 请求对象的末尾执行方法,例如:v3->pay->transactions->native->post([])
;每个
segments
级联对象末尾的HTTP METHOD
方法,同时支持getAsync|postAsync|putAsync|patchAsync|deleteAsync
方法链,即以异步
方式请求远端接口;每个
segments
有中线(dash)分隔符的,可以使用驼峰camelCase
风格书写,例如:merchant-service
可写成merchantService
,或者字面量属性,如v3['merchant-service']
;每个
segments
中,若有动态参数,例如business_code/{business_code}
可写成business_code->_business_code_
或者字面量属性风格,如business_code['{business_code}']
;以
v2
开头的segment
,其特殊标识为APIv2
级联对象开始位,之后串接其他segments
,如源pay/micropay
即串接成v2->pay->micropay
即以XML
形式请求远端接口;
开放接口包含了大量的使用示例代码,请按需参阅使用。
SERVER 模式
回调通知 章节,当应用工作在服务端模式时,需要接收 微信支付 的后台数据(消息)通知时,按照开发规范,需要对数据:1. 验签、2. 解密、3. 应答。微信支付后台数据目前有两大类数据结构,APIv2基于XML规范,APIv3基于JSON规范。
APIv2 XML规范
此类通知数据,首先需要对数据XML
文本做转换,得到 集合 $collection,本开发包提供了方法即:
$collection = \WeChatPay\Transformer::toArray($xml);
然后基于 对称算法的通用步骤 计算出签名值,然后对值比对。
验签
历史上,随官方业务的推进,在具体实现上,部分接口signType
默认签名方法是MD5
,部分接口是HMAC-SHA256
,还有部分接口无
签名(原因无从考证),存在即合理,应用端需要以微信支付官方公布的开发文档为准。
use \WeChatPay\Crypto\Hash;
// 对 集合 $collection 做本地运算
Hash::sign(Hash::ALGO_MD5, $something, $apiv2Key);
// 拿运算结果与通知签名值做安全比对
Hash::equals($localCaculated, $remoteProvided);
解密
密文是通过AES-ECB
加密的,密钥是对APIv2密钥做MD5
运算后取值小写的:
//对APIv2密钥做标准MD5取值
$cipherkey = \WeChatPay\Crypto\Hash::md5($apiv2Key);
//对密文做解密
\WeChatPay\Crypto\AesEcb::decrypt($ciphertext, $cipherkey);
应答
纯粹的数据格式转换,使用如下方法即:
\WeChatPay\Transformer::toXml([
'return_code' => 'SUCCESS',
'return_message' => 'OK'
]);
APIv3 JSON规范
此类通知数据,是基于 非对称算法 对请求的载荷
整体做验签,签名值在请求头(headers
)的Wechatpay-Signature
字段里。
验签
//对请求报文做算法格式化
$data = \WeChatPay\Formatter::joinedByLineFeed($body, $timestamp, $nonce);
//格式化后的内容做公钥验签
\WeChatPay\Crypto\Rsa::verify($data, $signature, $publicKeyInstance);
解密
//对请求载荷做转换
['resource' => [
'ciphertext' => $ciphertext,
'nonce' => $nonce,
'associated_data' => $aad
]] = \json_decode($something);
//对`$.resource.ciphertext`做解密
\WeChatPay\Crypto\AesGcm::decrypt($ciphertext, $apiv3Key, $nonce, $aad);
应答
纯粹的数据格式转换,使用内置的json_encode
字符串化即:
\json_encode(['code' => 'SUCCESS']);