详解用vue.js和laravel实现微信支付


Posted in Javascript onJune 23, 2017

注:此项是微信公众号开发,请在往下看之前,先实现网页微信授权登陆功能,具体参看我简书的另一篇文章:https://3water.com/article/117004.htm

1.打开app/config/wechat.php,配置微信支付参数:

/*
   * 微信支付
   */
   'payment' => [
     'merchant_id'    => env('WECHAT_PAYMENT_MERCHANT_ID', 'your-mch-id'),//商家号ID,请将其放在.env文件中
     'key'        => env('WECHAT_PAYMENT_KEY', 'key-for-signature'),//商家支付key,请将其放在.env文件中
     'cert_path'     => env('WECHAT_PAYMENT_CERT_PATH', storage_path('app/public/apiclient_cert.pem')), //微信支付证书apiclient_cert.pem的绝对路径,我放在storage/app/public/下
     'key_path'      => env('WECHAT_PAYMENT_KEY_PATH', storage_path('app/public/apiclient_key.pem')),   //微信支付证书apiclient_key.pem的绝对路径,我放在storage/app/public/下径
     // 'device_info'   => env('WECHAT_PAYMENT_DEVICE_INFO', ''),
     // 'sub_app_id'   => env('WECHAT_PAYMENT_SUB_APP_ID', ''),
     // 'sub_merchant_id' => env('WECHAT_PAYMENT_SUB_MERCHANT_ID', ''),
     // ...
   ],

以上参数,请依照自己的情况配置,请勿直接拷贝代码!

2.配置微信支付和回调路由

//以下路由我放在api.php路由里,如果你放在web.php路由,请自行调整!
Route::middleware('api')->post('wxpay','BillsController@wxpay');
Route::middleware('api')->post('wx_notify','BillsController@wxnotify');

3.在相应的控制器里创建wxpay的方法

/**
  * 这是我自己项目的内部代码示例,具体根据自己的业务逻辑调整,切不可直接拷贝!
  */
  public function wxpay(Request $request)
  {
    //本实例传递的参数为user_id 和 broadcast_id,具体
    if($request->has('user_id') && $request->has('broadcast_id')){
      $out_trade_no = md5(Carbon::now().str_random(8));
      $user_id = $request->get('user_id');
      $broadcast_id = $request->get('broadcast_id');
      $num = $request->get('num');
      $flag = $request->get('flag');

      $openid = $this->user->getOpenid($user_id);
      $broadcast = $this->broadcast->getById($broadcast_id);
      $speaker_id = $broadcast->speaker_id;
      $body = $broadcast->title;
      $detail = '';
      $paid_at = null;

      $status = 'pre_paid';
      $amount = ($broadcast->price)*$num;

      $attributes = [
        'trade_type'    => 'JSAPI', // JSAPI,NATIVE,APP...
        'body'       => $body, 
        'detail'      => $detail,
        'out_trade_no'   => $out_trade_no,
        'total_fee'    => $amount, // 单位:分
        'notify_url'    => $_ENV['APP_URL'].'/api/wx_notify', // 支付结果通知网址,如果不设置则会使用配置里的默认地址
        'openid'      => $openid, // trade_type=JSAPI,此参数必传,用户在商户appid下的唯一标识,
        // ...
      ];

      $order = new Order($attributes);
      $result = $this->wechat->payment->prepare($order);
      if ($result->return_code == 'SUCCESS' && $result->result_code == 'SUCCESS'){
        //创建预订单
        $param = [
          'out_trade_no'=>$out_trade_no,
          'user_id'=>$user_id,
          'broadcast_id'=>$broadcast_id,
          'speaker_id'=>$speaker_id,
          'body'=>$body,
          'detail'=>$detail,
          'paid_at'=>$paid_at,
          'amount'=>$amount,
          'flag'=>$flag,
          'status'=>$status,
          'num'=>$num
        ];
        $this->bill->store($param);
        //返回
        $prepayId = $result->prepay_id;
        $config = $this->wechat->payment->configForPayment($prepayId,false);

        return response()->json($config);
      }
    }

  }

4.在相应的控制器里添加回调wxnotify方法

/**
   * 这是我自己项目的内部代码示例,具体根据自己的业务逻辑调整,切不可直接拷贝!
   */
  public function wxnotify()
  {
    $response = $this->wechat->payment->handleNotify(function($notify, $successful){
      $order = $this->bill->getBillByOrderno($notify->out_trade_no);//查询订单($notify->out_trade_no);
      if (!$order) { // 如果订单不存在
        return 'Order not exist.'; // 告诉微信,我已经处理完了,订单没找到,别再通知我了
      }
      // 如果订单存在
      // 检查订单是否已经更新过支付状态
      if ($order->paid_at) { // 假设订单字段“支付时间”不为空代表已经支付
        return true; // 已经支付成功了就不再更新了
      }
      // 用户是否支付成功
      if ($successful) {
        // 不是已经支付状态则修改为已经支付状态
        $order->paid_at = Carbon::now(); // 更新支付时间为当前时间
        $order->status = 'paid';
      } else { // 用户支付失败
        $order->status = 'paid_fail';
      }
      $order->save(); // 保存订单
      return true; // 返回处理完成
    });
    return $response; 
  }

5.vue.js中methods的方法代码参考

