PHP 微信支付V3
发布时间:2024-12-01, 16:12:53 分类:PHP | 编辑 off 网址 | 辅助
正文 3232字数 12,993阅读
1.使用 PHP 包管理工具 Composer 安装 SDK:
composer require wechatpay/wechatpay
Run code
Cut to clipboard
3.获取微信支付平台证书
在服务器上进入PHP项目,进入vendor/bin/目录
在服务器上进入PHP项目,进入vendor/bin/目录
-k:apiv3秘钥
-m:商户号
-f:微信商户API私钥文件目录
-s:证书序列号
-o:生成后的证书保存地址
php CertificateDownloader.php -k ${apiV3key} -m ${mchId} -f ${mchPrivateKeyFilePath} -s ${mchSerialNo} -o ${outputFilePath}
例如:
php CertificateDownloader.php -k 241054wsd5we14586esfwqsfjke25344 -m 1600789654 -f /app/file/wxCert/apiclient_key.pem -s WB0E676A11B907E25875FCCBB15151637E4 -o /app/file/wxCert/
Run code
Cut to clipboard
4.构造一个APIV3客户端实例
<?php
require_once('vendor/autoload.php');
use WeChatPay\Builder;
use WeChatPay\Crypto\Rsa;
use WeChatPay\Util\PemUtil;
// 设置参数
// 商户号
$merchantId = '190000****';
// 从本地文件中加载「商户API私钥」,步骤2生成的API私钥文件
$merchantPrivateKeyFilePath = 'file:///path/to/merchant/apiclient_key.pem';
$merchantPrivateKeyInstance = Rsa::from($merchantPrivateKeyFilePath, Rsa::KEY_TYPE_PRIVATE);
// 「商户API证书」的「证书序列号」,步骤2生成的序列号
$merchantCertificateSerial = '3775B6A45ACD588826D15E583A95F5DD********';
//「微信支付平台证书」,步骤3生成的证书
$platformCertificateFilePath = 'file:///path/to/wechatpay/cert.pem';
$platformPublicKeyInstance = Rsa::from($platformCertificateFilePath, Rsa::KEY_TYPE_PUBLIC);
// 从「微信支付平台证书」中获取「证书序列号」,步骤3生成的证书
$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;
Run code
Cut to clipboard
5.APP支付下单为例
try {
$resp = $instance
->chain('v3/pay/transactions/app')
->post(['json' => [
'mchid' => '1900006XXX',
'out_trade_no' => 'native12177525012014070332333',
'appid' => 'wxdace645e0bc2cXXX',
'description' => 'Image形象店-深圳腾大-QQ公仔',
'notify_url' => 'https://weixin.qq.com/',
'amount' => [
'total' => 1,
'currency' => 'CNY'
],
]]);
echo $resp->getStatusCode(), PHP_EOL;
echo $resp->getBody(), PHP_EOL;
} catch (\Exception $e) {
// 进行错误处理
echo $e->getMessage(), PHP_EOL;
if ($e instanceof \GuzzleHttp\Exception\RequestException && $e->hasResponse()) {
$r = $e->getResponse();
echo $r->getStatusCode() . ' ' . $r->getReasonPhrase(), PHP_EOL;
echo $r->getBody(), PHP_EOL, PHP_EOL, PHP_EOL;
}
echo $e->getTraceAsString(), PHP_EOL;
}
Run code
Cut to clipboard
6.注意
1.若运行中出现如下错误:Cannot load privateKey from(string), please take care about the \\$thing input.
需要在文件前面添加 file://
例如:
2.若出现签名错误:
先自己查看商户API证书,API序列号,APIV3秘钥,商户号,微信平台证书是否一致,确保一致后还是出现签名错误,则可以验签。
1.若运行中出现如下错误:Cannot load privateKey from(string), please take care about the \\$thing input.
需要在文件前面添加 file://
例如:
$merchantPrivateKeyFilePath = 'file://'.私钥文件目录;
Run code
Cut to clipboard
2.若出现签名错误:
先自己查看商户API证书,API序列号,APIV3秘钥,商户号,微信平台证书是否一致,确保一致后还是出现签名错误,则可以验签。
(支付宝)给作者钱财以资鼓励 (微信)→
有过 2 条评论 »
1. 确认使用公钥模式
在接入微信支付时,确保选择公钥模式(RSA 或 RSA2)进行签名和验证。微信支付官方文档会提供详细的公钥生成和使用方法。
2. 生成公钥和私钥
使用工具生成 RSA 密钥对(公钥和私钥)。
将生成的公钥上传到微信商户平台。
保留好私钥,用于在本地生成签名。
生成密钥对的工具:
OpenSSL
在线生成工具(注意安全性)
编程语言中的加密库(如 Python 的 cryptography 库)
生成 RSA 密钥对的命令(OpenSSL):
# 生成私钥 openssl genpkey -algorithm RSA -out private_key.pem -pkeyopt rsa_keygen_bits:2048 # 从私钥中提取公钥 openssl rsa -in private_key.pem -pubout -out public_key.pem
3. 上传公钥到微信商户平台
登录微信商户平台,进入「API安全」页面。
找到「API 密钥」或「公钥管理」,将生成的 public_key.pem 文件内容上传。
4. 在代码中使用私钥进行签名
在开发过程中,使用本地保存的私钥对请求数据进行签名。
将签名结果作为请求参数发送给微信支付 API。
Python 示例:
from cryptography.hazmat.primitives import hashes from cryptography.hazmat.primitives.asymmetric import padding from cryptography.hazmat.primitives import serialization # 加载私钥 with open("private_key.pem", "rb") as key_file: private_key = serialization.load_pem_private_key( key_file.read(), password=None ) # 待签名字符串 data_to_sign = "your_data_to_sign" # 生成签名 signature = private_key.sign( data_to_sign.encode('utf-8'), padding.PKCS1v15(), hashes.SHA256() ) # 将签名转换为 Base64 编码 import base64 signature_base64 = base64.b64encode(signature).decode('utf-8') print("Signature:", signature_base64)
5. 验证微信支付的回调
当微信支付回调时,使用微信支付提供的公钥验证回调数据的签名。
确保回调数据未被篡改。
Python 示例:
from cryptography.hazmat.primitives import hashes from cryptography.hazmat.primitives.asymmetric import padding from cryptography.hazmat.primitives import serialization # 加载微信支付的公钥 with open("wechat_public_key.pem", "rb") as key_file: public_key = serialization.load_pem_public_key( key_file.read() ) # 回调数据和签名 callback_data = "your_callback_data" received_signature = base64.b64decode("received_signature_base64") # 验证签名 try: public_key.verify( received_signature, callback_data.encode('utf-8'), padding.PKCS1v15(), hashes.SHA256() ) print("Signature is valid") except Exception as e: print("Signature is invalid:", e)
6. 注意事项
私钥安全:私钥是核心敏感数据,必须妥善保管,切勿泄露。
公钥格式:上传到微信商户平台的公钥必须是 PEM 格式。
签名算法:微信支付支持 RSA 和 RSA2 算法,推荐使用 RSA2(SHA-256)。
版本兼容性:确保使用的 SDK 或库支持公钥模式。
7. 参考文档
微信支付官方文档:https://pay.weixin.qq.com/wiki/doc/apiv3/wechatpay/wechatpay4_0.shtml
微信支付 API 安全指南:https://pay.weixin.qq.com/wiki/doc/apiv3/wechatpay/wechatpay4_1.shtml
通过以上步骤,你可以顺利完成微信支付的公钥模式接入。如果遇到问题,可以参考微信支付官方文档或联系微信支付技术支持。