Ajax.php 16.4 KB
<?php

namespace app\index\controller;

use addons\litestore\model\Litestoreorder;
use addons\third\model\Third;
use addons\wechat\library\Config as ConfigService;
use app\api\model\StoreInform;
use app\common\controller\Frontend;
use EasyWeChat\Foundation\Application as WXPAY_APP;
use EasyWeChat\Foundation\Application;
use think\Db;
use think\Lang;
use think\Log;

/**
 * Ajax异步请求接口
 * @internal
 */
class Ajax extends Frontend
{

    protected $noNeedLogin = ['lang','store_inform_over','callback_for_wxgzh','store_notify','store_order_notify','notify','refund_notify'];
    protected $noNeedRight = ['*'];
    protected $layout = '';
    public function _initialize()
    {
        parent::_initialize();
        $this->user_id = $this->auth->id;
        $this->model = new Litestoreorder;

    }

    /**
     * 加载语言包
     */
    public function lang()
    {
        header('Content-Type: application/javascript');
        header("Cache-Control: public");
        header("Pragma: cache");

        $offset = 30 * 60 * 60 * 24; // 缓存一个月
        header("Expires: " . gmdate("D, d M Y H:i:s", time() + $offset) . " GMT");

        $controllername = input("controllername");
        $this->loadlang($controllername);
        //强制输出JSON Object
        $result = jsonp(Lang::get(), 200, [], ['json_encode_param' => JSON_FORCE_OBJECT | JSON_UNESCAPED_UNICODE]);
        return $result;
    }

    /**
     * 商圈信息红包过期
     */
    public function store_inform_over()
    {
        $inform_model = new StoreInform();
        $time = strtotime(date('Y-m-d',time())) - 14 * 86400;
        $end_time = $time + 86400 - 14 * 86400;
        $where = [
            'type' => 1,
            'status' => 2,
            'surplus' => ['gt',0],
            'updatetime' => ['between',[$time,$end_time]]
        ];
        $inform = $inform_model->where($where)->select();
        foreach ($inform as &$v) {
            Db::startTrans();
            $res = $inform_model->update(['id'=>$v['id'],'status'=>5]);
            $user_model = new \app\admin\model\User();
            $user = $user_model->where('id', $v['user_id'])->find();
            // 积分变动记录
            $log = [
                'user_id' => $v['user_id'],
                'score' => $v['score'],
                'before' => $user['score'],
                'after' => $user['score'] + $v['score'],
                'createtime' => time(),
                'status' => 3,
                'memo' => '商圈信息过期'
            ];
            $result_log = Db::name('user_score_log')->insertGetId($log);
            // 返还用户余额
            $result_user = $user_model->where('id', $user['id'])->setInc('score', $v['score']);
            if(!$res || !$result_log || !$result_user) {
                Db::rollback();
            }
            Db::commit();
        }
        echo 'success';
    }

    /**
     * 店铺申请回调
     */
    public function store_notify()
    {
        $app = new Application(ConfigService::load());
        $response = $app->payment->handleNotify(function($notify, $successful){
            /*这里是支付回调逻辑处理,一下是DEMO*/
            // 使用通知里的 "微信支付订单号" 或者 "商户订单号" 去自己的数据库找到订单
            $out_trade_no=$notify->out_trade_no;
            $info = Db::name('store')->where(['order_sn'=>$out_trade_no])->find();
            if (!$info) { // 如果订单不存在
                return 'Order not exist.'; // 告诉微信,我已经处理完了,订单没找到,别再通知我了
            }

            // 检查订单是否已经更新过支付状态
            if  ($info['transaction_id']) { // 假设订单字段“支付时间”不为空代表已经支付
                return true; // 已经支付成功了就不再更新了
            }

            // 用户是否支付成功
            if ($successful) {
                Db::startTrans();
                // 回填微信的订单号
                $update['transaction_id'] = $notify->transaction_id;
                $update['status'] = 2; //付款成功
                $update['pay_time'] = time();
                //更新状态: 已购买
                $res_order = Db::name('store')->where(['id' => $info['id']])->update($update);
                if(!$res_order) {
                    Db::rollback();
                    return false; // 返回处理完成
                }
                Db::commit();
            } else {
                // 用户支付失败
                $update['transaction_id'] = $notify->transaction_id;
                $update['status'] = 6; //异常-支付失败
                Db::name('deposit_order')->where(['id' => $info['id']])->update($update);
                return false; // 返回处理完成
            }

            return true; // 返回处理完成
        });

        $response->send();
    }

