Laravel+easywechat 实现公众号微信支付 | Laravel China 社区
laravel 项目直接在终端跑以下命令:
composer require overtrue/wechat:~4.0
然后创建配置文件:
php artisan vendor:publish --provider="Overtrue\LaravelWeChat\ServiceProvider"
创建配置文件完成后会在你项目的 config 文件夹下生成一个 wechat.php 的文件
编辑 wechat.php,这截图的是默认屏蔽的,看你个人需要释放相关代码。并填上相关参数,app_id,mch_id 等等。可在.env 里面配置,如果觉得麻烦可直接写在 default 里面。至此所有准备工作完毕。
代码块
1,laravel 路由
Route::middleware('wechat.oauth', 'wechat')->group(function () { Route::get('/pay', 'CourseController@pay');//支付路由 }); Route::post('/order/notify', 'OrderController@notify');//回调路由
注意
1.1,回调路由必须在 middleware 中间件路由外面,否则微信请求不到。
1.2,回调路由必须是 post 请求。
1.3,laravel 框架必须取消回调路由的 csrf 防护。在你项目的 app/Http/Middleware/VerifyCsrfToken.php 中加入如下代码:
protected $except = [ 'order/notify',//回调路由取消csrf防护 ];
2,支付流程
2.1,点击支付按钮,ajax 提交相应参数到后台支付方法。
2.2,后台接收数据,往你的订单表里插入一条订单数据,状态为 0,也就是未支付状态。
2.3,带上这条订单的订单号,价格,请求微信换取 prepay_id。
2.4,请求微信成功会返回支付所需要的参数,appid,timestamp 等。返回前端 js 调起支付。
2.5,支付后微信会将支付结果通过回调返回,可根据返回信息更改订单状态,或者进行其他操作。
3,项目代码
3.1,前端 js 代码:
var a; $('.pay').click(function () { var course_id=$(this).val();//购买商品的id var price=$('.price').text();//购买商品的价格 $.ajax({ type:"GET", url:"/wechat/course/pay", data:{course_id:course_id,price:price}, success:function (config) { a = config;//请求微信成功返回的支付参数 callpay() } }) }); //调用微信JS api 支付 function jsApiCall() { WeixinJSBridge.invoke( 'getBrandWCPayRequest', a, function (res) { WeixinJSBridge.log(res.err_msg); if (res.err_msg == 'get_brand_wcpay_request:ok') { window.location.reload(); } else { // alert('取消支付'); } } ); } function callpay() { if (typeof WeixinJSBridge == "undefined") { if (document.addEventListener) { document.addEventListener('WeixinJSBridgeReady', jsApiCall, false); } else if (document.attachEvent) { document.attachEvent('WeixinJSBridgeReady', jsApiCall); document.attachEvent('onWeixinJSBridgeReady', jsApiCall); } } else { jsApiCall(); } }
3.2,控制器代码:
//微信支付 public function pay(Request $request) { $customer = session('wechat.customer'); $customer_id = $customer['id']; $price = $request->get('price'); $order = PcOrder::create([ 'user_id' => $customer_id, 'out_trade_no' => date('Ymd') . str_pad(mt_rand(1, 99999), 5, '0', STR_PAD_LEFT) . rand(1000, 9999), 'total_price' => $price, 'status' => 0,//0未支付 1已支付 'course_id' => $request->get('course_id'), ]); $original = session('wechat.oauth_user.default.original'); $openid = $original['openid']; $payment = \EasyWeChat::payment(); // 微信支付实例 $total_fee = $price * 100;//微信支付以分为单位 //统一下单 $result = $payment->order->unify([ 'body' => '微信支付', 'out_trade_no' => $order['out_trade_no'], 'total_fee' => $total_fee, 'notify_url' => 'https://www.********.com/order/notify', //回调地址,用于接收微信支付结果 'trade_type' => 'JSAPI', 'openid' => $openid, ]); if ($result['result_code'] == 'SUCCESS' && $result['return_code'] == 'SUCCESS') { $prepayId = $result['prepay_id']; $jssdk = $payment->jssdk; $config = $jssdk->sdkConfig($prepayId); return $config; } else { return $result; } }
注意
1,如果支付时出现报错,timestame 参数问题。这是 easywechat 底层文件出错了。
解决办法:在你项目的 vendor/overtrue/wechat/src/Payment/Jssdk/Client.php 中把第 70 行和第 71 行代码屏蔽了就行。
3.3,回调代码:
/** * 微信测评支付回调方法,修改订单状态 * @return mixed */ public function notify() { $payment = \EasyWeChat::payment(); $response = $payment->handlePaidNotify(function ($message, $fail) { if ($message['return_code'] === 'SUCCESS' && $message['result_code'] === 'SUCCESS') { \Log::debug($message); PcOrder::where('out_trade_no', $message['out_trade_no'])->update(['status' => 1, 'pay_time' => time()]);//更改订单状态 //支付后,微信会在此处返回支付状态,就是$message,回调里面打印不出来,可通过写入日志里面查看,支付成功后更改订单状态。当然你也可以进行其他操作。 return true; } else { \Log::debug('我不买了'); return $fail('失败'); } }); return $response; }
3.4,回调日志:
[2019-11-27 19:00:03] local.DEBUG: array ( 'appid' => '**************', 'bank_type' => 'CFT', 'cash_fee' => '1', 'fee_type' => 'CNY', 'is_subscribe' => 'Y', 'mch_id' => '*************', 'nonce_str' => '*******', 'openid' => '*****************', 'out_trade_no' => '20191127733582017', 'result_code' => 'SUCCESS', 'return_code' => 'SUCCESS', 'sign' => '************', 'time_end' => '20191127190001', 'total_fee' => '1', 'trade_type' => 'JSAPI', 'transaction_id' => '**************', )
结束
1,本人是一个萌新 php,很多都不懂,这是我上班时碰到的问题,所以记录下来,希望对和我一样的新手有所帮助,如有疑问评论即可。
2,大佬们看到此文章如有错误之处请多多指教,万分感谢。
本作品采用《CC 协议》,转载必须注明作者和本文链接