Jelajahi Sumber

充值与回调重写

lizhen_gitee 9 bulan lalu
induk
melakukan
7542b7c433
3 mengubah file dengan 358 tambahan dan 220 penghapusan
  1. 261 0
      application/api/controller/Notify.php
  2. 96 220
      application/api/controller/Pay.php
  3. 1 0
      application/config.php

+ 261 - 0
application/api/controller/Notify.php

@@ -0,0 +1,261 @@
+<?php
+namespace app\api\controller;
+
+use app\common\controller\Api;
+use think\Db;
+use addons\epay\library\Service;
+/**
+ * 订单支付回调
+ */
+class Notify extends Api
+{
+    protected $noNeedLogin = ['*'];
+    protected $noNeedRight = ['*'];
+
+    //充值金币 异步回调对外方法
+    public function gold_notify_base(){
+
+        //验签
+        $paytype = input('paytype','wechat');
+        $notify_file = $this->notify_log_start($paytype);
+        $pay = Service::checkNotify($paytype);
+        if (!$pay) {
+            echo '签名错误';
+            exit;
+        }
+
+        //验证,拿订单号等信息
+        $data = $pay->verify();
+        $out_trade_no = $data['out_trade_no'];
+        //订单查询
+        $info = Db::name('pay_order')->where('out_trade_no',$out_trade_no)->find();
+
+        if(empty($info)){
+            echo $pay->success();
+            exit;
+        }
+
+        if($info['order_status'] != 0)
+        {
+            echo $pay->success();
+            exit;
+        }
+        //你可以在此编写订单逻辑
+//        $rs = $this->gold_notify_do($out_trade_no);
+        $args = json_decode($info['args'], true);
+        $rechargeM = new \app\common\model\Recharge();
+        $rs = $rechargeM->goldpaysucc($out_trade_no, $args,1);
+
+
+        if($rs === false){
+            //不论结果都应返回success
+            echo $pay->success();
+            exit;
+        }else{
+            //不论结果都应返回success
+            echo $pay->success();
+            exit;
+        }
+
+        //默认
+        echo $pay->success();
+        exit;
+    }
+
+    //充值金币 逻辑
+    private function gold_notify_do($out_trade_no){
+
+        Db::startTrans();
+        $orderInfo = Db::name('pay_order')->where(['out_trade_no' => $out_trade_no])->lock(true)->find();
+        if (empty($orderInfo)) {
+            Db::rollback();
+            return false;
+        }
+
+        if($orderInfo['order_status'] != 0){
+            Db::rollback();
+            return false;
+        }
+
+        //逻辑开始
+        $args = json_decode($orderInfo['args'],true);
+        $result = model('Wallet')->lockChangeAccountRemain($orderInfo['user_id'],'gold',$args['gold'],10, '金币充值','pay_order',$orderInfo['id']);
+        if($result['status']===false)
+        {
+            Db::rollback();
+            return false;
+        }
+        //逻辑结束
+
+        //状态
+        $ros = Db::name('pay_order')->where(['out_trade_no' => $out_trade_no])->update(['order_status'=>1,'notifytime'=>time()]);
+        if($ros === false) {
+            Db::rollback();
+            return false;
+        }
+
+        //默认提交
+        Db::commit();
+        return true;
+    }
+
+
+    //充值VIP 异步回调对外方法
+    public function vip_notify_base(){
+
+        //验签
+        $paytype = input('paytype','wechat');
+        $notify_file = $this->notify_log_start($paytype);
+        $pay = Service::checkNotify($paytype);
+        if (!$pay) {
+            echo '签名错误';
+            exit;
+        }
+
+        //验证,拿订单号等信息
+        $data = $pay->verify();
+        $out_trade_no = $data['out_trade_no'];
+        //订单查询
+        $info = Db::name('pay_order')->where('out_trade_no',$out_trade_no)->find();
+
+        if(empty($info)){
+            echo $pay->success();
+            exit;
+        }
+
+        if($info['order_status'] != 0)
+        {
+            echo $pay->success();
+            exit;
+        }
+        //你可以在此编写订单逻辑
+//        $rs = $this->vip_notify_do($out_trade_no);
+        $args = json_decode($info['args'], true);
+        $rechargeM = new \app\common\model\Recharge();
+        $rs = $rechargeM->vippaysucc($out_trade_no, $args);
+
+        if($rs === false){
+            //不论结果都应返回success
+            echo $pay->success();
+            exit;
+        }else{
+            //不论结果都应返回success
+            echo $pay->success();
+            exit;
+        }
+
+        //默认
+        echo $pay->success();
+        exit;
+    }
+
+    //充值金币 逻辑
+    private function vip_notify_do($out_trade_no){
+
+        Db::startTrans();
+        $orderInfo = Db::name('pay_order')->where(['out_trade_no' => $out_trade_no])->lock(true)->find();
+        if (empty($orderInfo)) {
+            Db::rollback();
+            return false;
+        }
+
+        if($orderInfo['order_status'] != 0){
+            Db::rollback();
+            return false;
+        }
+
+        //逻辑开始
+        //先充值
+        $args = json_decode($orderInfo['args'],true);
+        $user_info = Db::name('user_wallet')->where('user_id',$orderInfo['user_id'])->lock(true)->find();
+        if($user_info['vip_endtime'] < time()){
+            //过期了
+            $vip_endtime = time() + (intval($args['days']) * 86400);
+            $vip_type = 1;
+        }else{
+            //追加vip
+            $vip_endtime = $user_info['vip_endtime'] + (intval($args['days']) * 86400);
+            $vip_type = 2;
+        }
+        $update_data = [
+            'vip_endtime'=>$vip_endtime,
+        ];
+        $result = Db::name('user_wallet')->where('user_id',$orderInfo['user_id'])->update($update_data);
+
+        //记录日志
+        $log_data = [
+            'user_id' => $orderInfo['user_id'],
+            'before'  => $user_info['vip_endtime'],
+            'change_value'  => intval($args['days']) * 86400,
+            'remain'  => $vip_endtime,
+            'remark'  => '安卓购买vip',
+            'createtime'  => time(),
+            'vip_type'  => $vip_type,
+        ];
+        Db::name('user_vip_log')->insertGetId($log_data);
+
+        if($result === false)
+        {
+            Db::rollback();
+            return false;
+        }
+
+
+        //逻辑结束
+
+        //状态
+        $ros = Db::name('pay_order')->where(['out_trade_no' => $out_trade_no])->update(['order_status'=>1,'notifytime'=>time()]);
+        if($ros === false) {
+            Db::rollback();
+            return false;
+        }
+
+        //默认提交
+        Db::commit();
+        return true;
+    }
+
+
+    //异步日志
+    private function notify_log_start($paytype = 'wechat'){
+        //记录支付回调数据
+        ignore_user_abort(); // run script in background
+        set_time_limit(30);
+        // 日志文件 start
+        $log_base_dir = '../paylog/'.$paytype.'/';
+        if (!is_dir($log_base_dir))
+        {
+            mkdir($log_base_dir, 0770, true);
+            @chmod($log_base_dir, 0770);
+        }
+        $notify_file = $log_base_dir.'notify.txt';
+        if(!file_exists($notify_file)) {
+            @touch($notify_file);
+            @chmod($notify_file, 0770);
+        }
+        if(filesize($notify_file)>5242880)//大于5M自动切换
+        {
+            rename($notify_file, $log_base_dir.'notify_'.date('Y_m_d_H_i_s').'.txt');
+        }
+        if(!file_exists($notify_file)) {
+            @touch($notify_file);
+            @chmod($notify_file, 0770);
+        }
+        // 日志文件 end
+        //开始写入
+        $_REQUEST = isset($_REQUEST) ? $_REQUEST : array();
+        if($_REQUEST && $paytype == 'alipay') {
+            file_put_contents($notify_file, "\r\n\r\n".date('Y-m-d H:i:s')." [notify][入口接收request]".json_encode($_REQUEST), FILE_APPEND);
+        } else {
+            $xml = file_get_contents("php://input");
+            file_put_contents($notify_file, "\r\n\r\n".date('Y-m-d H:i:s')." [notify][入口接收php://input流原始数据] \n".$xml, FILE_APPEND);
+            $xmlObj = simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA);
+            file_put_contents($notify_file, "\r\n\r\n".date('Y-m-d H:i:s')." [notify][入口接收php://input流] ".json_encode($xmlObj), FILE_APPEND);
+        }
+
+        ini_set('display_errors','On');
+
+        return $notify_file;
+
+    }
+}

