使用指南
此开发包承载了三部分内容,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']);