wechatpay(){
    var param = {
     'user_id':this.getStorage(),
     'broadcast_id':this.id,
     'num':1,
     'flag':'buy',
    }
    this.$http.post(this.GLOBAL.apiUrl+'/wxpay',param).then((response) => {
     WeixinJSBridge.invoke(
      'getBrandWCPayRequest', response.data,
      function(res){
       if(res.err_msg == "get_brand_wcpay_request:ok" ) {
        # 回调成功后跳转
        # router.push({name: 'Room',params:{id:this.id}});
       }
      }
     );
    })
   },

6.微信公众平台配置

1) 在“公众账号设置”—“JS接口安全域名”设置中填写前端域名

2) 在“微信支付”—“开发配置”页面中,公众账号支付下填写“支付授权目录”,注意的是,此授权url为前端支付按钮所在页面的url

7.接下来你就可以测试了

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
JavaScript实现16进制颜色值转RGB的方法
Feb 09 Javascript
浅析Node.js 中 Stream API 的使用
Oct 23 Javascript
JS工作中的小贴士之”闭包“与事件委托的”阻止冒泡“
Jun 16 Javascript
理解JavaScript原型链
Oct 25 Javascript
JS简单获取当前日期和农历日期的方法
Apr 17 Javascript
详解Vue 动态添加模板的几种方法
Apr 25 Javascript
利用Angular.js编写公共提示模块的方法教程
May 28 Javascript
基于JavaScript实现百度搜索框效果
Jun 28 Javascript
使用webpack3.0配置webpack-dev-server教程
May 29 Javascript
js使用swiper实现层叠轮播效果实例代码
Dec 12 Javascript
vue之debounce属性被移除及处理详解
Nov 13 Javascript
JS 5种遍历对象的方式
Jun 16 Javascript
详解用vue.js和laravel实现微信授权登陆
Jun 23 #Javascript
妙用Angularjs实现表格按指定列排序
Jun 23 #Javascript
VUE中v-model和v-for指令详解
Jun 23 #Javascript
JavaScript正则表达式简单实用实例
Jun 23 #Javascript
js中的事件委托或是事件代理使用详解
Jun 23 #Javascript
JS判断非空至少输入两个字符的简单实现方法
Jun 23 #Javascript
详解Vue.js之视图和数据的双向绑定(v-model)
Jun 23 #Javascript
You might like
笑谈配置,使用Smarty技术
2007/01/04 PHP
100多行PHP代码实现socks5代理服务器[2]
2016/05/05 PHP
php each 返回数组中当前的键值对并将数组指针向前移动一步实例
2016/11/22 PHP
php连接微软MSSQL(sql server)完全攻略
2016/11/27 PHP
PHP回调函数与匿名函数实例详解
2017/08/16 PHP
详解如何实现Laravel的服务容器的方法示例
2019/04/15 PHP
跨浏览器的设置innerHTML方法
2006/09/18 Javascript
Wordpress ThickBox 点击图片显示下一张图的修改方法
2010/12/11 Javascript
用jquery实现自定义风格的滑动条实现代码
2011/04/26 Javascript
javascript创建createXmlHttpRequest对象示例代码
2014/02/10 Javascript
jQuery表格排序组件-tablesorter使用示例
2014/05/26 Javascript
兼容IE、firefox以及chrome的js获取时间(getFullYear)
2014/07/04 Javascript
nodejs实现的一个简单聊天室功能分享
2014/12/06 NodeJs
jQuery将所有被选中的checkbox某个属性值连接成字符串的方法
2015/01/24 Javascript
JavaScript中全选、全不选、反选、无刷新删除、批量删除、即点即改入库(在yii框架中操作)的代码分享
2016/11/01 Javascript
Javascript 对cookie操作详解及实例
2016/12/29 Javascript
vue.js中v-on:textInput无法执行事件问题的解决过程
2017/07/12 Javascript
AngularJs每天学习之总体介绍
2017/08/07 Javascript
通过nodejs 服务器读取HTML文件渲染到页面的方法
2018/05/17 NodeJs
vue中v-for通过动态绑定class实现触发效果
2018/12/06 Javascript
Jquery实现无缝向上循环滚动列表的特效
2019/02/13 jQuery
[00:36]我的中国心——Serenity vs Fnatic
2018/08/21 DOTA
Python的Bottle框架的一些使用技巧介绍
2015/04/08 Python
Python+django实现简单的文件上传
2016/08/17 Python
python 同时读取多个文件的例子
2019/07/16 Python
Django ORM多对多查询方法(自定义第三张表&ManyToManyField)
2019/08/09 Python
Python函数的迭代器与生成器的示例代码
2020/06/18 Python
CSS3 @keyframes简单动画实现
2018/02/24 HTML / CSS
推荐10个HTML5响应式框架
2016/02/25 HTML / CSS
微信端html5页面调用分享接口示例
2018/03/14 HTML / CSS
美国在线家居装饰店:Belle&June
2018/10/24 全球购物
伯克斯奥特莱斯:Burkes Outlet
2019/03/30 全球购物
运动会稿件100字
2014/09/24 职场文书
典型事迹材料范文
2014/12/29 职场文书
音乐教师个人工作总结
2015/02/06 职场文书
运动员加油词
2015/07/18 职场文书