zoukankan      html  css  js  c++  java
  • tp5微信支付2--实际开发与测试

    一、参数配置

     这里有两个配置

    1、微信授权的配置,要用到这几个参数

     2、是支付的设置

     二、微信授权

    1、原生微信接口获取授权

     public function oauth()
        {
                $code = input('code');
                $wx_config = $this->config;
                if(empty($code))
                {
    //获取code
    $r_url = urlencode('http://jskj.all2best.cn/index.php/api/weixinpay/oauth');//这里一定要用urlencode, $url1 = "https://open.weixin.qq.com/connect/oauth2/authorize?appid={$wx_config['app_id']}&redirect_uri={$r_url}&response_type=code&scope=snsapi_base&state=STATE#wechat_redirect"; header('location:' . $url1); exit(); }else {
    //获取用户信息
    $url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid={$wx_config['app_id']}&secret={$wx_config['secret']}&code={$code}&grant_type=authorization_code"; $result = curl_client($url); $result = json_decode($result, true); if (isset($result['errcode'])) { throw new Exception($result['errcode'] . $result['msg']); } // dump($result); Session::prefix('index_auth'); session('open_id',$result['openid']); } }

     2、使用 easywechat接口  获取授权

    class Wxtest extends Controller
    {
    
        //服务端验证
        public function wx_init()
        {
            try {
                $app = Factory::officialAccount($this->new_config);
                // $app->server->push(function ($message) {
                //     return "您好!欢迎使用 EasyWeChat!";
                // });
                $response = $app->server->serve();
                $response->send();
                exit;
            } catch (Exception $e) {
                echo $e->getMessage();
            }
        }
    
        //配置参数
        protected $new_config = [
            'debug'  => true,
            'app_id' => 'appid',
            'secret' => 'secret',
            'token'  => 'token',
            'aes_key' => 'aes_key',
            'response_type' => 'array',// 指定 API 调用返回结果的类型:array(default)/collection/object/raw/自定义类名
            'oauth' => [
                'scopes'   => ['snsapi_userinfo'],
                'callback' => '/index.php/api/wxtest/oauth',//授权回调页面
            ],
        ];
    
        //业务页面
        public function profile()
        {
            $app   = Factory::officialAccount($this->new_config);
            $oauth = $app->oauth;
            // 未登录
            if (empty(session('wx_user'))) {
    
                session('target_url','/index.php/api/wxtest/profile');
    
                //return $oauth->redirect();
                // 这里不一定是return,如果你的框架action不是返回内容的话你就得使用
                $oauth->redirect()->send();
            }
            // 已经登录过
            $user = session('wx_user');
            dump($user);
            //业务逻辑处理
        }
    
        //授权回调页
        public function oauth()
        {
            $app = Factory::officialAccount($this->new_config);
            $oauth = $app->oauth;
    
            // 获取 OAuth 授权结果用户信息
            $user = $oauth->user();
    
            session('wx_user',$user->toArray());
    
            $targetUrl = empty(session('target_url')) ? '/' : session('target_url');
            header('location:'. $targetUrl); // 跳转到 profile
            exit();
        }
    }

    scope的两种区别:

    snsapi_base:不弹出授权页面,直接跳转,只能获取用户openid

    snsapi_userinfo:弹出授权页面,可通过openid拿到昵称、性别、所在地。并且,即使在未关注的情况下,只要用户授权,也能获取其信息。

    redirect_uri:授权后重定向的回调链接地址,请使用urlencode对链接进行处理。(easywechat不用处理,直接填写url即可

    二、微信支付:用的是easywechat的统一下单接口

     public function wx_pay($bill_no, $amount)
        {
            //已登录
            Session::prefix('index_auth');
            $openid = session('open_id');//$user->getId();
            if(empty($openid))
            {
                $this->oauth();
            }$jssdk  = $this->payment->jssdk;
    //统一下单
    $result = $this->payment->order->unify([ 'body' => 'Kingjim', 'out_trade_no' => $bill_no, 'total_fee' => (int)bcmul($amount, 100), 'notify_url' => url('index.php/api/weixinpay/notify', '', '', true), // 支付结果通知网址,如果不设置则会使用配置里的默认地址 'trade_type' => 'JSAPI', // 请对应换成你的支付方式对应的值类型 'openid' => $openid ]); //预支付订单号prepayId, 生成支付 JS 配置 $prepayId = $result['prepay_id']; $jsApiParameters = $jssdk->bridgeConfig($prepayId); return $jsApiParameters; }

    三、支付回调方法

    /**
    * notify_url接收通知页面
    */
    public function notify()
    {
    try {
    $response = $this->payment->handlePaidNotify(function ($message, $fail) {
    $order = (new Order())->get_order($message['out_trade_no']);
    if (!$order || $order['pay_status'] == 2) { // 如果订单不存在 或者 订单已经支付过了
    return true; // 告诉微信,我已经处理完了,订单没找到,别再通知我了
    }
    if ($message['return_code'] === 'SUCCESS') { // return_code 表示通信状态
    if ($message['result_code'] === 'SUCCESS') {
    $order['pay_status'] = 2; // 更新支付状态
    (new Order())::update($order, ['bill_no' => $message['out_trade_no']]); // 保存订单
    //添加流水
    (new Flow())->add_ex($order['order_final_amount'],2,$message['out_trade_no']);
    // 用户支付失败
    } elseif ($message['result_code'] === 'FAIL') {
    return $fail('通信失败,请稍后再通知我');
    }
    } else {
    return $fail('通信失败,请稍后再通知我');
    }
    return true; // 返回处理完成
    });
    $response->send(); // return $response;
    } catch (Exception $e) {
    return tips($e->getMessage());
    }
    }

    四、前端代码

    function onBridgeReady(){
       WeixinJSBridge.invoke(
          'getBrandWCPayRequest', {
             "appId":"wx2421b1c4370ec43b",     //公众号名称,由商户传入     
             "timeStamp":"1395712654",         //时间戳,自1970年以来的秒数     
             "nonceStr":"e61463f8efa94090b1f366cccfbbb444", //随机串     
             "package":"prepay_id=u802345jgfjsdfgsdg888",     
             "signType":"MD5",         //微信签名方式:     
             "paySign":"70EA570631E4BB79628FBCA90534C63FF7FADD89" //微信签名 
          },
          function(res){
          if(res.err_msg == "get_brand_wcpay_request:ok" ){
          // 使用以上方式判断前端返回,微信团队郑重提示:
                //res.err_msg将在用户支付成功后返回ok,但并不保证它绝对可靠。
          } 
       }); 
    }

    //需要先判断是否是微信浏览器,并且微信内置包是否加载完成
    //有时会出现当触发事件的时候微信内置包还未加载完成,必须加上下面判断
    if (typeof WeixinJSBridge == "undefined"){
       if( document.addEventListener ){
           document.addEventListener('WeixinJSBridgeReady', onBridgeReady, false);
       }else if (document.attachEvent){
           document.attachEvent('WeixinJSBridgeReady', onBridgeReady); 
           document.attachEvent('onWeixinJSBridgeReady', onBridgeReady);
       }
    }else{
       onBridgeReady();
    }
  • 相关阅读:
    springJDBC01 利用springJDBC操作数据库
    Struts2框架05 result标签的类型、拦截器
    Struts2框架04 struts和spring整合
    JDBC03 利用JDBC实现事务提交与回滚【调用Connection中的方法实现事务管理】
    JDBC02 利用JDBC连接数据库【使用数据库连接池】
    JDBC01 利用JDBC连接数据库【不使用数据库连接池】
    ???Struts2框架03 session的使用、登录逻辑【session工作原理】
    Struts2框架02 消息传递
    Struts2框架01【如果使用struts框架】【利用struts框架写一个 hello world】
    格式化输出
  • 原文地址:https://www.cnblogs.com/ivy-zheng/p/12403738.html
Copyright © 2011-2022 走看看