+ 96 - 220
application/api/controller/Pay.php

@@ -5,16 +5,13 @@ namespace app\api\controller;
 use app\common\controller\Api;
 use think\Db;
 use addons\epay\library\Service;
-use app\common\model\Wallet;
-use think\Exception;
-use app\utils\CurlUtil;
 
 /**
  * 充值配置与充值订单
  */
 class Pay extends Api
 {
-    protected $noNeedLogin = ['testpay'];
+    protected $noNeedLogin = [];
     protected $noNeedRight = ['*'];
 
     //vip用的
@@ -34,30 +31,31 @@ class Pay extends Api
     }
 
     //vip用的,创建订单
-    /*public function vip_recharge(){
-
+    public function vip_recharge()
+    {
         $rc_id = input('rc_id',0);
         $pay_type = input('pay_type','wechat');
         $uid = $this->auth->id;
 
+        if (!in_array($pay_type, ['wechat', 'alipay'])) {
+            $this->error('错误的支付类型');
+        }
+
         if(!$rc_id){
             $this->error('请选择会员套餐');
         }
 
-
         //赋值money
         $recharge_config = Db::name('payvip_config')->where('id',$rc_id)->find();
         $money = $recharge_config['money'];
 
-        if($money<=0)
-        {
+        if($money <= 0) {
             $this->error('支付金额必须大于0');
         }
         if($money > 10000){
             $this->error('支付金额太大');
         }
 
-
         //会员等级冲突
         //当前是会员,但是却要向下级续费,直接提示报错
         //修改等级,向上立刻改,向下不允许
@@ -76,19 +74,16 @@ class Pay extends Api
         $data['user_id'] = $uid;
         $data['ext_info'] =  json_encode(['subject'=>'充值vip支付']);
         $data['memo'] =  '充值会员支付';
+        $data['args'] = json_encode(['user_id'=>$uid,'days'=>$recharge_config['days'],'vip_level'=>$recharge_config['vip_level'],'gold_num'=>$recharge_config['gold_num'],'money'=>$money]);
+
         $data['createtime'] = time();
         //$data['payment'] = 'miniapp';
         $data['payment'] = 'app';
-        $orderid = Db::name('pay_order')->insertGetId($data);
+        $pay_order = Db::name('pay_order')->insertGetId($data);
 
-        //创建回调
-        $even_data = [];
-        $even_data['event'] = 'success';
-        $even_data['class'] = 'app\common\model\Recharge';
-        $even_data['method'] = 'vippaysucc';
-        $even_data['args'] = json_encode(['user_id'=>$uid,'days'=>$recharge_config['days'],'vip_level'=>$recharge_config['vip_level'],'gold_num'=>$recharge_config['gold_num'],'money'=>$money]);
-        $even_data['pay_no'] = $pay_no;
-        Db::name('pay_event')->insertGetId($even_data);
+        if (!$pay_order) {
+            $this->error('下单失败');
+        }
 
         //下单
         $params = [
@@ -97,110 +92,13 @@ class Pay extends Api
             'title'        => $data['memo'],
             'amount'       => $data['money'],
             //'amount'       => 0.01,
-            //'method'       => 'miniapp',
             'method'       => 'app',
-            //'openid'       => $openid,
-            'notifyurl' => $this->request->root(true) . '/notify.php/paytype/'.$pay_type,
+            'notifyurl' => config('pay_notify_url').'/api/notify/vip_notify_base/paytype/'.$pay_type,
             'returnurl' => '',
         ];
         $res = Service::submitOrder($params);
 
-        if($pay_type == 'wechat'){
-            $this->success('success',json_decode($res,true));
-        }else{
-            $this->success('success',$res);
-        }
-    }*/
-    public function vip_recharge()
-    {
-        exit;//功能重复,采用精秀,屏蔽
-        Db::startTrans();
-        try {
-            $rc_id = input('rc_id',0);
-            $pay_type = input('pay_type','wechat');
-            $uid = $this->auth->id;
-
-            if(!$rc_id){
-                throw new Exception('请选择会员套餐');
-            }
-
-            //赋值money
-            $recharge_config = Db::name('payvip_config')->where('id',$rc_id)->find();
-            $money = $recharge_config['money'];
-
-            if($money <= 0) {
-                throw new Exception('支付金额必须大于0');
-            }
-            if($money > 10000){
-                throw new Exception('支付金额太大');
-            }
-
-            //会员等级冲突
-            //当前是会员,但是却要向下级续费,直接提示报错
-            //修改等级,向上立刻改,向下不允许
-            $wallet_info = model('wallet')->getWallet($this->auth->id);
-            if($wallet_info['vip_endtime'] > time() && $recharge_config['vip_level'] < $wallet_info['vip_level']){
-                throw new Exception('当前会员没有过期,不能续费');
-            }
-
-            //创建订单
-            $data = [];
-            $data['status'] = 0;
-            $pay_no = createUniqueNo('V',$uid);
-            $data['pay_no'] = $pay_no;
-            $data['money'] = $money;
-            $data['payment_class'] = $pay_type;
-            $data['user_id'] = $uid;
-            $data['ext_info'] =  json_encode(['subject'=>'充值vip支付']);
-            $data['memo'] =  '充值会员支付';
-            $data['createtime'] = time();
-            //$data['payment'] = 'miniapp';
-            $data['payment'] = 'app';
-            $orderid = Db::name('pay_order')->insertGetId($data);
-
-            //创建回调
-            $even_data = [];
-            $even_data['event'] = 'success';
-            $even_data['class'] = 'app\common\model\Recharge';
-            $even_data['method'] = 'vippaysucc';
-            $even_data['args'] = json_encode(['user_id'=>$uid,'days'=>$recharge_config['days'],'vip_level'=>$recharge_config['vip_level'],'gold_num'=>$recharge_config['gold_num'],'money'=>$money]);
-            $even_data['pay_no'] = $pay_no;
-            Db::name('pay_event')->insertGetId($even_data);
-
-            if ($pay_type == 'wechat') {
-                //$money = 0.01;
-                $sandpay = new \app\common\library\Sandpay();
-                $sandpayParams = [
-                    'order_no' => $pay_no,
-                    'goods_name' => '充值vip支付',
-                    'money' => $money,
-                    'type' => 'vip',
-                ];
-                $sandRes = $sandpay->wechath5($sandpayParams);
-                if ($sandRes['status'] != 1) {
-                    throw new Exception('失败');
-                }
-                $res = $sandRes['data'];
-            } else {
-                //下单
-                $params = [
-                    'type'         => $pay_type,
-                    'orderid'      => $pay_no,
-                    'title'        => $data['memo'],
-                    'amount'       => $data['money'],
-                    //'amount'       => 0.01,
-                    'method'       => 'app',
-                    'notifyurl' => CurlUtil::getHttp('/notify.php/paytype/'.$pay_type),
-                    'returnurl' => '',
-                ];
-                $res = Service::submitOrder($params);
-            }
-            Db::commit();
-            $this->success('success',$res);
-        } catch (Exception $e) {
-            Db::rollback();
-            $this->error($e->getMessage());
-        }
+        $this->success('success',$res);
     }
 
 
