# wechat-pay **Repository Path**: s-gaolei/wechat-pay ## Basic Information - **Project Name**: wechat-pay - **Description**: 可简单调用就能实现微信支付 的 PHP 依赖包 - **Primary Language**: PHP - **License**: MIT - **Default Branch**: v3 - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 2 - **Forks**: 0 - **Created**: 2021-04-27 - **Last Updated**: 2025-04-29 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # WehatPay > 可简单调用就能实现的 微信支付 依赖包,使用微信最新的v3 接口 * 需要使用到商户证书 ## 已实现功能 - `JsApi` 微信内网页、小程序支付 - `H5` 微信外网页支付 - `Native` 扫码支付 - `App` App应用支付 - `Refund` 退款申请 - `Close` 关闭订单 - `Notify` 异步回调处理 - 商户平台证书生成 ## 安装方式 ```shell script composer require gaolei/wechat-pay:~v3 ``` ## 使用方式 ### `Config` 配置项 - #### 老版平台证书模式 > `mchCertPath` 路径中需要包含文件协议类型 ```php $config = [ 'mchId' => '1600000001', 'appId' => 'wx00000000000001', 'mchCertNo' => 'BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB', 'mchCertPath' => 'file:///cert/1600000001/apiclient_key.pem', 'wxCertPath' => '/cert/1600000001/wechat_cert.pem', ]; ``` - #### 新版支付公钥模式 > `mchCertPath` 与 `wxPubCertPath` 路径中均需要包含文件协议类型 ```php $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` 商户ID `mchCertNo` 商户证书编号 `mchCertPath` 商户证书路径 `wxCertPath` 平台证书路径,生成方式将在文章末尾进行介绍 ### `JsPay` 公众号网页、小程序支付 ```php 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 调起支付 ```javascript var pkg = JSON.parse(''); 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手机网页支付 ```php 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` 网页扫码支付 ```php 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应用支付 ```php $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` 申请退款 ```php 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` 关闭订单 ```php $wechat = \Gaolei\WechatPay\WechatPay::create($config); $orderNo = '10101010110010101111010'; $rest = $wechat->close($orderNo); if($rest['error'] === null){ // 处理成功 } print_r($rest); echo PHP_EOL; ``` ### `Notify` 异步回调处理 ```php 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); } ``` ## 平台证书生成 > 仅限老版商户号,请注意查看商户号后台 ```php 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); ```