博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
laravel5.5+laravel-wechat3.0微信公众号支付
阅读量:6080 次
发布时间:2019-06-20

本文共 5992 字,大约阅读时间需要 19 分钟。

  hot3.png

    前段时间一个朋友使用laravel5.5框架做微信公众号的开发,项目引用了overtrue的laravel-wechat3.0插件,然后让我帮他接入微信支付。在浏览众多相关的文档及尝试了各路开发者的案例后,功夫不负有心人,成功完成了任务,下面是我简单而又详细的介绍接入微信公众号支付的流程(附完整源码):

    接入微信支付的准备工作我就不一一说明了,无非是申请微信的服务号并认证,申请开通微信支付,然后分别登录微信公众平台和商户平台进行相关信息的获取与配置了。建议先行阅读官方的微信公众号支付文档。

    1、发起生成订单的ajax请求(可忽略)

function generate_order() {        $.ajax({            type: 'POST',            url: '/order/generateorder',            data: { id : '{
{$goods->id}}', buy_count : $('.shu').text(),_token:'{
{csrf_token()}}'}, dataType: 'json', success: function(data){ // console.log(data.msg); let url_pre = '{
{url("wxpay/orderpay")}}'; window.location.href = url_pre + "/" + data.order_id; }, error: function(xhr, type){ alert('Ajax error!'); } }); }

上面的function的作用:生成一个订单,成功即跳到后台payOrder函数,路由设置:

Route::get('wxpay/orderpay/{id}','mobile\WxPayController@payOrder');

2、下面是mobile\WxPayController控制器代码:

'xxx', //你的APPID 'secret' => 'xxx', // AppSecret 'token' => 'xxx', // Token 'aes_key' => 'xxx', // EncodingAESKey,安全模式下请一定要填写!!! // ... // payment 'payment' => [ 'merchant_id' => 'xxx', // 微信支付商户号 'key' => 'xxx',// API秘钥 'cert_path' => '/usr/local/nginx/cert/apiclient_cert.pem', // XXX: 绝对路径!!!! 'key_path' => '/usr/local/nginx/cert/apiclient_key.pem', // XXX: 绝对路径!!!! 'notify_url' => url("wxpay/notify"), //你的回调地址 你也可以在下单时单独设置来想覆盖它 // 'device_info' => '013467007045764', // 'sub_app_id' => '', // 'sub_merchant_id' => '', // ... ], ]; } public function payOrder($order_id) { //支付订单页面 //$order_id = Input::get('id'); $order_find = \App\Http\Models\Order::find($order_id); if(empty($order_find)) return Redirect::back()->withInput()->withErrors('该订单无效!'); //$js = EasyWeChat::js(); $options = $this->options(); $app = new Application($options); $payment = $app->payment; $out_trade_no = md5(uniqid().microtime()); //拼一下商户订单号 $user = (session('wechat.oauth_user'))->toArray(); $attributes = [ 'trade_type' => 'JSAPI', // JSAPI,NATIVE,APP... 'body' => '商品支付', 'detail' => '商品详情', //商品详情,你也可以自定义 'out_trade_no' => $out_trade_no, //商户订单号 'total_fee' => $order_find->order_amount*100, //因为是以分为单位,所以订单里面的金额乘以100 // 'notify_url' => 'http://xxx.com/order-notify', // 支付结果通知网址,如果不设置则会使用配置里的默认地址 'openid' => $user['original']['openid'], // trade_type=JSAPI,此参数必传,用户在商户appid下的唯一标识,当前用户的 openid // ... ]; $order = new Order($attributes); $result = $payment->prepare($order); if ($result->return_code == 'SUCCESS' && $result->result_code == 'SUCCESS') { $res1 = DB::table('order') ->where('id', $order_id) ->update(['out_trade_no' => $out_trade_no]);//在这里更新订单的支付ID // return response()->json(['result'=>$result]); $prepayId = $result->prepay_id; $config = $payment->configForJSSDKPayment($prepayId); $js = $app->js; // 这个是jssdk里页面上需要用到的js参数信息。 return view('mobile.wxpay.payOrder') ->withConfig($config) ->withJs($js) ->withOrder($order_find); } } //下面是回调函数 public function notify(Request $request) {// Log::info('come in notify()'); $options = $this->options(); $app = new Application($options); $response =$app->payment->handleNotify(function($notify, $successful){ // 使用通知里的 "微信支付订单号" 或者 "商户订单号" 去自己的数据库找到订单 $order = \App\Http\Models\Order::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) {// Log::info('支付成功'); // 不是已经支付状态则修改为已经支付状态 $res1 = DB::table('order') ->where('out_trade_no', $notify->out_trade_no) ->update(['pay_time' => time(),'order_status' => 2]);//已支付 } else { // 用户支付失败// Log::info('支付失败'); $res2 = DB::table('order') ->where('out_trade_no', $notify->out_trade_no) ->update(['order_status' => 1]);//待付款 } return true; // 返回处理完成 });// Log::info($response); return $response; }}

3、mobile.wxpay.payOrder文件--HTML5页面:

@extends('mobile.mobile')@section('title', '支付订单')@section('header')    
@endsection@section('main')
提示:请在24小时内完成在线支付,逾期将视为订单无效
  • 您的订单号:{
    {$order->order_sn}}
  • 应付金额:¥{
    {$order->order_amount}}
确认支付
@endsection@section('javaScript') @endsection

点击‘确认支付’,即调用微信jsapi发起支付。

4、微信支付回调网址路由设置:(注意不要把它放到任何验证类型的中间件里)

Route::any('wxpay/notify','mobile\WxPayController@notify');

支付结果通知回调,是支付完成后微信服务器通过post方式回调返回支付结果信息,所以回调接口地址一定是在公网直接可以访问的,Laravel 5 默认启用了 CSRF 中间件,因为微信的消息是 POST 过来,所以会触发 CSRF 检查导致无法正确响应消息,所以可以在CSRF验证中排除指定URL。可以通过在VerifyCsrfTokenapp/Http/Middleware/VerifyCsrfToken.php中间件中将要排除的请求URL添加到$except属性数组中,如下:

5、至此,基本done了,代码不够优雅或者有任何改进的地方,请指教。。

转载于:https://my.oschina.net/24kb/blog/1828353

你可能感兴趣的文章
Android ListView上下滑动弹性动画
查看>>
Android LruCache 二级缓存
查看>>
Java使用Redis
查看>>
【Cloud Foundry 应用开发大赛】“八卦街”后台管理系统
查看>>
ice版本resize 错误调试(Host key verification failed)
查看>>
http://fulinweiyang.iteye.com/
查看>>
php ssh2
查看>>
状态码
查看>>
Git合并多个 Commit
查看>>
结合Spring和Groovy解决脚本热加载
查看>>
【实战Java高并发程序设计 3】带有时间戳的对象引用:AtomicStampedReference
查看>>
SpringMVC内部跳转与重定向
查看>>
oracle 创建,删除存储过程,参数传递,创建,删除存储函数,存储过程和函数的查看,包,系统包...
查看>>
基础代码随笔
查看>>
如何实现SVN导出某段时间修改过的文件;自动将class文件部署到服务器中;重启服务器...
查看>>
PropertyUtils、BeanUtils的copyProperties()和set、get性能比较
查看>>
2014-11-10 关于C# 如何获取本地电脑的UTC时区
查看>>
Ceph的基本情况进行概要介绍
查看>>
MySQL数据库优化思路之配置文件优化
查看>>
分享纯 nginx 防御代码 nginx safe.conf
查看>>