Laravel使用EasyWechat,3分钟完成微信支付
一.准备工作
1.下载微信官方PHP的SDK,里面有个rootca.pem要用到,在php.ini里配置curl.cainfo=你存放rootca.pem的绝对路径,重启PHP
2.composer集成easywechat的laravel版本,具体怎么使用点这里
2.1
composer require "overtrue/laravel-wechat:~3.0"
2.2
Laravel 应用
- 注册
ServiceProvider:
Overtrue\LaravelWechat\ServiceProvider::class,
- 创建配置文件:
php artisan vendor:publish --provider="Overtrue\LaravelWechat\ServiceProvider"
请修改应用根目录下的
config/wechat.php中对应的项即可;(可选)添加外观到
config/app.php中的aliases部分:
'EasyWeChat' => Overtrue\LaravelWechat\Facade::class,
二.创建控制器WechatController.php
或许有些人看到这里有一些懵,讲一下流程:
1.自己创建一个订单(就是数据库里新建一个订单记录,相信谁都会吧。。),这个订单里有金额,购买人的user_id,支付状态status等信息
2.创建好订单后,这时我们就要去微信端申请支付了,目的是申请微信的预支付ID,有了预支付ID才能付款。拿订单id是为了拿到里面的金额money信息,而且还要给这个订单添加一个out_trade_no的字段信息,这个out_trade_no的信息,就是将来微信回调的时候来找你这个订单的。
3.支付完成后,微信会一直POST你的回调地址(注意是post,所以要去中间件里,关掉这个回调地址的csrf验证),这个回调方法就是通过out_trade_no找到这个订单,然后更改订单状态的。
PS:我这里给出的都是function方法,具体路由还是去routes.php需要自己建哦。
<?phpnamespace App\Http\Controllers;use Illuminate\Http\Request;use App\Http\Requests;use App\Http\Controllers\Controller;use Illuminate\Support\Facades\Input;use Auth,Redirect;use Validator;use App\Models\ExampleOrder; //这是我的模型use EasyWeChat\Foundation\Application;use EasyWeChat\Payment\Order;use EasyWeChat;class WechatController extends Controller{protected function options(){ //选项设置return [// 前面的appid什么的也得保留哦'app_id' => 'xxxxxxxxx', //你的APPID'secret' => 'xxxxxxxxx', // AppSecret// 'token' => 'your-token', // Token// 'aes_key' => '', // EncodingAESKey,安全模式下请一定要填写!!!// ...// payment'payment' => ['merchant_id' => '你的商户ID,MCH_ID','key' => '你的KEY',// 'cert_path' => 'path/to/your/cert.pem', // XXX: 绝对路径!!!!// 'key_path' => 'path/to/your/key', // XXX: 绝对路径!!!!'notify_url' => '你的回调地址', // 你也可以在下单时单独设置来想覆盖它// 'device_info' => '013467007045764',// 'sub_app_id' => '',// 'sub_merchant_id' => '',// ...],];}//传入订单ID即可,我这里是通过订单,来查询该订单的金额,当然你也可以自定义金额public function pay(){$id = Input::get('order_id');//传入订单ID$order_find = ExampleOrder::find($id); //找到该订单$mch_id = xxxxxxx;//你的MCH_ID$options = $this->options();$app = new Application($options);$payment = $app->payment;$out_trade_no = $mch_id.date("YmdHis"); //拼一下订单号$attributes = ['trade_type' => 'APP', // JSAPI,NATIVE,APP...'body' => '购买CSDN产品','detail' => $order_find->info, //我这里是通过订单找到商品详情,你也可以自定义'out_trade_no' => $out_trade_no,'total_fee' => $order_find->money*100, //因为是以分为单位,所以订单里面的金额乘以100// 'notify_url' => 'http://xxx.com/order-notify', // 支付结果通知网址,如果不设置则会使用配置里的默认地址// 'openid' => '当前用户的 openid', // trade_type=JSAPI,此参数必传,用户在商户appid下的唯一标识,// ...];$order = new Order($attributes);$result = $payment->prepare($order);if ($result->return_code == 'SUCCESS' && $result->result_code == 'SUCCESS'){$order_find->out_trade_no = $out_trade_no; //在这里更新订单的支付ID$order_find->save();// return response()->json(['result'=>$result]);$prepayId = $result->prepay_id;$config = $payment->configForAppPayment($prepayId);return response()->json($config);}}//下面是回调函数public function paySuccess(){$options = $this->options();$app = new Application($options);$response = $app->payment->handleNotify(function($notify, $successful){// 使用通知里的 "微信支付订单号" 或者 "商户订单号" 去自己的数据库找到订单$order = ExampleOrder::where('out_trade_no',$notify->out_trade_no)->first();if (count($order) == 0) { // 如果订单不存在return 'Order not exist.'; // 告诉微信,我已经处理完了,订单没找到,别再通知我了}// 如果订单存在// 检查订单是否已经更新过支付状态if ($order->pay_time) { // 假设订单字段“支付时间”不为空代表已经支付return true; // 已经支付成功了就不再更新了}// 用户是否支付成功if ($successful) {// 不是已经支付状态则修改为已经支付状态$order->pay_time = time(); // 更新支付时间为当前时间$order->status = 6; //支付成功,} else { // 用户支付失败$order->status = 2; //待付款}$order->save(); // 保存订单return true; // 返回处理完成});}}
大功告成,是不是很EASY呀~
改成微信网页端支付也很简单,多传一个参数open_id,然后把类型改为JSAPI,然后去渲染一个页面就行
public function pay(){$id = Input::get('order_id');//传入订单ID$order_find = ExampleOrder::find($id); //找到该订单$mch_id = xxxxxxx;//你的MCH_ID$options = $this->options();$app = new Application($options);$payment = $app->payment;$out_trade_no = $mch_id.date("YmdHis"); //拼一下订单号$attributes = ['trade_type' => 'JSAPI', // JSAPI,NATIVE,APP...'body' => '购买CSDN产品','detail' => $order_find->info, //我这里是通过订单找到商品详情,你也可以自定义'out_trade_no' => $out_trade_no,'total_fee' => $order_find->money*100, //因为是以分为单位,所以订单里面的金额乘以100// 'notify_url' => 'http://xxx.com/order-notify', // 支付结果通知网址,如果不设置则会使用配置里的默认地址'openid' => '当前用户的 openid', // trade_type=JSAPI,此参数必传,用户在商户appid下的唯一标识,// ...];$order = new Order($attributes);$result = $payment->prepare($order);if ($result->return_code == 'SUCCESS' && $result->result_code == 'SUCCESS'){$order_find->out_trade_no = $out_trade_no; //在这里更新订单的支付ID$order_find->save();// return response()->json(['result'=>$result]);$prepayId = $result->prepay_id;$config = $payment->configForAppPayment($prepayId);return response()->json($config);}}
渲染页面的方法
public function payOrder(){ //支付订单页面$order_id = Input::get('order_id');$order = ExampleOrder::find($order_id);$config = $this->payment($order->pay_id);$js = EasyWeChat::js();return view('home.mobile.pay_order')->withConfig($config)->withJs($js)->withOrder($order);}
然后前端实现
<div><h1>支付{{$order->money}}元</h1><br><input type="button" value="支付" id="pay"></div><script src="https://res.wx.qq.com/open/js/jweixin-1.0.0.js" type="text/javascript" charset="utf-8"></script><script type="text/javascript" charset="utf-8">wx.config(<?php echo $js->config(array('chooseWXPay'), false) ?>); //这里改成true就可以打开微信js的调试模式// wx.ready(function(){// wx.chooseWXPay({// timestamp: {{$config["timestamp"]}},// nonceStr: '{{$config["nonceStr"]}}',// package: '{{$config["package"]}}',// signType: '{{$config["signType"]}}',// paySign: '{{$config["paySign"]}}', // 支付签名// success: function (res) {// // 支付成功后的回调函数// window.location.href='/myorder';// }// });// });$('#pay').click(function(){wx.chooseWXPay({timestamp: {{$config['timestamp']}},nonceStr: '{{$config['nonceStr']}}',package: '{{$config['package']}}',signType: '{{$config['signType']}}',paySign: '{{$config['paySign']}}', // 支付签名success: function (res) {// 支付成功后的回调函数window.location.href='/mobile';}});});</script>
赞 (0)
