本来想手写,但是有sdk 就没必要这么麻烦。
composer地址:wechatpay/wechatpay - Packagist
微信官网sdk,给的是github,打不开。
一 sdk使用
<?php
require_once 'vendor/autoload.php';
defined('ROOT_PATH') or define('ROOT_PATH', './');
use WeChatPay\Builder;
use WeChatPay\Crypto\Rsa;
use WeChatPay\Util\PemUtil;
class Test
{
public function payconfig2()
{
$config = [
'appid' => 'appid',
'mchid' => '商户号',
'key' => 'key',
'serial_no' => '证书序列号',
];
return $config;
}
private function getpems()
{
$arr = [
'SSLCERT' => ROOT_PATH . "/cert/apiclient_cert.pem",
'SSLKEY' => ROOT_PATH . "/cert/apiclient_key.pem",
];
return $arr;
}
public function dotest()
{
$pems = $this->getpems();
$config = $this->payconfig2();
$merchantPrivateKeyFilePath = file_get_contents($pems['SSLKEY']);
$merchantPrivateKeyInstance = Rsa::from($merchantPrivateKeyFilePath, Rsa::KEY_TYPE_PRIVATE);
// 「商户API证书」的「证书序列号」
$merchantCertificateSerial = $config['serial_no'];
$merchantId = $config['mchid'];
// 从本地文件中加载「微信支付平台证书」,用来验证微信支付应答的签名
$platformCertificateFilePath = file_get_contents($pems['SSLCERT']);
$platformPublicKeyInstance = Rsa::from($platformCertificateFilePath, Rsa::KEY_TYPE_PUBLIC);
// 从「微信支付平台证书」中获取「证书序列号」
$platformCertificateSerial = PemUtil::parseCertificateSerialNo($platformCertificateFilePath);
// 构造一个 APIv3 客户端实例
$instance = Builder::factory([
'mchid' => $merchantId,
'serial' => $merchantCertificateSerial,
'privateKey' => $merchantPrivateKeyInstance,
'certs' => [
$platformCertificateSerial => $platformPublicKeyInstance,
],
]);
// 发送请求
$resp = $instance->chain('v3/certificates')->get(
['debug' => true]// 调试模式,https://docs.guzzlephp.org/en/stable/request-options.html#debug
);
echo $resp->getBody(), PHP_EOL;
}
}
$t = new Test();
$t->dotest();
证书序列号需要去商户平台看。
其次这个key有v2、v3之分。问过别人这俩版本不共用。
- 文件名是 apiclient_key.pem 的,是 「商户私钥」文件
- 文件名是 apiclient_cert.pem 的,是 「商户证书」文件
二 证书生成
上面例子中用的SSLCERT证书可以用于退款,是从微信后台直接生成。而支付的证书需要使用这个框架中的代码生成。
详见:https://github.com/wechatpay-apiv3/wechatpay-php
composer exec CertificateDownloader.php -- -k ${apiV3key} -m ${mchId} -f ${mchPrivateKeyFilePath} -s ${mchSerialNo} -o ${outputFilePath}
必须linux环境下运行,windows环境下运行不会生成证书。
将生成的证书替换SSLCERT的值,就能正常运行了~ 因为是新生成的证书,不影响旧的证书,即不影响旧证书涉及的其他问题。
三 参考
微信支付:API商户证书序列号serialNo获取-YES开发框架网