    /**
     * 店铺申请回调
     */
    public function store_order_notify()
    {
        $app = new Application(ConfigService::load());
        $response = $app->payment->handleNotify(function($notify, $successful){
            /*这里是支付回调逻辑处理,一下是DEMO*/
            // 使用通知里的 "微信支付订单号" 或者 "商户订单号" 去自己的数据库找到订单
            $out_trade_no=$notify->out_trade_no;
            $info = Db::name('store_order')->where(['order_sn'=>$out_trade_no])->find();
            if (!$info) { // 如果订单不存在
                return 'Order not exist.'; // 告诉微信,我已经处理完了,订单没找到,别再通知我了
            }

            // 检查订单是否已经更新过支付状态
            if  ($info['transaction_id']) { // 假设订单字段“支付时间”不为空代表已经支付
                return true; // 已经支付成功了就不再更新了
            }
            $store = Db::name('store')->where('id',$info['store_id'])->find();

            // 用户是否支付成功
            if ($successful) {
                Db::startTrans();
                // 回填微信的订单号
                $update['transaction_id'] = $notify->transaction_id;
                $update['status'] = 2; //付款成功
                $update['pay_time'] = time();
                //更新状态: 已购买
                $res_order = Db::name('store_order')->where(['id' => $info['id']])->update($update);
                // 新增关联社区
                $update = [
                    'house_ids' => $store['house_ids'].','.$info['house_ids'].','
                ];
                $res_store = Db::name('store')->where('id',$info['store_id'])->update($update);
                if(!$res_order || !$res_store) {
                    Db::rollback();
                    return false; // 返回处理完成
                }
                Db::commit();
            } else {
                // 用户支付失败
                $update['transaction_id'] = $notify->transaction_id;
                $update['status'] = 6; //异常-支付失败
                Db::name('deposit_order')->where(['id' => $info['id']])->update($update);
                return false; // 返回处理完成
            }

            return true; // 返回处理完成
        });

        $response->send();
    }

    /**
     * 支付回调
     */
    public function notify(){
        $app = new Application(ConfigService::load());
        $response = $app->payment->handleNotify(function($notify, $successful){
            /*这里是支付回调逻辑处理,一下是DEMO*/
            // 使用通知里的 "微信支付订单号" 或者 "商户订单号" 去自己的数据库找到订单
            $out_trade_no=$notify->out_trade_no;
            $info = Db::name('deposit_order')->where(['order_sn'=>$out_trade_no])->find();
            if (!$info) { // 如果订单不存在
                return 'Order not exist.'; // 告诉微信,我已经处理完了,订单没找到,别再通知我了
            }

            // 检查订单是否已经更新过支付状态
            if  ($info['transaction_id']) { // 假设订单字段“支付时间”不为空代表已经支付
                return true; // 已经支付成功了就不再更新了
            }

            // 用户是否支付成功
            if ($successful) {
                Db::startTrans();
                // 回填微信的订单号
                $update['transaction_id'] = $notify->transaction_id;
                $update['status'] = 0; //付款成功,接单中
                $update['pay_time'] = time();
                //更新状态: 已购买
                $res_order = Db::name('deposit_order')->where(['id' => $info['id']])->update($update);
                $user = Db::name('user')->where('id',$info['user_id'])->find();

                //记录钱包log
                $insert_data = array(
                    'user_id' => $info['user_id'],
                    'score' => $info['score'],
                    'before'   => $user['score'],
                    'after'   => $user['score'] + $info['score'],
                    'createtime' => time(),
                    'memo' => '充值',
                );
                $res_log = Db::name('user_score_log')->insert($insert_data);
                // 增加用户板币余额
                $res_user = Db::name('user')->where('id',$info['user_id'])->setInc('score',$info['score']);
                if(!$res_order || !$res_log || !$res_user) {
                    Db::rollback();
                    return false; // 返回处理完成
                }
                Db::commit();
            } else {
                // 用户支付失败
                $update['transaction_id'] = $notify->transaction_id;
                $update['status'] = 6; //异常-支付失败
                Db::name('deposit_order')->where(['id' => $info['id']])->update($update);
                return false; // 返回处理完成
            }

            return true; // 返回处理完成
        });

        $response->send();
    }

    /**
     * 商家入驻支付结果回调
     */
    public function callback_for_wxgzh(){
        $this->init_wx_pay_for_gzh(false);
        $response = $this->wxapp->payment->handleNotify(function($notify, $successful){
            $order = $this->model->payDetail($notify->out_trade_no);

            if (empty($order)) { // 如果订单不存在
                return true;
                //return 'Order not exist.'; // 告诉微信,我已经处理完了,订单没找到,别再通知我了
            }
            if ($successful) {
                $order->updatePayStatus($notify->transaction_id);
            }

            return true; // 返回处理完成
        });

        $response->send();
    }

