美文网首页
2021-02-24 laravel + EasyWechat

2021-02-24 laravel + EasyWechat

作者: 浩克啊12138 | 来源:发表于2021-02-24 13:40 被阅读0次

    1.安装必要的第三方包

    $ composer require overtrue/wechat:~5.0 -vvv
    
    1. 在控制器中添加微信支付调用方法
        public function payOrder(Request $request)
        {
            $memberId = $request->attributes->get('memberId');
            $orderSn = $request->get('orderSn');
            $order = Orders::where('order_sn', $orderSn)->where('status', 0)->get()->toArray();
            if (empty($order)) {
                return ['code' => 404, 'massage' => '找不到订单!'];
            }
    
            try {
                $config = Pay::payByWeChat(reset($order)['id'], $memberId);
                return ['code' => 200, 'data' => $config];
            } catch (\Exception $e) {
                return ['code' => 404, 'massage' => $e->getMessage()];
            }
        }
    

    3.在模型中创建支付方法

        public static function getConfig()
        {
            $config = Configs::first()->toArray();
    
            return [
                // 必要配置
                'app_id' => $config['app_id'] ?? env('WECHAT_APP_ID'),
                'mch_id' => $config['mch_id'] ?? env('WECHAT_MCH_ID'),
                'key' => $config['key'] ?? env('WECHAT_KEY'),   // API 密钥
    
                // 如需使用敏感接口(如退款、发送红包等)需要配置 API 证书路径(登录商户平台下载 API 证书)
    //            'cert_path' => 'path/to/your/cert.pem', // 绝对路径!!!!
    //            'key_path' => 'path/to/your/key',      // 绝对路径!!!!
    
                'notify_url' => route('order.notify'),     // 你也可以在下单时单独设置来想覆盖它
    //            'sandbox' => true, // 设置为 false 或注释则关闭沙箱模式
            ];
        }
    
        public static function payByWeChat($orderId, $memberId)
        {
            $goodsIds = OrderItems::where('orders_id', 11)->select('goods_id')->get()->toArray();
            $goodsIds = array_column($goodsIds, 'goods_id');
            $lastOrder = Orders::join('orders_items', 'orders_items.orders_id', '=', 'orders.id')
                ->where('orders.member_id', $memberId)
                ->where('orders.type', 0)
                ->whereIn('orders_items.goods_id', $goodsIds)
                ->where('orders.pay_time', '>=', date('Y-m-d'))
                ->orderBy('orders.pay_time', 'desc')
                ->get()
                ->toArray();
    
            if (!empty($lastOrder)) {
                throw new \Exception('今日该商品已达到购买上限, 支付失败!');
            }
    
            $order = Orders::find($orderId)->toArray();
            $member = Members::find($memberId)->toArray();
    
            $payment = Factory::payment(self::getConfig());
            $jssdk = $payment->jssdk;
    
            $result = $payment->order->unify([
                'body' => env('APP_NAME'),         // 订单说明
                'out_trade_no' => $order['order_sn'],   // 平台内部订单号
                'total_fee' => $order['price'] * 100,   // 价格, 单位为分
    //            'spbill_create_ip' => '123.12.12.123', // 可选,如不传该参数,SDK 将会自动获取相应 IP 地址
    //            'notify_url' => 'https://pay.weixin.qq.com/wxpay/pay.action', // 支付结果通知网址,如果不设置则会使用配置里的默认地址
                'trade_type' => 'JSAPI', // 请对应换成你的支付方式对应的值类型 小程序为JSAPI
                'openid' => $member['openid'],
            ]);
    
            if ($result['return_code'] == 'SUCCESS' && $result['result_code'] == 'SUCCESS') {
                $prepayId = $result['prepay_id'];
    
                $config = $jssdk->sdkConfig($prepayId);
    //            $config['orderSn'] = $order['order_sn'];
    //            $config['orderId'] = $order['id'];
                return $config;
    //            return response($config);
            }
    
            if ($result['return_code'] == 'FAIL' && array_key_exists('return_msg', $result)) {
                throw new \Exception($result['return_msg']);
            }
    
            throw new \Exception($result['err_code_des']);
        }
    
    1. 在控制器中添加微信回调方法
        public function notify(Request $request)
        {
            $fields = $request->query->all();
    
            return Pay::notifyByWeChat($fields);
        }
    

    5.在模型中创建微信回调处理方法

        public static function notifyByWeChat($fields, $notify)
        {
            $config = self::getConfig();
            $payment = Factory::payment($config);
    
            $response = $payment->handlePaidNotify(function ($message, $fail) use ($fields) {
                // 根据返回的订单号查询订单数据
                $order = Orders::where('order_sn', $message['out_trade_no'])->get()->toArray();
                if (!$order) {
                    $fail('订单不存在!');
                }
                $order = reset($order);
    
                if ($order['status'] == '1') {
                    return true;
                }
    
                // 支付成功后的业务逻辑
                if ($message['result_code'] === 'SUCCESS') {
                    $order['order_sn'] = $message['out_trade_no']; // 回调订单号
                    $order['pay_order_sn'] = $message['transaction_id']; // 回调流水号
                    $order['verification_code'] = Pay::generateVerificationCode();
                    $order['pay_time'] = date('Y-m-d H:i:s');
                    $order['status'] = 1;
                    $order = Orders::timestamps($order);
    
                    Orders::where('order_sn', $order['order_sn'])->update($order);
                    if ($order['type']) {
                        $card = OrderItems::where('order_id', $order['id']);
                        $timeLimit = reset($card)['time_limit'];
                        $member = Members::find($order['member_id'])->toArray();
                        $expireTime = strtotime($member['expire_time']);
                        if (empty($member['expire_time']) || $expireTime < time()) {
                            $time = date('Y-m-d', time() + $timeLimit * 86400);
                        } else {
                            $time = date('Y-m-d', $expireTime + $timeLimit * 86400);
                        }
    
                        $data = ['expire_time' => $time];
                        $data['status'] = 1;
                        $data['updated_at'] = date('Y-m-d H:i:s');
                        Members::where('id', $order['member_id'])->update($data);
                    }
                }
    
                return true;
            });
    
            return $response;
        }
    

    6.设置路由

    Route::group([
        'middleware' => 'jwt.user',
        'prefix' => 'orders',
    ], function (Router $router) {
        // 订单支付
        $router->post('pay', 'OrderController@payOrder');
        // 微信支付回调
        $router->any('notify', 'OrderController@notify')->name('order.notify');
    });
    

    7.小程序端测试代码
    wxml文件

    <!--index.wxml-->
    <view class="container">
      <view class="userinfo">
        <button wx:if="{{!hasUserInfo && canIUse}}" open-type="getUserInfo" bindgetuserinfo="getUserInfo"> 获取头像昵称 </button>
        <block wx:else>
          <image bindtap="bindViewTap" class="userinfo-avatar" src="{{userInfo.avatarUrl}}" mode="cover"></image>
          <text class="userinfo-nickname">{{userInfo.nickName}}</text>
        </block>
      </view>
      <view class="usermotto">
        <text class="user-motto">{{motto}}</text>
      </view>
    </view>
    
    // index.js
    // 获取应用实例
    const app = getApp()
    
    Page({
      data: {
        motto: 'Hello World',
        userInfo: {},
        hasUserInfo: false,
        canIUse: wx.canIUse('button.open-type.getUserInfo')
      },
      // 事件处理函数
      bindViewTap() {
        wx.navigateTo({
          url: '../logs/logs'
        })
      },
      onLoad() {
        console.log(app.globalData)
        if (app.globalData.userInfo) {
          this.setData({
            userInfo: app.globalData.userInfo,
            hasUserInfo: true
          })
        } else if (this.data.canIUse) {
          // 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回
          // 所以此处加入 callback 以防止这种情况
          app.userInfoReadyCallback = res => {
            this.setData({
              userInfo: res.userInfo,
              hasUserInfo: true
            })
          }
        } else {
          // 在没有 open-type=getUserInfo 版本的兼容处理
          wx.getUserInfo({
            success: res => {
              app.globalData.userInfo = res.userInfo
              this.setData({
                userInfo: res.userInfo,
                hasUserInfo: true
              })
            }
          })
        }
      },
      getUserInfo(e) {
        console.log(e)
        var rawData = e.detail.rawData 
        app.globalData.userInfo = e.detail.userInfo
        this.setData({
          userInfo: e.detail.userInfo,
          hasUserInfo: true
        })
    
        console.log(rawData)
        wx.login({
          success:function (res){
            var code = res.code;  
            var token = null;
            wx.request({
              url: 'http://fiveyears.cc/wechat/auth', 
              header: {
                'content-type': 'application/json'
              },
              data: {
                code: code,
                rawData: rawData
              },
              success(res) {
                console.log(res)
                token = res.data.token
    
                console.log(token)
    
                wx.request({
                  url: 'http://fiveyears.cc/orders/pay', 
                  header: {
                    'content-type': 'application/json'
                  },
                  data: {
                    token: token,
                    orderSn: 'VIP2021021908181676096'
                  },
                  method: 'post',
                  success(res) {
                    console.log(res)
                    console.log(res.data)
                    console.log(res.data.data.timestamp)
      
                    wx.requestPayment({
                      'timeStamp':res.data.data.timestamp,//
                      'nonceStr': res.data.data.nonceStr,
                      'package': res.data.data.package,
                      'signType': 'MD5',
                      'paySign': res.data.data.paySign,
                      'success':function(res){
                          console.log(res);
                      },
                      'fail':function(res){
                          console.log('fail:'+JSON.stringify(res));
                      }
                    })
                  }
                })
              }
            })
    
          }
        })
    
      }
    })
    

    相关文章

      网友评论

          本文标题:2021-02-24 laravel + EasyWechat

          本文链接:https://www.haomeiwen.com/subject/ehhsfltx.html