gaolei / wechat-pay
可简单调用就能实现的微信支付 PHP 依赖包
v3.0.6
2024-12-23 11:19 UTC
Requires
- php: >=7.2
- ext-curl: *
- ext-json: *
- ext-libxml: *
- ext-openssl: *
- ext-simplexml: *
- wechatpay/wechatpay: 1.4.10
README
可简单调用就能实现的 微信支付 依赖包,使用微信最新的v3 接口
* 需要使用到商户证书
已实现功能
JsApi
微信内网页、小程序支付H5
微信外网页支付Native
扫码支付App
App应用支付Refund
退款申请Close
关闭订单Notify
异步回调处理- 商户平台证书生成
安装方式
composer require gaolei/wechat-pay:~v3
使用方式
Config
配置项
老版平台证书模式
mchCertPath
路径中需要包含文件协议类型$config = [ 'mchId' => '1600000001', 'appId' => 'wx00000000000001', 'mchCertNo' => 'BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB', 'mchCertPath' => 'file:///cert/1600000001/apiclient_key.pem', 'wxCertPath' => '/cert/1600000001/wechat_cert.pem', ];
新版支付公钥模式
mchCertPath
与wxPubCertPath
路径中均需要包含文件协议类型$config = [ 'mchId' => '1600000001', 'appId' => 'wx00000000000001', 'mchCertNo' => 'BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB', 'mchCertPath' => 'file:///certs/1600000001/apiclient_key.pem', 'wxPubCertNo' => 'PUB_KEY_ID_BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB', 'wxPubCertPath' => 'file:///certs/1600000001/pub_key.pem', ];
- 下方未指定
$config
参数的代码均使用上方的 $config 作为配置参数
这里解释一下,
mchId
商户IDmchCertNo
商户证书编号mchCertPath
商户证书路径wxCertPath
平台证书路径,生成方式将在文章末尾进行介绍
JsPay
公众号网页、小程序支付
use Gaolei\WechatPay\WechatPay;
$resp = WechatPay::create($config)->jsPay([
'attach' => 'attach', // 订单数据包(字符串),异步返回回原样携带
'title' => '支付测试', // 订单展示标题
'order' => 'jspay-' . time(), // 你的订单编号
'amount' => 0.01, // 单位 元
'time_expire' => 6, // 订单超时时间(分钟),取值范围为[6,30],区间外默认 6 分钟
'notify' => 'https://xx.cn/xx', // 支付成功之后的 异步通知地址
'payer' => [
'openid' => 'os1-a59lxlc7GyF2zc03j4y8bZoY'
]
]);
print_r($resp);
$package = json_encode($resp["body"]["pkg"]);
jsapi 调起支付
var pkg = JSON.parse('<?php echo $package; ?>');
function onBridgeReady(){
WeixinJSBridge.invoke('getBrandWCPayRequest', pkg, function (res){
console.log(res)
if (res.err_msg == "get_brand_wcpay_request:ok") {
// 使用以上方式判断前端返回,微信团队郑重提示:
//res.err_msg将在用户支付成功后返回ok,但并不保证它绝对可靠。
alert('支付成功')
}
});
}
if (typeof WeixinJSBridge == "undefined") {
if (document.addEventListener) {
document.addEventListener('WeixinJSBridgeReady', onBridgeReady, false);
}else if (document.attachEvent) {
document.attachEvent('WeixinJSBridgeReady', onBridgeReady);
document.attachEvent('onWeixinJSBridgeReady', onBridgeReady);
}
}else{
onBridgeReady();
}
H5Pay
h5手机网页支付
use Gaolei\WechatPay\WechatPay;
$resp = WechatPay::create($config)->h5Pay([
'attach' => 'attach', // 订单数据包(字符串),异步返回回原样携带
'title' => '支付测试', // 订单展示标题
'order' => 'h5pay-'.time(), // 你的订单编号
'amount' => 0.01, // 单位 元
'time_expire' => 6, // 订单超时时间(分钟),取值范围为[6,30],区间外默认 6 分钟
'notify' => 'https://xx.cn/xx', // 支付成功之后的 异步通知地址
'scene_info' => [
"payer_client_ip" => "39.144.137.172",
'h5_info' => [
'type' => 'Wap'
]
]
]);
var_dump($resp);
直接跳转到返回数据中的网页路径即可发起支付
Native
网页扫码支付
use Gaolei\WechatPay\WechatPay;
$resp = WechatPay::create($config)->native([
'attach' => 'attach', // 订单数据包(字符串),异步返回回原样携带
'title' => '支付测试', // 订单展示标题
'order' => 'native-'.time(), // 你的订单编号
'amount' => 0.01, // 单位 元
'time_expire' => 10, // 订单超时时间(分钟),取值范围为[6,30],区间外默认 6 分钟
'notify' => 'https://xx.cn/xx', // 支付成功之后的 异步通知地址
]);
var_dump($resp);
AppPay
App应用支付
$wechat = \Gaolei\WechatPay\WechatPay::create($config);
$order = 'h5pay-' . time();
$pack = $wechat->appPay([
'attach' => 'attach', // 订单数据包(字符串),异步返回回原样携带
'title' => '支付测试', // 订单展示标题
'order' => $order, // 你的订单编号
'amount' => 0.01, // 单位 元
'time_expire' => 6, // 订单超时时间(分钟),取值范围为[6,30],区间外默认 6 分钟
'notify' => 'https://xx.cn/xx', // 支付成功之后的 异步通知地址
]);
echo $order.PHP_EOL;
print_r($pack);
print_r(json_encode($pack['body']['pkg']));
Refund
申请退款
use Gaolei\WechatPay\WechatRefund;
$config = [
'mchId' => '1600000001',
'mchCertNo' => 'BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB',
'mchCertPath' => 'file:///Users/user/cert/1600000001/apiclient_key.pem',
'wxCertPath' => '/Users/user/cert/1600000001/wechat_cert.pem',
];
$config = [
'mchId' => '1600000001',
'mchCertNo' => 'XXXXXXXXXXX43EE9B706180FB6675130DAAA',
'mchCertPath' => 'file://' . __DIR__ . '/certs/1600000001/apiclient_key.pem',
'wxPubCertNo' => 'PUB_KEY_ID_xxxxxxxxxxxxxxxxxxxxxx',
'wxPubCertPath' => 'file://' . __DIR__ . '/certs/1600000001/pub_key.pem',
];
$wechat = WechatRefund::create($config);
// 商家退款编号
$refundNo = 'refund-' . time();
$refundParams = [
'reason' => '测试退款', // 退款原因,可选参数
'order_no' => 'native-1627643208',
'order_amount' => 0.01, // 订单金额 单位元[人民币]
'refund_no' => $refundNo,
'refund_amount' => 0.01, // 退款金额 单位元[人民币]
'notify_url' => 'https://xx.cn/xx', // 成功之后的 异步通知地址
];
$resp = $wechat->refund($refundParams);
print_r($resp);
Close
关闭订单
$wechat = \Gaolei\WechatPay\WechatPay::create($config);
$orderNo = '10101010110010101111010';
$rest = $wechat->close($orderNo);
if($rest['error'] === null){
// 处理成功
}
print_r($rest);
echo PHP_EOL;
Notify
异步回调处理
use Gaolei\WechatPay\WechatPay;
$pack = json_decode(file_get_contents('php://input'), true);
print_r($pack);
$resource = $pack['resource'];
// 商户 apiKeyv3
$apiV3Key = '04F8B9AA596F9F704CE6ECE35CE627AC';
$resource = WechatPay::decryptToString($apiV3Key,$resource['associated_data'], $resource['nonce'], $resource['ciphertext']);
if($resource['error']){
print_r($resource);
die;
}
[$eventType, $eventStatus] = explode('.', $pack['event_type']);
$resourceType = $pack['resource_type'];
print_r($resource);
if($eventType === 'REFUND'){
// 退款回调
/**
* $resource['package'] 示例值
* {
"mchid": "1900000100",
"transaction_id": "1008450740201411110005820873",
"out_trade_no": "20150806125346",
"refund_id": "50200207182018070300011301001",
"out_refund_no": "7752501201407033233368018",
"refund_status": "SUCCESS",
"success_time": "2018-06-08T10:34:56+08:00",
"user_received_account": "招商银行信用卡0403",
"amount" : {
"total": 999,
"refund": 999,
"payer_total": 999,
"payer_refund": 999
}
* }
*
*/
} elseif($eventType === 'TRANSACTION'){
// 支付回调
/**
* $resource['package'] 示例值
* {
"transaction_id":"1217752501201407033233368018",
"amount":{
"payer_total":100,
"total":100,
"currency":"CNY",
"payer_currency":"CNY"
},
"mchid":"1230000109",
"trade_state":"SUCCESS",
"bank_type":"CMC",
"success_time":"2018-06-08T10:34:56+08:00",
"payer":{
"openid":"oUpF8uMuAJO_M2pxb1Q9zNjWeS6o"
},
"out_trade_no":"1217752501201407033233368018",
"appid":"wxd678efh567hg6787",
"trade_state_desc":"支付成功",
"trade_type":"MICROPAY",
"attach":"自定义数据",
"scene_info":{
"device_id":"013467007045764"
}
* }
*
*/
$info = WechatPay::getPayRespByResource($resource['package']);
print_r($info);
}
平台证书生成
仅限老版商户号,请注意查看商户号后台
use Gaolei\WechatPay\WechatCert;
$mchId = '你的商户ID'; // 例:'1600000001'
$apiV3Key = '你的V3接口秘钥'; // 例:'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
$mchCertNo = '你的商户证书编号'; // 例: 'BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB'
$mchCertPath = '商户证书文件地址'; // 例: '/Users/user/cert/1600000001/apiclient_key.pem'
$certSavePath = '证书保存路径[目录]'; // 例: ./ 或 ./wechat_cert.pem
$res = WechatCert::generate($mchId,$apiV3Key,$mchCertNo,$mchCertPath,$certSavePath);
var_dump($res);