@@ -209,7 +107,7 @@ class Pay extends Api
         $list = Db::name('paygold_config')->where('is_show',1)->order('weight asc,id asc')->select();
         $data['goldconfig'] = $list;
         $data['gold'] = model('wallet')->getWallet($this->auth->id,'gold');
-        $data['money_to_gold'] = config('site.money_to_gold');
+        $data['money_to_gold'] = config('site.rmb_to_gold');
         $data['is_first'] = Db::name('user_paygold_log')->where(['uid' => $this->auth->id])->count('id');
 
         if ($list) {
@@ -221,7 +119,10 @@ class Pay extends Api
 				'is_show' => 1,
 				'weight' => 1,
 				'first_gold' => 0,
-				'first_vipdays' => 0
+				'first_vipdays' => 0,
+				'vip_gold' => 0,
+				'is_default' => 0,
+				'jewel' => 0
             ];
 
             array_push($data['goldconfig'], $arr);
@@ -237,110 +138,85 @@ class Pay extends Api
     //充值金币 创建订单
     public function gold_recharge()
     {
-        exit;//功能重复,采用精秀,屏蔽
-        Db::startTrans();
-        try {
-            $rc_id     = input_post('rc_id',0);
-            $pay_type  = input_post('pay_type','wechat');
-            $freemoney = input_post('freemoney', 0, 'intval');
-            $uid = $this->auth->id;
-
-            if(!$rc_id && !$freemoney){
-                throw new Exception('请选择或填写充值金额');
-            }
-            if (!in_array($pay_type,['wechat','alipay'])) {
-                throw new Exception('错误的支付类型');
-            }
-            //赋值money
-            if($rc_id){
-                $recharge_config = Db::name('paygold_config')->where('id',$rc_id)->find();
-                $money = $recharge_config ? $recharge_config['money']: 0;
-                $gold  = $recharge_config ? $recharge_config['gold'] : 0;
-                $first_gold     = $recharge_config ? $recharge_config['first_gold'] : 0;
-                $first_vipdays  = $recharge_config ? $recharge_config['first_vipdays'] : 0;
-                $vip_gold  = $recharge_config ? $recharge_config['vip_gold'] : 0;
-            }
+        $rc_id     = input_post('rc_id',0);
+        $pay_type  = input_post('pay_type','wechat');
+        $freemoney = input_post('freemoney', 0, 'intval');
+        $uid = $this->auth->id;
 
-            //自由输入覆盖
-            if(!empty($freemoney)){
-                $rc_id = 0;
-                $money = floatval($freemoney);
-                $bili = config('site.rmb_to_gold') ?: 10;
-                $gold  = bcmul($money,$bili,0);
-                $first_gold = 0;
-                $first_vipdays = 0;
-                $vip_gold  = 0;
-            }
-            if($money <= 0) {
-                throw new Exception('支付金额必须大于0');
-            }
-            if($money > 10000){
-                throw new Exception('支付金额太大');
-            }
-            //查询是不是会员,若不是则不赠送金币
-            $vip_endtime = Db::name('user_wallet')->where('user_id',$this->auth->id)->value('vip_endtime');
-            if ($vip_endtime < time()) {
-                $vip_gold = 0;
-            }
+        if(!$rc_id && !$freemoney){
+            $this->error('请选择或填写充值金额');
+        }
+        if (!in_array($pay_type,['wechat','alipay'])) {
+            $this->error('错误的支付类型');
+        }
+        //赋值money
+        if($rc_id){
+            $recharge_config = Db::name('paygold_config')->where('id',$rc_id)->find();
+            $money = $recharge_config ? $recharge_config['money']: 0;
+            $gold  = $recharge_config ? $recharge_config['gold'] : 0;
+            $first_gold     = $recharge_config ? $recharge_config['first_gold'] : 0;
+            $first_vipdays  = $recharge_config ? $recharge_config['first_vipdays'] : 0;
+            $vip_gold  = $recharge_config ? $recharge_config['vip_gold'] : 0;
+        }
+
+        //自由输入覆盖
+        if(!empty($freemoney)){
+            $rc_id = 0;
+            $money = floatval($freemoney);
+            $bili = config('site.rmb_to_gold') ?: 10;
+            $gold  = bcmul($money,$bili,0);
+            $first_gold = 0;
+            $first_vipdays = 0;
+            $vip_gold  = 0;
+        }
+        if($money <= 0) {
+            $this->error('支付金额必须大于0');
+        }
+        if($money > 10000){
+            $this->error('支付金额太大');
+        }
+        //查询是不是会员,若不是则不赠送金币
+        $vip_endtime = Db::name('user_wallet')->where('user_id',$this->auth->id)->value('vip_endtime');
+        if ($vip_endtime < time()) {
+            $vip_gold = 0;
+        }
+
+        //创建订单
+        $data = [];
+        $data['status'] = 0;
+        $pay_no = createUniqueNo('P',$uid);
+        $data['pay_no'] = $pay_no;
+        $data['money'] = $money;
+        $data['payment_class'] = $pay_type;
+        $data['user_id'] = $uid;
+        $data['ext_info'] =  json_encode(['subject'=>'充值金币支付']);
+        $data['memo'] =  '充值金币支付';
+        $data['args'] = json_encode(['user_id'=>$uid,'gold'=>$gold,'money'=>$money,'pg_id'=>$rc_id,'first_gold'=>$first_gold,'first_vipdays'=>$first_vipdays, 'intro_uid' => $this->auth->intro_uid, 'vip_gold' => $vip_gold]);
 
-            //创建订单
-            $data = [];
-            $data['status'] = 0;
-            $pay_no = createUniqueNo('P',$uid);
-            $data['pay_no'] = $pay_no;
-            $data['money'] = $money;
-            $data['payment_class'] = $pay_type;
-            $data['user_id'] = $uid;
-            $data['ext_info'] =  json_encode(['subject'=>'充值金币支付']);
-            $data['memo'] =  '充值金币支付';
-            $data['createtime'] = time();
-            $data['payment'] = 'app';
-            $orderid = Db::name('pay_order')->insertGetId($data);
-
-            //创建回调
-            $even_data = [];
-            $even_data['event'] = 'success';
-            $even_data['class'] = 'app\common\model\Recharge';
-            $even_data['method'] = 'goldpaysucc';
-            $even_data['args'] = json_encode(['user_id'=>$uid,'gold'=>$gold,'money'=>$money,'pg_id'=>$rc_id,'first_gold'=>$first_gold,'first_vipdays'=>$first_vipdays, 'intro_uid' => $this->auth->intro_uid, 'vip_gold' => $vip_gold]);
-            $even_data['pay_no'] = $pay_no;
-            Db::name('pay_event')->insertGetId($even_data);
-
-            if ($pay_type == 'wechat') {
-                //$money = 0.01;
-                $sandpay = new \app\common\library\Sandpay();
-                $sandpayParams = [
-                    'order_no' => $pay_no,
-                    'goods_name' => '充值金币支付',
-                    'money' => $money,
-                    'type' => 'gold',
-                ];
-                $sandRes = $sandpay->wechath5($sandpayParams);
-                if ($sandRes['status'] != 1) {
-                    throw new Exception('失败');
-                }
-                $res = $sandRes['data'];
-            } else {
-                //下单
-                $params = [
-                    'type'         => $pay_type,
-                    'orderid'      => $pay_no,
-                    'title'        => $data['memo'],
-                    'amount'       => $data['money'],
-                    //'amount'       => 0.01,
-                    'method'       => 'app',
-                    'notifyurl' => CurlUtil::getHttp('/notify.php/paytype/'.$pay_type),
-                    'returnurl' => '',
-                ];
-                $res = Service::submitOrder($params);
-            }
 
-            Db::commit();
-            $this->success('成功', $res);
-        } catch (Exception $e) {
-            Db::rollback();
-            $this->error($e->getMessage());
+        $data['createtime'] = time();
+        $data['payment'] = 'app';
+        $pay_order = Db::name('pay_order')->insertGetId($data);
+
+        if (!$pay_order) {
+            $this->error('下单失败');
         }
+
+        //下单
+        $params = [
+            'type'         => $pay_type,
+            'orderid'      => $pay_no,
+            'title'        => $data['memo'],
+            'amount'       => $data['money'],
+            //'amount'       => 0.01,
+            'method'       => 'app',
+            'notifyurl' => config('pay_notify_url').'/api/notify/gold_notify_base/paytype/'.$pay_type,
+            'returnurl' => '',
+        ];
+        $res = Service::submitOrder($params);
+
+        $this->success('成功', $res);
+
     }
 
 

+ 1 - 0
application/config.php

@@ -378,6 +378,7 @@ return [
     ],
     //图片路径
     'img_url'                   => 'http://lejian.huxiukeji.cn',
+    'pay_notify_url'                   => 'http://lejian.huxiukeji.cn',
     //支付宝 rsa公钥 私钥  支付宝公钥
     'ali_app_id' => '', //appid
     'ali_sign_type' => 'RSA2', //签名