Ajax.php 14.8 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\common\controller\Frontend;
use EasyWeChat\Foundation\Application as WXPAY_APP;
use EasyWeChat\Foundation\Application;
use think\Db;
use think\Lang;

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

    protected $noNeedLogin = ['lang','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_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), 'order_refund');
            // 其中 $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), 'order_refund');
                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), 'order_refund');
                        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), 'order_refund');
                    $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), 'order_refund');
                        Db::rollback();
                        return false;
                    }
//                    Log::write(date('Y-m-d H:i') . '订单退款操作4,返回数据:' . json_encode([$result], JSON_UNESCAPED_UNICODE), 'order_refund');
                    Db::commit();
                }
            }
            return true; // 返回 true 告诉微信“我已处理完成”
            // 或返回错误原因 $fail('参数格式校验错误');
        });

        $response->send();
    }

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

}