    private function init_wx_pay_for_gzh($Ischeck=false){
        //这里首先判断 此用户是否绑定了微信公众号
        if($Ischeck){
            $third = Third::where(['user_id' => $this->user_id, 'platform' => 'wechat'])->find();
            if(!$third){
                //从这里自动绑定微信公众号的账户
                $this->error('您未绑定微信号',null,1008);
            }
        }

        $config = get_addon_config('litestore');

        $third_config = get_addon_config('third');
        $third_options = array_intersect_key($third_config, array_flip(['wechat']));
        $third_options = $third_options['wechat'];

        $options = [
            'debug'  => true,
            'log' => [
                'level' => 'debug',
                'file'  => '/tmp/easywechat.log',
            ],
            'app_id'   => $third_options['app_id'],
            'secret'   => $third_options['app_secret'],
            'payment' => [
                'merchant_id'        =>  $config['MCHIDGZH'],
                'key'                =>  $config['APIKEYGZH'],
                'notify_url'         =>  \think\Request::instance()->domain().addon_url('litestore/api.order/callback_for_wxgzh'),
            ],

        ];
        $this->wxapp = new WXPAY_APP($options);
    }

    /**
     * 退款结果回调
     */
    public function refund_notify() {
        $app = new Application(ConfigService::load());
        $response = $app->payment->handleRefundNotify(function ($message, $reqInfo) {
//            Log::write(date('Y-m-d H:i') . '订单退款操作,返回数据:' . json_encode($message, JSON_UNESCAPED_UNICODE), 'notice');
            // 其中 $message['req_info'] 获取到的是加密解密信息
            // $reqInfo 成功时为1
            // 你的业务逻辑...
            if($reqInfo) {
                $refund_where = [
                    'order_sn'          => $message['req_info']['out_trade_no'],
                    'transaction_id'    => $message['req_info']['transaction_id'],
                    'out_refund_no'     => $message['req_info']['out_refund_no']
                ];
                $refund = Db::name('Refund')->where($refund_where)->find();
//                Log::write(date('Y-m-d H:i') . '订单退款操作1,返回数据:' . json_encode($refund, JSON_UNESCAPED_UNICODE), 'notice');
                if($refund['status'] == 1) {
                    return true;
                } else {
                    Db::startTrans();
                    $update = [
                        'out_refund_no'             => $message['req_info']['out_refund_no'],
                        'refund_id'                 => $message['req_info']['refund_id'],
                        'refund_account'            => $message['req_info']['refund_account'],
                        'refund_request_source'     => $message['req_info']['refund_request_source'],
                        'updatetime'                => time(),
                        'more'                      => json_encode($message)
                    ];
                    $ask_order_result = true;
                    // 处理退款状态
                    if($message['req_info']['refund_status'] == 'SUCCESS') {
                        $update['status'] = 1;
                        $update['success_time'] = strtotime($message['req_info']['success_time']);
                        Log::write(date('Y-m-d H:i') . '订单退款操作2,返回数据:' . json_encode($update, JSON_UNESCAPED_UNICODE), 'notice');
//                        if($refund['type'] == 1) {
//                            // 修改订单状态为已退款
//                            $ask_order_update = [
//                                'id' => $refund['ask_order_id'],
//                                'status' => 4
//                            ];
//                            $ask_order_result = Db::name('ask_order')->update($ask_order_update);
//                        }
//                        if($refund['type'] == 2) {
//                            // 修改订单状态为已退款
//                            $ask_order_update = [
//                                'id' => $refund['ask_order_id'],
//                                'status' => 2
//                            ];
//                            $ask_order_result = Db::name('ask_orderson')->update($ask_order_update);
//                        }
                    } elseif($message['req_info']['refund_status'] == 'CHANGE') {
                        $update['status'] = 2;
                    } elseif($message['req_info']['refund_status'] == 'REFUNDCLOSE') {
                        $update['status'] = 3;
                    }
//                    Log::write(date('Y-m-d H:i') . '订单退款操作3,返回数据:' . json_encode($refund_where, JSON_UNESCAPED_UNICODE), 'notice');
                    $result = Db::name('Refund')->where($refund_where)->update($update);
                    if(!$result || !$ask_order_result) {
                        Log::write(date('Y-m-d H:i') . '订单退款操作5,返回数据:' . json_encode([$result,$ask_order_result], JSON_UNESCAPED_UNICODE), 'notice');
                        Db::rollback();
                        return false;
                    }
                    Log::write(date('Y-m-d H:i') . '订单退款操作4,返回数据:' . json_encode([$result], JSON_UNESCAPED_UNICODE), 'notice');
                    Db::commit();
                }
            }
            return true; // 返回 true 告诉微信“我已处理完成”
            // 或返回错误原因 $fail('参数格式校验错误');
        });

        $response->send();
    }

    /**
     * 上传文件
     */
    public function upload()
    {
        return action('api/common/upload');
    }

}