1.引入SDK到项目中
composer require wechatpay/wechatpay-guzzle-middleware
2.引入Guzzle,Guzzle 将使用 PHP 流包装器发送 HTTP 请求
composer require guzzlehttp/guzzle:^7.0
3.在控制器中使用
use GuzzleHttp\Exception\RequestException;
use WechatPay\GuzzleMiddleware\WechatPayMiddleware;
use WechatPay\GuzzleMiddleware\Util\PemUtil;
// 商户相关配置
$merchantId = '1000100'; // 商户号
$merchantSerialNumber = 'XXXXXXXXXX'; // 商户API证书序列号
$merchantPrivateKey = PemUtil::loadPrivateKey('/path/to/mch/private/key.pem'); // 商户私钥
// 微信支付平台配置
$wechatpayCertificate = PemUtil::loadCertificate(app()->getRootPath().'/wechatpay_56E4BDC5960BB32054738D302C1943DD8630FA25.pem'); // 微信支付平台证书文件路径(我放在了项目根目录)
// 构造一个WechatPayMiddleware
$wechatpayMiddleware = WechatPayMiddleware::builder()
->withMerchant($merchantId, $merchantSerialNumber, $merchantPrivateKey) // 传入商户相关配置
->withWechatPay([ $wechatpayCertificate ]) // 可传入多个微信支付平台证书,参数类型为array
->build();
// 将WechatPayMiddleware添加到Guzzle的HandlerStack中
$stack = \GuzzleHttp\HandlerStack::create();
$stack->push($wechatpayMiddleware, 'wechatpay');
// 创建Guzzle HTTP Client时,将HandlerStack传入
$client = new \GuzzleHttp\Client(['handler' => $stack]);
// 创建Guzzle HTTP Client时,将HandlerStack传入,接下来,正常使用Guzzle发起API请求,WechatPayMiddleware会自动地处理签名和验签
$client = new \GuzzleHttp\Client(['handler' => $stack]);
try {
$resp = $client->request(
'POST',
'https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi', //请求URL
[
// JSON请求体
'json' => [
"time_expire" => "2023-03-15T10:34:56+08:00",
"amount" => [
"total" => 10,
"currency" => "CNY",
],
"mchid" => "16388714xx",
"description" => "测试",
"notify_url" => "https://xxx.com/admin/Login/notifyUrlApi",
"payer" => [
"openid" => "22CBI5G1ILObeNu1oHhGjLI7k2Cs",
],
"out_trade_no" => "1217752501201407033233368018",
"goods_tag" => "WXG",
"appid" => "wx2d5db4945b8537xx",
"attach" => "自定义数据说明",
"scene_info" => [
"store_info" => [
"address" => "广东省深圳市南山区科技中一道10000号",
"area_code" => "440305",
"name" => "腾讯大厦分店",
"id" => "0001",
],
"device_id" => "013467007045764",
"payer_client_ip" => "14.23.150.211",
]
],
'headers' => [ 'Accept' => 'application/json' ]
]
);
$statusCode = $resp->getStatusCode();
if ($statusCode == 200) { //处理成功
echo "success,return body = " . $resp->getBody()."\n";
} else if ($statusCode == 204) { //处理成功,无返回Body
echo "success";
}
} catch (RequestException $e) {
// 进行错误处理
echo $e->getMessage()."\n";
if ($e->hasResponse()) {
echo "failed,resp code = " . $e->getResponse()->getStatusCode() . " return body = " . $e->getResponse()->getBody() . "\n";
}
return;
}
注意!!!:上面代码中配置证书不是商户公钥,一定要记住!!!下面是此配置讲解
// 微信支付平台配置
$wechatpayCertificate = PemUtil::loadCertificate('/path/to/wechatpay/cert.pem'); // 微信支付平台证书
微信支付平台证书 获取方式:
composer exec CertificateDownloader.php -- -k ${apiV3key} -m ${mchId} -f ${mchPrivateKeyFilePath} -s ${mchSerialNo} -o ${outputFilePath}
Options:
-m, --mchid=<merchantId> 商户号
-s, --serialno=<serialNo> 商户证书的序列号
-f, --privatekey=<privateKeyFilePath>
商户的私钥文件
-k, --key=<apiV3key> ApiV3Key
-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.
例如:composer exec CertificateDownloader.php -- -k 123456789098765432116606169225 -m 1638871484 -f file:///www/wwwroot/daidai.qhwoyoung.com/apiclient_key.pem -s 7823EA0FFC9160F49C21F61ED277FC0A7A78410C -o file:///www/wwwroot/daidai.qhwoyoung.com/
回调函数处理:
public function notifyUrlApi()
{
//接收返回数据
$wechatRes = file_get_contents('php://input', 'r');
$res = json_decode($wechatRes, true);
$text =base64_decode($res['resource']['ciphertext']);
//env("KEY") -> 获取的是v3设置的密钥
$new = sodium_crypto_aead_aes256gcm_decrypt($text,$res['resource']['associated_data'],$res['resource']['nonce'],env("KEY"));
$new = json_decode($new, true);
if ($new['trade_state'] == 'SUCCESS') {
//成功后操作流程写这里。。。
echo '执行成功';
$str='<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>';
}else{
$str='<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[签名失败]]></return_msg></xml>';
}
return $str;
}