<?php
namespace app\common\controller;
use think\facade\View;
use think\facade\Session;
use think\facade\Cache;
use think\facade\Db;
use think\helper\Str;
use wxpay\WxPayApi;
use helper\URL;
use helper\BaiduPay;
use Alipay\EasySDK\Kernel\Factory;
use Alipay\EasySDK\Kernel\Util\ResponseChecker;
use Alipay\EasySDK\Kernel\Config as AliConfig;
use app\common\variable\MsgCode;
use app\common\model\Orders as OrdersModel;
use app\common\model\UserVip as UserVipModel;
use app\common\model\UserInfo as UserInfoModel;
use app\common\model\UserScore as UserScoreModel;
use app\common\model\Vip as VipModel;
use app\common\model\VipRule as VipRuleModel;
use app\common\model\VipRuleValue as VipRuleValueModel;
use app\common\model\VipValueAdded as VipValueAddedModel;
use app\common\model\VipValueAddedDiscount as VipValueAddedDiscountModel;
use app\common\model\UserVipRule as UserVipRuleModel;
use app\common\model\ResumeDownloaded as ResumeDownloadedModel;
use app\common\model\UserVipRuleLog as UserVipRuleLogModel;
use app\common\model\Company as CompanyModel;
use app\common\model\Jobs as JobsModel;
use app\common\model\JobsRefreshAuto as JobsRefreshAutoModel;
use app\common\model\PushTask as PushTaskModel;
use app\common\model\UserAli as UserAliModel;
use app\common\model\UserWx as UserWxModel;
use app\common\controller\JobFair as JobFairController;
use app\common\model\JobFair as JobFairModel;
use app\common\model\JobFairBooth as JobFairBoothModel;
use app\common\model\Coupon as CouponModel;
use app\common\model\CouponList as CouponListModel;
class Pay extends Base
{
    const IS_TEST=false;
    public static function generateOrderInfo($D)
    {
        if (empty($D['alias_id']))
            return parent::ajaxReturn('请先选择套餐',MsgCode::$error);
        if (empty($D['pay_type']))
            return parent::ajaxReturn('请选择支付方式',MsgCode::$error);
        if (!$D['uid'])
            return parent::ajaxReturn('请先登录',MsgCode::$error);
        switch ($D['type']) {
            // 开通会员
        	case 1:
        		$orderInfo=self::getVipOrderInfo($D);
        		break;
            //下载简历服务
        	case 2:
        		$orderInfo=self::getVipValueAddedOrderInfo($D);
        		break;
            //短信增值
            case 3:
                $orderInfo=self::getVipValueAddedOrderInfo($D);
                break;
            //职位置顶
            case 4:
                if (!$D['value'])
                    return parent::ajaxReturn('请选择职位',MsgCode::$error);
                $orderInfo=self::getVipValueAddedOrderInfo($D);
                break;
            //职位紧急
            case 5:
                if (!$D['value'])
                    return parent::ajaxReturn('请选择职位',MsgCode::$error);
                $orderInfo=self::getVipValueAddedOrderInfo($D);
                break;
            //企业模板
            case 6:
                $orderInfo=self::getVipValueAddedOrderInfo($D);
                break;
            //职位智能刷新
            case 7:
                if (!$D['value'])
                    return parent::ajaxReturn('请选择职位',MsgCode::$error);
                if (JobsRefreshAutoModel::where(['jobs_id'=>$D['value'],'status'=>1])->count())
                    return parent::ajaxReturn('当前职位已存在智能刷新任务',MsgCode::$error);
                $orderInfo=self::getVipValueAddedOrderInfo($D);
                break;
            // 积分充值
            case 10:
                $orderInfo=self::getScoreOrderInfo($D);
                break;
            // 下载简历
            case 11:
                $orderInfo=self::getDownloadResumeOrderInfo($D);
                break;
            // 招聘会
            case 12:
                $orderInfo=self::getJobFairOrderInfo($D);
                break;
        	default:
	            return parent::ajaxReturn('订单类型不正确',MsgCode::$error);
        }
        if (empty($orderInfo) || is_string($orderInfo)) {
            return parent::ajaxReturn($orderInfo,MsgCode::$error);
        }else{
            if (!empty($orderInfo['is_pay']) && $orderInfo['is_pay'])
                return parent::ajaxReturn('success',MsgCode::$pay_success,['otrade'=>$orderInfo['otrade']]);
            switch ($D['app']) {
                case 'pc':
                    return self::WebPlaceAnOrder($orderInfo,$D['pay_type']);
                    break;
                case 'app':
                    return self::AppPlaceAnOrder($orderInfo,$D['pay_type']);
                    break;
                case 'h5':
                    return self::H5PlaceAnOrder($orderInfo,$D['pay_type']);
                    break;
                case 'toutiao':
                    return self::ToutiaoPlaceAnOrder($orderInfo,$D['pay_type']);
                    break;
                case 'baidu':
                    return self::BaiduPlaceAnOrder($orderInfo,$D['pay_type']);
                    break;
                case 'alipay':
                    return self::AliMpPayPlaceAnOrder($orderInfo,$D['pay_type']);
                    break;
                case 'wechatminiprogram':
                    return self::WechatminiprogramPlaceAnOrder($orderInfo,$D['pay_type']);
                    break;
            }
        }
    }
    public static function getOrderInfoByOtrade($D)
    {
        $where=[];
        $where[]=['uid','=',$D['uid']];
        $where[]=['otrade','=',$D['otrade']];
        $OrdersModel=OrdersModel::where($where)->field('otrade,oprice,otitle,expire_time')->find();
        if ($OrdersModel) {
            $OrdersModel->time=$OrdersModel->expire_time-time();
            switch ($D['app']) {
                case 'pc':
                    return self::WebPlaceAnOrder($OrdersModel->toArray(),$D['pay_type']);
                    break;
                case 'app':
                    return self::AppPlaceAnOrder($OrdersModel->toArray(),$D['pay_type']);
                    break;
                case 'h5':
                    return self::H5PlaceAnOrder($OrdersModel->toArray(),$D['pay_type']);
                    break;
                case 'toutiao':
                    return self::ToutiaoPlaceAnOrder($OrdersModel->toArray(),$D['pay_type']);
                    break;
                case 'baidu':
                    return self::BaiduPlaceAnOrder($OrdersModel->toArray(),$D['pay_type']);
                    break;
                case 'alipay':
                    return self::AliMpPayPlaceAnOrder($OrdersModel->toArray(),$D['pay_type']);
                    break;
                case 'wechatminiprogram':
                    return self::WechatminiprogramPlaceAnOrder($OrdersModel->toArray(),$D['pay_type']);
                    break;
            }
        }else return parent::ajaxReturn('订单不存在',MsgCode::$error);
    }
    public static function getVipValueAddedOrderInfo($D)
    {
        if (!$D['company_id'])
            return '请先完善企业资料';
        $VipLevel=UserVipModel::getCompanyVipLevel($D['uid']);
        $VipModel=VipModel::where(['level'=>$VipLevel])->field('id')->find();
        if (!$VipModel)
            return 'VIP等级不正确，请联系管理员';
        $va=VipValueAddedModel::alias('va')->where(['va.id'=>$D['alias_id'],'va.status'=>1])
            ->join('vip_value_added_discount discount','discount.vid='.$VipModel->id.' AND discount.type=va.type','LEFT')
            ->field('va.id,va.type,va.title,va.value,va.price,va.stock,va.surplus_stock,discount.discount')->find();
        if ($va) {
            $StockModel=null;
            $score=0;
            if ($va->stock){
                if (!$va->surplus_stock)
                    return '当前服务已售罄';
                $va->surplus_stock      = Db::raw('surplus_stock-1');
                $StockModel=$va;
            }
            $where=[
                'alias_id'  =>  $va->id,
                'uid'       =>  $D['uid'],
                'type'      =>  $D['type'],
                'status'    =>  0,
            ];
            $content=[
                'company_id'    =>  $D['company_id'],
            ];
            if ($D['value'])
                $content['jobs_id'] =  $D['value'];
            $price=0;
            switch ($D['pay_type']) {
                case 'top_jobs':
                    $top_day=UserVipRuleModel::alias('rule')
                    ->where(['rule.uid'=>$D['uid'],'rule.status'=>1])
                    ->join(config('databse.prefix').'vip vip','vip.id=rule.vid')
                    ->join('vip_rule_value value','value.id=rule.rid')
                    ->whereTime('rule.expiry_time','>',time())->order('rule.level desc')->where(['vip.is_company'=>1,'value.alias'=>'top-day'])->sum('rule.surplus_value');
                    if($top_day<$va->value)
                        return '当前置顶天数不足';
                    break;
                case 'urgent_jobs':
                    $urgent_day=UserVipRuleModel::alias('rule')
                    ->where(['rule.uid'=>$D['uid'],'rule.status'=>1])
                    ->join(config('databse.prefix').'vip vip','vip.id=rule.vid')
                    ->join('vip_rule_value value','value.id=rule.rid')
                    ->whereTime('rule.expiry_time','>',time())->order('rule.level desc')->where(['vip.is_company'=>1,'value.alias'=>'urgent-day'])->sum('rule.surplus_value');
                    if($urgent_day<$va->value)
                        return '当前紧急置顶天数不足';
                    break;
                
                default:
                    $price=$va->price;
                    if ($va->discount>0)
                        $price=round($va->price*($va->discount/100),2);
                    $UserInfo=UserInfoModel::where(['uid'=>$D['uid']])->find();
                    $scoreConfig=config('xy_score');
                    if ($D['score']) {
                        $scorePrice=$UserInfo->score/$scoreConfig['recharge_rate'];
                        $price1= floor($price);
                        if ($scoreConfig['is_integer']) {
                            //可以低多少钱
                            $proportion_price=intval($price1*($scoreConfig['proportion']/100));
                            if ($scorePrice>=$proportion_price) {
                                $score=$scoreConfig['recharge_rate']*$proportion_price;
                                $price=round($price-$proportion_price,2);
                            }else{
                                $proportion_price=intval($scorePrice);
                                $score=$proportion_price*$scoreConfig['recharge_rate'];
                                $price=round($price-$proportion_price,2);
                            }
                        }else{
                            //可以低多少钱
                            $proportion_price=$price1*($scoreConfig['proportion']/100);
                            if ($scorePrice>=$proportion_price) {
                                $score=$proportion_price*$scoreConfig['recharge_rate'];
                                $price=round($price-$proportion_price,2);
                            }else{
                                $proportion_price=$scorePrice;
                                $score=$scorePrice*$scoreConfig['recharge_rate'];
                                $price=round($price-$scorePrice,2);
                            }

                        }
                    }
                    break;
            }
            $where['score']        =   $score;
            $where['channel_type']  =   $D['channel_type'];
            $Data=$where;
            $Data['content']       =   json_encode($content,JSON_UNESCAPED_UNICODE);
            $Data['channel_type']  =   $D['channel_type'];
            $Data['role_type']     =   $D['role_type'];
            $Data['right_exchange']=   $D['pay_type'];
            if(!empty($D['selected_coupon']))
            $Data['coupon']        =   $D['selected_coupon'];
            $Data['va_value']      =   $va->value;
           	$Data['score']         =   $score;
            $Data['price']         =   static::IS_TEST?0.01:$price;
            $Data['original_price']=   $va->price;
            $Data['title']         =   '订购'.$va->title.'服务';
            return self::createOrderInfo($where,$Data,$StockModel);
        }else{
            return '该服务已下架或不存在';
        }
    }
    public static function getVipOrderInfo($D)
    {
        if (!$D['company_id'])
            return '请先完善企业资料';
        $VipModel=VipModel::where(['id'=>$D['alias_id'],'status'=>1])->find();
        $StockModel=null;
        if ($VipModel->stock){
            if (!$VipModel->surplus_stock)
                return '当前套餐已售罄';
            $VipModel->surplus_stock      = Db::raw('surplus_stock-1');
            $StockModel=$VipModel;
        }
        if ($VipModel) {
            $where=[
                'alias_id'  =>  $VipModel->id,
                'uid'       =>  $D['uid'],
                'type'      =>  $D['type'],
                'status'    =>  0,
            ];
            $content=[
                'company_id'    =>  $D['company_id'],
            ];
            $price=$VipModel->price;
            if ($VipModel->discount>0)
                $price=round($VipModel->price*($VipModel->discount/100),2);
            $where['channel_type']  =   $D['channel_type'];
            $Data=$where;
            $Data['content']       =   json_encode($content,JSON_UNESCAPED_UNICODE);
            $Data['score']         =   0;
            $Data['channel_type']  =   $D['channel_type'];
            $Data['role_type']     =   $D['role_type'];
            if(!empty($D['selected_coupon']))
            $Data['coupon']        =   $D['selected_coupon'];
            $Data['price']         =   static::IS_TEST?0.01:$price;
            $Data['original_price']=   $VipModel->price;
            $Data['title']         =   '开通'.$VipModel->title.'套餐';
            return self::createOrderInfo($where,$Data,$StockModel);
        }else{
            return '该套餐已下架或不存在';
        }
    }
    public static function getScoreOrderInfo($D)
    {
        $scoreConfig=config('xy_score');
        if (empty($scoreConfig) || !$scoreConfig['recharge_status'])
            return '积分充值未开放';
        if ($D['value']<$scoreConfig['min_score'])
            return '最低充值：'.$scoreConfig['min_score'].'积分';

        $price=round($D['value']/$scoreConfig['recharge_rate'],2);
        $where=[
            'alias_id'  =>  $D['uid'],
            'uid'       =>  $D['uid'],
            'type'      =>  $D['type'],
            'oprice'    =>  $price,
            'status'    =>  0,
        ];
        $content=[
            'value'    =>  $D['value'],
        ];
        $where['channel_type']  =   $D['channel_type'];
        $Data=$where;
        $Data['content']       =   json_encode($content,JSON_UNESCAPED_UNICODE);
        $Data['score']         =   0;
        $Data['channel_type']  =   $D['channel_type'];
        $Data['role_type']     =   $D['role_type'];
            if(!empty($D['selected_coupon']))
        $Data['coupon']        =   $D['selected_coupon'];
        $Data['price']         =   static::IS_TEST?0.01:$price;
        $Data['original_price']=   $price;
        $Data['title']         =   '充值：'.$D['value'].'积分';
        return self::createOrderInfo($where,$Data);
    }
    public static function getDownloadResumeOrderInfo($D)
    {
        if (!$D['company_id'])
            return '请先完善企业信息';
        $CompanyModel=CompanyModel::where(['id'=>$D['company_id']])->field('id,attestation')->find();
        if (!$CompanyModel) {
            return '请先完善企业信息';
        }else{
            switch (config('xy_resume.company_download_resume')) {
                case 1:
                    if ($CompanyModel->attestation!=3)
                        return '请先完成企业认证';
                    break;
                case 2:
                    if (JobsModel::where(['company_id'=>$CompanyModel->id])->count()<=0)
                        return '请先发布职位后在下载';
                    break;
            }
        }
        if ($D['pay_type']==='resume') {
            $download_value=UserVipRuleModel::alias('rule')
            ->where(['rule.uid'=>$D['uid'],'rule.status'=>1])
            ->join(config('databse.prefix').'vip vip','vip.id=rule.vid')
            ->join('vip_rule_value value','value.id=rule.rid')
            ->whereTime('rule.expiry_time','>',time())->order('rule.level desc')->where(['vip.is_company'=>1,'value.alias'=>'download-resume'])->sum('rule.surplus_value');
            if ($download_value<config('xy_resume.download_resume_rule_value')) 
                return '当前简历点不足';
        }
        $ResumeDownloadedModel=ResumeDownloadedModel::where(['id'=>$D['alias_id'],'status'=>0])->find();
        if (OrdersModel::where(['type'=>11,'alias_id'=>$D['alias_id']])->where('status','in',[1,2])->count())
            return '下载简历记录已经支付,请勿重复支付';

        $score=0;
        if ($ResumeDownloadedModel) {
            $where=[
                'alias_id'  =>  $ResumeDownloadedModel->id,
                'uid'       =>  $D['uid'],
                'type'      =>  $D['type'],
                'status'    =>  0,
                'score'     =>  0,
            ];
            $content=[
                'company_id'    =>  $ResumeDownloadedModel->company_id,
                'resume_id'     =>  $ResumeDownloadedModel->resume_id,
            ];
            $one_resume_download_price=config('xy_resume.one_resume_download_price');
            $price=$one_resume_download_price;
            if ($D['pay_type']==='resume') {
                $content['download_value']=config('xy_resume.download_resume_rule_value');
            }else{
                $UserInfo=UserInfoModel::where(['uid'=>$D['uid']])->find();
                $scoreConfig=config('xy_score');
                if ($D['score']) {
                    $scorePrice=$UserInfo->score/$scoreConfig['recharge_rate'];
                    $price1= floor($price);
                    if ($scoreConfig['is_integer']) {
                        //可以低多少钱
                        $proportion_price=intval($price1*($scoreConfig['proportion']/100));
                        if ($scorePrice>=$proportion_price) {
                            $score=$scoreConfig['recharge_rate']*$proportion_price;
                            $price=round($price-$proportion_price,2);
                        }else{
                            $proportion_price=intval($scorePrice);
                            $score=$proportion_price*$scoreConfig['recharge_rate'];
                            $price=round($price-$proportion_price,2);
                        }
                    }else{
                        //可以低多少钱
                        $proportion_price=$price1*($scoreConfig['proportion']/100);
                        if ($scorePrice>=$proportion_price) {
                            $score=$proportion_price*$scoreConfig['recharge_rate'];
                            $price=round($price-$proportion_price,2);
                        }else{
                            $proportion_price=$scorePrice;
                            $score=$scorePrice*$scoreConfig['recharge_rate'];
                            $price=round($price-$scorePrice,2);
                        }

                    }
                }
                $where['score']        =   $score;
            }
            $where['channel_type']  =   $D['channel_type'];
            $Data=$where;
            $Data['content']       =   json_encode($content,JSON_UNESCAPED_UNICODE);
            $Data['channel_type']  =   $D['channel_type'];
            $Data['role_type']     =   $D['role_type'];
            $Data['right_exchange']=   $D['pay_type'];
            if(!empty($D['selected_coupon']))
            $Data['coupon']        =   $D['selected_coupon'];
           	$Data['score']         =   $score;
            $Data['download_value']=   config('xy_resume.download_resume_rule_value');
            $Data['price']         =   static::IS_TEST?0.01:$price;
            $Data['original_price']=   $one_resume_download_price;
            $Data['title']         =   '下载ID为：'.$ResumeDownloadedModel->resume_id.'的简历';
            return self::createOrderInfo($where,$Data);
        }else{
            return '下载简历记录不存在或已经支付';
        }
    }
    public static function getJobFairOrderInfo($D)
    {
        if (!$D['company_id'])
            return '请先完善企业资料';
        $JobFairBoothModel=JobFairBoothModel::where(['id'=>$D['alias_id']])->find();
        if(!$JobFairBoothModel)
            return '展位不存在';
        $JobFair=JobFairController::getFind(['job.id'=>$JobFairBoothModel->jid]);
        if(!$JobFair)
            return '招聘会不存在';
        if($JobFair->status===0)
            return '招聘会未开启';
        if($JobFair->status===3)
            return '招聘会已结束';
        $JobFairBoothSum=JobFairBoothModel::where(['company_id'=>$D['company_id']])->count();
        if($JobFairBoothSum>=$JobFair->booth_sum)
            return '已达展位预定上限:'.$JobFair->booth_sum.'个';
        $where=[
            'alias_id'  =>  $JobFairBoothModel->id,
            'uid'       =>  $D['uid'],
            'type'      =>  $D['type'],
            'status'    =>  0,
        ];
        if($JobFairBoothModel->status===1){
            if(!OrdersModel::where($where)->count())
            return '展位已锁定';
        }
        if($JobFairBoothModel->status===2)
            return '请选择其他展位，当前展位已售罄';
        if($D['pay_type']=='job_fair'){
            $job_fair=UserVipRuleModel::alias('rule')
            ->where(['rule.uid'=>$D['uid'],'rule.status'=>1])
            ->join(config('databse.prefix').'vip vip','vip.id=rule.vid')
            ->join('vip_rule_value value','value.id=rule.rid')
            ->whereTime('rule.expiry_time','>',time())->order('rule.level desc')->where(['vip.is_company'=>1,'value.alias'=>'job-fair'])->sum('rule.surplus_value');
            if($job_fair<=0)
                return '当前招聘会场数不足';
        }
        $content=[
            'company_id'    =>  $D['company_id'],
        ];
        $where['channel_type']  =   $D['channel_type'];
        $Data=$where;
        $Data['content']       =   json_encode($content,JSON_UNESCAPED_UNICODE);
        $Data['score']         =   0;
        $Data['channel_type']  =   $D['channel_type'];
        $Data['role_type']     =   $D['role_type'];
        $Data['right_exchange']=   $D['pay_type'];
        if(!empty($D['selected_coupon']))
        $Data['coupon']        =   $D['selected_coupon'];
        $Data['price']         =   static::IS_TEST?0.01:$JobFairBoothModel->price;
        $Data['original_price']=   $JobFairBoothModel->price;
        $Data['title']         =   '预定'.$JobFair->title.'，'.$JobFairBoothModel->identifier.$JobFairBoothModel->index.'展位';
        $JobFairBoothModel->status=1;
        return self::createOrderInfo($where,$Data,$JobFairBoothModel);
    }
    public static function createOrderInfo($where,$D,$DataModel=null)
    {
        $OrdersModel=OrdersModel::where($where)->field('uid,otrade,oprice,otitle,expire_time')->find();
        $UserInfoModel=null;
        $UserScoreModel=null;
        $UserVipRuleData=[];
        $UserVipRuleLogModel=null;
        $PushTaskModel=null;
        $UserVipModel=null;
        if ($OrdersModel) {
            if (!empty($D['right_exchange'])
                &&in_array($D['right_exchange'],['resume', 'top_jobs', 'urgent_jobs', 'job_fair'])) {
                switch ($D['right_exchange']) {
                    case 'resume':
                        $VipRuleValueModel=VipRuleValueModel::where(['alias'=>'download-resume'])->field('id,title,unit')->find();
                        $UserVipRuleLogModel=new UserVipRuleLogModel;
                        $UserVipRuleLogModel->uid       =$D['uid'];
                        $UserVipRuleLogModel->title     =$D['title'];
                        $UserVipRuleLogModel->value     =$D['download_value'];
                        $UserVipRuleModel=new UserVipRuleModel;
                        $UserVipModel=UserVipModel::where(['uid'=>$D['uid']])->find();
                        $UserVipModel->update_vip=1;
                        $UserVipRuleList=UserVipRuleModel::where(['uid'=>$D['uid'],'rid'=>$VipRuleValueModel->id,'status'=>1])->field('id,surplus_value')->order('expiry_time asc,surplus_value asc,level asc')->whereTime('expiry_time','>',time())->select()->toArray();
                        $UserVipRuleData=[];
                        $surplus_value=$D['download_value'];
                        foreach ($UserVipRuleList as $k => $v) {
                            $surplus_value=$v['surplus_value']-$surplus_value;
                            $item=[];
                            $item['id']=$v['id'];
                            $is_break=false;
                            if($surplus_value<0){
                                $item['status']=0;
                                $item['surplus_value']=0;
                            }else{
                                $item['surplus_value']=$surplus_value;
                                $is_break=true;
                            }
                            $UserVipRuleData[]=$item;
                            if($is_break)break;
                        }
                        break;
                    case 'top_jobs':
                        $UserVipRuleLogModel=new UserVipRuleLogModel;
                        $UserVipRuleLogModel->uid       =$D['uid'];
                        $UserVipRuleLogModel->title     =$D['title'];
                        $UserVipRuleLogModel->value     =$D['va_value'];
                        $UserVipRuleModel=new UserVipRuleModel;
                        $UserVipModel=UserVipModel::where(['uid'=>$D['uid']])->find();
                        $UserVipModel->update_vip=1;
                        $UserVipRuleList=UserVipRuleModel::alias('rule')
                        ->where(['rule.uid'=>$UserVipModel->uid,'rule.status'=>1])
                        ->join(config('databse.prefix').'vip vip','vip.id=rule.vid')
                        ->join('vip_rule_value value','value.id=rule.rid')
                        ->whereTime('rule.expiry_time','>',time())->where(['vip.is_company'=>1,'value.alias'=>'top-day'])
                        ->field('rule.id,rule.surplus_value')
                        ->order('rule.expiry_time asc,rule.surplus_value asc,rule.level asc')
                        ->select()->toArray();
                        $UserVipRuleData=[];
                        $surplus_value=$D['va_value'];
                        foreach ($UserVipRuleList as $k => $v) {
                            $surplus_value=$v['surplus_value']-$surplus_value;
                            $item=[];
                            $item['id']=$v['id'];
                            $is_break=false;
                            if($surplus_value<0){
                                $item['status']=0;
                                $item['surplus_value']=0;
                            }else{
                                $item['surplus_value']=$surplus_value;
                                $is_break=true;
                            }
                            $UserVipRuleData[]=$item;
                            if($is_break)break;
                        }
                        break;
                    case 'urgent_jobs':
                        $UserVipRuleLogModel=new UserVipRuleLogModel;
                        $UserVipRuleLogModel->uid       =$D['uid'];
                        $UserVipRuleLogModel->title     =$D['title'];
                        $UserVipRuleLogModel->value     =$D['va_value'];
                        $UserVipRuleModel=new UserVipRuleModel;
                        $UserVipModel=UserVipModel::where(['uid'=>$D['uid']])->find();
                        $UserVipModel->update_vip=1;
                        $UserVipRuleList=UserVipRuleModel::alias('rule')
                        ->where(['rule.uid'=>$UserVipModel->uid,'rule.status'=>1])
                        ->join(config('databse.prefix').'vip vip','vip.id=rule.vid')
                        ->join('vip_rule_value value','value.id=rule.rid')
                        ->whereTime('rule.expiry_time','>',time())->where(['vip.is_company'=>1,'value.alias'=>'urgent-day'])
                        ->field('rule.id,rule.surplus_value')
                        ->order('rule.expiry_time asc,rule.surplus_value asc,rule.level asc')
                        ->select()->toArray();
                        $UserVipRuleData=[];
                        $surplus_value=$D['va_value'];
                        foreach ($UserVipRuleList as $k => $v) {
                            $surplus_value=$v['surplus_value']-$surplus_value;
                            $item=[];
                            $item['id']=$v['id'];
                            $is_break=false;
                            if($surplus_value<0){
                                $item['status']=0;
                                $item['surplus_value']=0;
                            }else{
                                $item['surplus_value']=$surplus_value;
                                $is_break=true;
                            }
                            $UserVipRuleData[]=$item;
                            if($is_break)break;
                        }
                        break;
                    case 'job_fair':
                        $UserVipRuleLogModel=new UserVipRuleLogModel;
                        $UserVipRuleLogModel->uid       =$D['uid'];
                        $UserVipRuleLogModel->title     =$D['title'];
                        $UserVipRuleLogModel->value     =1;
                        $UserVipRuleModel=new UserVipRuleModel;
                        $UserVipModel=UserVipModel::where(['uid'=>$D['uid']])->find();
                        $UserVipModel->update_vip=1;
                        $UserVipRuleList=UserVipRuleModel::alias('rule')
                        ->where(['rule.uid'=>$UserVipModel->uid,'rule.status'=>1])
                        ->join(config('databse.prefix').'vip vip','vip.id=rule.vid')
                        ->join('vip_rule_value value','value.id=rule.rid')
                        ->whereTime('rule.expiry_time','>',time())->where(['vip.is_company'=>1,'value.alias'=>'job-fair'])
                        ->field('rule.id,rule.surplus_value')
                        ->order('rule.expiry_time asc,rule.surplus_value asc,rule.level asc')
                        ->select()->toArray();
                        $UserVipRuleData=[];
                        $surplus_value=1; 
                        if($OrdersModel->oprice<=0){
                            $surplus_value=0;
                            break;
                        }
                        foreach ($UserVipRuleList as $k => $v) {
                            $surplus_value=$v['surplus_value']-$surplus_value;
                            $item=[];
                            $item['id']=$v['id'];
                            $is_break=false;
                            if($surplus_value<0){
                                $item['status']=0;
                                $item['surplus_value']=0;
                            }else{
                                $item['surplus_value']=$surplus_value;
                                $is_break=true;
                            }
                            $UserVipRuleData[]=$item;
                            if($is_break)break;
                        }
                        break;
                }
                $OrdersModel->status=1;
                $OrdersModel->pay_type=5;
                $OrdersModel->pay_time=time();
                $is_pay=true;
            }else{
                $OrdersModel->time=$OrdersModel->expire_time-time();
                return $OrdersModel->toArray();
            }
        }else{
            $otrade=date('YmdHis').GetRand();
            while (OrdersModel::where(['otrade'=>$otrade])->count()>0) {
                $otrade=date('YmdHis').GetRand();
            }
            if (static::IS_TEST)
                $D['title']='测试'.$D['title'];
            $OrdersModel=new OrdersModel;
            $OrdersModel->uid           =   $D['uid'];
            $OrdersModel->type          =   $D['type'];
            $OrdersModel->otrade        =   $otrade;
            $OrdersModel->alias_id      =   $D['alias_id'];
            $OrdersModel->content       =   $D['content'];
            $OrdersModel->channel_type  =   $D['channel_type'];
            $OrdersModel->is_company    =   $D['role_type'];
            $OrdersModel->oprice        =   $D['price'];
            $OrdersModel->original_price=   $D['original_price'];
            $OrdersModel->score         =   $D['score'];
            $OrdersModel->otitle        =   $D['title'];
            $OrdersModel->product_id    =   config('applepay.product_id').'.'.$D['type'].'.'.$D['alias_id'];
            $OrdersModel->expire_time   =   time()+1800;
            $is_pay=false;
            if (!empty($D['right_exchange'])
            	&&in_array($D['right_exchange'],['resume', 'top_jobs', 'urgent_jobs', 'job_fair'])) {
            	switch ($D['right_exchange']) {
                    case 'resume':
                        $VipRuleValueModel=VipRuleValueModel::where(['alias'=>'download-resume'])->field('id,title,unit')->find();
                        $UserVipRuleLogModel=new UserVipRuleLogModel;
                        $UserVipRuleLogModel->uid       =$D['uid'];
                        $UserVipRuleLogModel->title     =$D['title'];
                        $UserVipRuleLogModel->value     =$D['download_value'];
                        $UserVipRuleModel=new UserVipRuleModel;
                        $UserVipModel=UserVipModel::where(['uid'=>$D['uid']])->find();
                        $UserVipModel->update_vip=1;
                        $UserVipRuleList=UserVipRuleModel::where(['uid'=>$D['uid'],'rid'=>$VipRuleValueModel->id,'status'=>1])->field('id,surplus_value')->order('expiry_time asc,surplus_value asc,level asc')->whereTime('expiry_time','>',time())->select()->toArray();
                        $UserVipRuleData=[];
                        $surplus_value=$D['download_value'];
                        foreach ($UserVipRuleList as $k => $v) {
                            $surplus_value=$v['surplus_value']-$surplus_value;
                            $item=[];
                            $item['id']=$v['id'];
                            $is_break=false;
                            if($surplus_value<0){
                                $item['status']=0;
                                $item['surplus_value']=0;
                            }else{
                                $item['surplus_value']=$surplus_value;
                                $is_break=true;
                            }
                            $UserVipRuleData[]=$item;
                            if($is_break)break;
                        }
                        break;
                    case 'top_jobs':
                        $UserVipRuleLogModel=new UserVipRuleLogModel;
                        $UserVipRuleLogModel->uid       =$D['uid'];
                        $UserVipRuleLogModel->title     =$D['title'];
                        $UserVipRuleLogModel->value     =$D['va_value'];
                        $UserVipRuleModel=new UserVipRuleModel;
                        $UserVipModel=UserVipModel::where(['uid'=>$D['uid']])->find();
                        $UserVipModel->update_vip=1;
                        $UserVipRuleList=UserVipRuleModel::alias('rule')
                        ->where(['rule.uid'=>$UserVipModel->uid,'rule.status'=>1])
                        ->join(config('databse.prefix').'vip vip','vip.id=rule.vid')
                        ->join('vip_rule_value value','value.id=rule.rid')
                        ->whereTime('rule.expiry_time','>',time())->where(['vip.is_company'=>1,'value.alias'=>'top-day'])
                        ->field('rule.id,rule.surplus_value')
                        ->order('rule.expiry_time asc,rule.surplus_value asc,rule.level asc')
                        ->select()->toArray();
                        $UserVipRuleData=[];
                        $surplus_value=$D['va_value'];
                        foreach ($UserVipRuleList as $k => $v) {
                            $surplus_value=$v['surplus_value']-$surplus_value;
                            $item=[];
                            $item['id']=$v['id'];
                            $is_break=false;
                            if($surplus_value<0){
                                $item['status']=0;
                                $item['surplus_value']=0;
                            }else{
                                $item['surplus_value']=$surplus_value;
                                $is_break=true;
                            }
                            $UserVipRuleData[]=$item;
                            if($is_break)break;
                        }
                        break;
                    case 'urgent_jobs':
                        $UserVipRuleLogModel=new UserVipRuleLogModel;
                        $UserVipRuleLogModel->uid       =$D['uid'];
                        $UserVipRuleLogModel->title     =$D['title'];
                        $UserVipRuleLogModel->value     =$D['va_value'];
                        $UserVipRuleModel=new UserVipRuleModel;
                        $UserVipModel=UserVipModel::where(['uid'=>$D['uid']])->find();
                        $UserVipModel->update_vip=1;
                        $UserVipRuleList=UserVipRuleModel::alias('rule')
                        ->where(['rule.uid'=>$UserVipModel->uid,'rule.status'=>1])
                        ->join(config('databse.prefix').'vip vip','vip.id=rule.vid')
                        ->join('vip_rule_value value','value.id=rule.rid')
                        ->whereTime('rule.expiry_time','>',time())->where(['vip.is_company'=>1,'value.alias'=>'urgent-day'])
                        ->field('rule.id,rule.surplus_value')
                        ->order('rule.expiry_time asc,rule.surplus_value asc,rule.level asc')
                        ->select()->toArray();
                        $UserVipRuleData=[];
                        $surplus_value=$D['va_value'];
                        foreach ($UserVipRuleList as $k => $v) {
                            $surplus_value=$v['surplus_value']-$surplus_value;
                            $item=[];
                            $item['id']=$v['id'];
                            $is_break=false;
                            if($surplus_value<0){
                                $item['status']=0;
                                $item['surplus_value']=0;
                            }else{
                                $item['surplus_value']=$surplus_value;
                                $is_break=true;
                            }
                            $UserVipRuleData[]=$item;
                            if($is_break)break;
                        }
                        break;
            		case 'job_fair':
		                $UserVipRuleLogModel=new UserVipRuleLogModel;
		                $UserVipRuleLogModel->uid       =$D['uid'];
		                $UserVipRuleLogModel->title     =$D['title'];
		                $UserVipRuleLogModel->value     =1;
		                $UserVipRuleModel=new UserVipRuleModel;
		                $UserVipModel=UserVipModel::where(['uid'=>$D['uid']])->find();
		                $UserVipModel->update_vip=1;
		                $UserVipRuleList=UserVipRuleModel::alias('rule')
                        ->where(['rule.uid'=>$UserVipModel->uid,'rule.status'=>1])
                        ->join(config('databse.prefix').'vip vip','vip.id=rule.vid')
                        ->join('vip_rule_value value','value.id=rule.rid')
                        ->whereTime('rule.expiry_time','>',time())->where(['vip.is_company'=>1,'value.alias'=>'job-fair'])
                        ->field('rule.id,rule.surplus_value')
                        ->order('rule.expiry_time asc,rule.surplus_value asc,rule.level asc')
                        ->select()->toArray();
		                $UserVipRuleData=[];
                        $surplus_value=1; 
                        if($OrdersModel->oprice<=0){
                            $surplus_value=0;
                            break;
                        }
		                foreach ($UserVipRuleList as $k => $v) {
		                    $surplus_value=$v['surplus_value']-$surplus_value;
		                    $item=[];
		                    $item['id']=$v['id'];
		                    $is_break=false;
		                    if($surplus_value<0){
		                        $item['status']=0;
		                        $item['surplus_value']=0;
		                    }else{
		                        $item['surplus_value']=$surplus_value;
		                        $is_break=true;
		                    }
		                    $UserVipRuleData[]=$item;
		                    if($is_break)break;
		                }
            			break;
            	}
                $OrdersModel->status=1;
                $OrdersModel->pay_type=5;
                $OrdersModel->pay_time=time();
                $is_pay=true;
            }else{
                if ($D['score']>0) {
                    $UserInfoModel=UserInfoModel::where(['uid'=>$D['uid']])->find();
                    $UserInfoModel->score=Db::raw('score-'.$D['score']);
                    $UserScoreModel=new UserScoreModel;
                    $UserScoreModel->uid    =   $D['uid'];
                    $UserScoreModel->tid    =   0;
                    $UserScoreModel->score  =   -$D['score'];
                    $UserScoreModel->desc   =   '支付'.$D['title'];
                    if ($D['price']<=0) {
                        $OrdersModel->status=1;
                        $OrdersModel->pay_type=4;
                        $OrdersModel->pay_time=time();
                        $is_pay=true;
                    }
                }
            }
        }
        $CouponListModel=null;
        if ($OrdersModel->oprice>0) {
            if (!empty($D['coupon'])) {
                $CouponListData=[];
                $UseCouponListData=[];
                $UserVip=UserVipModel::where(['uid'=>$OrdersModel->uid])->find();
                $CouponList=CouponListModel::alias('list')->where(['list.uid'=>$OrdersModel->uid,'list.status'=>1,'c.status'=>1])
                ->whereIn('list.alias',$D['coupon'])
                ->join('coupon c','c.id=list.alias_id')
                ->field('list.id,list.alias_id,list.start_time,list.end_time,c.type,c.alias_type,c.price,c.discount,c.satisfy_price,c.superposition,c.vip_level')
                ->withAttr('alias_type',function($v,$data){
                    return json_decode($v,true);
                })->withAttr('price',function($v,$data){
                    return (float)$v;
                })->withAttr('satisfy_price',function($v,$data){
                    return (float)$v;
                })->select();
                if (!$CouponList->isEmpty()) {
                    $oprice=$OrdersModel->oprice;
                    $coupon_price=0;
                    $is_break=false;
                    $is_use_superposition=false;
                    foreach ($CouponList as $item) {
                        if (self::hasCouponIsUse($OrdersModel,$item,$UserVip)) {
                            if ($item->type) {
                                $coupon_price=$coupon_price+($oprice-($oprice*($item->discount/100)));
                            }else{
                                $coupon_price=$coupon_price+$item->price;
                            }
                            if ($is_use_superposition&&!$item->superposition) {
                                $is_break=true;
                                break;
                            }
                            if (!$item->superposition) {
                                $is_use_superposition=true;
                            }
                            $UseCouponListData[]=$item->id;
                            $CouponListData[]=[
                                'id'        =>  $item->id,
                                'status'    =>  2,
                                'use_time'  =>  time()
                            ];
                        }
                    }
                    if ($is_break)return '优惠券使用失败';
                    if ($coupon_price>0) {
                        if ($oprice-$coupon_price<=0) {
                            $OrdersModel->oprice=0;
                            $OrdersModel->status=1;
                            $OrdersModel->pay_type=4;
                            $OrdersModel->pay_time=time();
                            $is_pay=true;
                        }else{
                            $OrdersModel->oprice=$oprice-$coupon_price;
                        }
                        $OrdersModel->coupon=json_encode($UseCouponListData);
                        $CouponListModel=new CouponListModel;
                    }
                }
            }
        }
        if ($is_pay) {
            $PushTaskModel=new PushTaskModel;
            $PushTaskModel->event       =   'orderPaySuccess';
            $PushTaskModel->uid         =   $OrdersModel->uid;
            $PushTaskModel->data        =   json_encode($OrdersModel,JSON_UNESCAPED_UNICODE);
        }
        Db::startTrans();
        try {
            $OrdersModel->save();
            if ($DataModel) $DataModel->save();
            if ($UserInfoModel) $UserInfoModel->save();
            if ($UserScoreModel) $UserScoreModel->save();
            if (!empty($UserVipRuleData)) $UserVipRuleModel->saveAll($UserVipRuleData);
            if ($UserVipRuleLogModel) $UserVipRuleLogModel->save();
            if ($PushTaskModel) $PushTaskModel->save();
            if ($UserVipModel) $UserVipModel->save();
            if (!empty($CouponListData)) $CouponListModel->saveAll($CouponListData);
            // 提交事务
            Db::commit();
            Cache::set('updateUser:'.$OrdersModel->uid,true);
            return [
                'is_pay'        =>  $is_pay,
                'uid'           =>  $OrdersModel->uid,
                'otrade'        =>  $OrdersModel->otrade,
                'oprice'        =>  $OrdersModel->oprice,
                'expire_time'   =>  $OrdersModel->expire_time,
                'time'          =>  $OrdersModel->expire_time-time(),
                'otitle'        =>  $OrdersModel->otitle
            ];
        } catch (Exception $e) {
            //回滚事务
            Db::rollback();
            return '生成订单失败，请重试';
        }
    }
    public static function hasCouponIsUse($OrdersModel,$item,$UserVip)
    {
        if (count($item->alias_type)&&!in_array($OrdersModel->type,$item->alias_type)){
            return false;
        }
        if ($item->satisfy_price>$OrdersModel->original_price){
            return false;
        }
        if ($item->start_time&&$item->start_time>time()) {
            return false;
        }
        if ($item->end_time<time()) {
            return false;
        }
        if ($item->vip_level) {
            if(!$UserVip)
                return false;
            if ($item->vip_leve>$UserVip->company_vip_level)
                return false;
        }
        return true;
    }
    public static function WebPlaceAnOrder($order,$pay_type)
    {
    	switch ($pay_type) {
    		case 'alipay':
                return self::aliPay($order);
    		case 'wxpay':
                return self::wxPay($order);
    	}
    }
    public static function AppPlaceAnOrder($order,$pay_type)
    {
        switch ($pay_type) {
            case 'alipay':
                return self::aliPayApp($order);
            case 'wxpay':
                return self::wxPayApp($order);
            case 'applepay':
                return parent::ajaxReturn('success',MsgCode::$success,['otrade'=>$order['otrade'],'time'=>$order['time']]);
        }
    }
    public static function H5PlaceAnOrder($order,$pay_type)
    {
        switch ($pay_type) {
            case 'alipay':
                return self::aliPayH5($order);
            case 'wxpay':
				$agent = strtolower(request()->header('user-agent'));
	            if (strpos($agent,'micromessenger')) {
                	return self::wxPayH5Jsapi($order);
	            }else{
                	return self::wxPayH5($order);
	            }
        }
    }
    public static function ToutiaoPlaceAnOrder($order,$pay_type)
    {
        switch ($pay_type) {
            case 'toutiao':
                return self::toutiaoPay($order);
        }
    }
    public static function BaiduPlaceAnOrder($order,$pay_type)
    {
        switch ($pay_type) {
            case 'baidu':
                return self::baiduPay($order);
        }
    }
    public static function AliMpPayPlaceAnOrder($order,$pay_type)
    {
        switch ($pay_type) {
            case 'alipay':
                return self::aliPayMp($order);
        }
    }
    public static function WechatminiprogramPlaceAnOrder($order,$pay_type)
    {
        switch ($pay_type) {
            case 'wxpay':
                return self::wxPayWechatminiprogram($order);
        }
    }
    public static function aliPay($order)
    {
        //读取支付宝配置
        $alipayConfig=config('alipay');
        if(empty($alipayConfig['status']) || !$alipayConfig['status'])
            return parent::ajaxReturn('支付宝支付暂不可用',MsgCode::$error);

        $options = new AliConfig();
        $options->protocol              = 'https';
        $options->gatewayHost           = 'openapi.alipay.com';
        $options->signType              = $alipayConfig['sign_type'];
        $options->appId                 = $alipayConfig['appid'];
        $options->merchantPrivateKey    = $alipayConfig['rsaPrivateKey'];
        $options->alipayPublicKey       = $alipayConfig['alipayPublicKey'];
        $options->notifyUrl             = $alipayConfig['notify_url'];
        $options->encryptKey            = $alipayConfig['encryptKey'];
        Factory::setOptions($options);
        try {
            //2. 发起API调用（以支付能力下的统一收单交易创建接口为例）
            $result = Factory::payment()->facetoface()->precreate($order['otitle'], $order['otrade'], $order['oprice']);
            $responseChecker = new ResponseChecker();
            //3. 处理响应或异常
            if ($responseChecker->success($result)) {
                return parent::ajaxReturn('success',MsgCode::$success,['url'=>$result->qrCode,'otrade'=>$order['otrade'],'time'=>$order['time']]);
            } else {
            return parent::ajaxReturn($result->msg."，".$result->subMsg.PHP_EOL,MsgCode::$error);
            }
        } catch (Exception $e) {
            return parent::ajaxReturn($e->getMessage(). PHP_EOL,MsgCode::$error);
        }
    }
    public static function aliPayApp($order)
    {
        //读取支付宝配置
        $alipayConfig=config('alipay');
        if(empty($alipayConfig['status']) || !$alipayConfig['status'])
            return parent::ajaxReturn('支付宝支付暂不可用',MsgCode::$error);

        $options = new AliConfig();
        $options->protocol              = 'https';
        $options->gatewayHost           = 'openapi.alipay.com';
        $options->signType              = $alipayConfig['sign_type'];
        $options->appId                 = $alipayConfig['appid'];
        $options->merchantPrivateKey    = $alipayConfig['rsaPrivateKey'];
        $options->alipayPublicKey       = $alipayConfig['alipayPublicKey'];
        $options->notifyUrl             = $alipayConfig['notify_url'];
        $options->encryptKey            = $alipayConfig['encryptKey'];
        Factory::setOptions($options);
        try {
            //2. 发起API调用（以支付能力下的统一收单交易创建接口为例）
            $result = Factory::payment()->app()->pay($order['otitle'], $order['otrade'], $order['oprice']);
            $responseChecker = new ResponseChecker();
            //3. 处理响应或异常
            if ($responseChecker->success($result)) {
                return parent::ajaxReturn('success',MsgCode::$success,['body'=>$result->body,'otrade'=>$order['otrade'],'time'=>$order['time']]);
            } else {
            return parent::ajaxReturn($result->msg."，".$result->subMsg.PHP_EOL,MsgCode::$error);
            }
        } catch (Exception $e) {
            return parent::ajaxReturn($e->getMessage(). PHP_EOL,MsgCode::$error);
        }
    }
    public static function aliPayH5($order)
    {
        //读取支付宝配置
        $alipayConfig=config('alipay');
        if(empty($alipayConfig['status']) || !$alipayConfig['status'])
            return parent::ajaxReturn('支付宝支付暂不可用',MsgCode::$error);

        $options = new AliConfig();
        $options->protocol              = 'https';
        $options->gatewayHost           = 'openapi.alipay.com';
        $options->signType              = $alipayConfig['sign_type'];
        $options->appId                 = $alipayConfig['appid'];
        $options->merchantPrivateKey    = $alipayConfig['rsaPrivateKey'];
        $options->alipayPublicKey       = $alipayConfig['alipayPublicKey'];
        $options->notifyUrl             = $alipayConfig['notify_url'];
        $options->encryptKey            = $alipayConfig['encryptKey'];
        Factory::setOptions($options);
        try {
            //2. 发起API调用（以支付能力下的统一收单交易创建接口为例）
            $result = Factory::payment()->wap()->pay($order['otitle'], $order['otrade'], $order['oprice'],config('web.h5'),$alipayConfig['notify_url']);
            $responseChecker = new ResponseChecker();
            //3. 处理响应或异常
            if ($responseChecker->success($result)) {
            	if(request()->isPost()){
                	return parent::ajaxReturn('success',MsgCode::$success,['body'=>config('web.h5').'/pay/getH5AlipayForm?otrade='.$order['otrade'],'otrade'=>$order['otrade'],'time'=>$order['time']]);
            	}else{
	            	$html='<!DOCTYPE html> <html lang="zh-cn"> <head> <meta charset="UTF-8"> <title>Pay</title> </head> <body>'.$result->body.'</body> </html>';
	            	return $html;
            	}
            } else {
            return parent::ajaxReturn($result->msg."，".$result->subMsg.PHP_EOL,MsgCode::$error);
            }
        } catch (Exception $e) {
            return parent::ajaxReturn($e->getMessage(). PHP_EOL,MsgCode::$error);
        }
    }
    public static function aliPayMp($order)
    {
        $UserAliModel=UserAliModel::where(['uid'=>$order['uid']])->find();
        if(!$UserAliModel)
            return parent::ajaxReturn('请先授权支付宝',MsgCode::$error);
        //读取支付宝配置
        $alipayConfig=config('alipay');
        if(empty($alipayConfig['status']) || !$alipayConfig['status'])
            return parent::ajaxReturn('支付宝支付暂不可用',MsgCode::$error);

        $options = new AliConfig();
        $options->protocol              = 'https';
        $options->gatewayHost           = 'openapi.alipay.com';
        $options->signType              = $alipayConfig['sign_type'];
        $options->appId                 = $alipayConfig['appid'];
        $options->merchantPrivateKey    = $alipayConfig['rsaPrivateKey'];
        $options->alipayPublicKey       = $alipayConfig['alipayPublicKey'];
        $options->notifyUrl             = $alipayConfig['notify_url'];
        $options->encryptKey            = $alipayConfig['encryptKey'];
        Factory::setOptions($options);
        try {
            //2. 发起API调用（以支付能力下的统一收单交易创建接口为例）
            $result = Factory::payment()->common()->create($order['otitle'], $order['otrade'], $order['oprice'],$UserAliModel->user_id);
            $responseChecker = new ResponseChecker();
            //3. 处理响应或异常
            if ($responseChecker->success($result)) {
                return parent::ajaxReturn('success',MsgCode::$success,['body'=>['tradeNO'=>$result->tradeNo],'otrade'=>$order['otrade'],'time'=>$order['time']]);
            } else {
            return parent::ajaxReturn($result->msg."，".$result->subMsg.PHP_EOL,MsgCode::$error);
            }
        } catch (Exception $e) {
            return parent::ajaxReturn($e->getMessage(). PHP_EOL,MsgCode::$error);
        }
    }
    public static function wxPay($order)
    {
        $wxpayConfig=config('wxpay');
        if(empty($wxpayConfig['status']) || !$wxpayConfig['status'])
            return parent::ajaxReturn('微信支付暂不可用',MsgCode::$error);
        $nonce_str=Str::random();
        $data=[
            'appid'             =>  $wxpayConfig['appid'],
            'mch_id'            =>  $wxpayConfig['mchid'],
            'body'              =>  $order['otitle'],
            'nonce_str'         =>  $nonce_str,
            'notify_url'        =>  $wxpayConfig['notify_url'],
            'out_trade_no'      =>  $order['otrade'],
            'spbill_create_ip'  =>  request()->ip(),
            'total_fee'         =>  $order['oprice'] * 100,
            'product_id'        =>  $order['otrade'],
            'trade_type'        =>  'NATIVE',
            'time_start'        =>  date('YmdHis',$order['expire_time']-1800),
            'time_expire'       =>  date('YmdHis',$order['expire_time']),
        ];
        $data['sign']=self::MakeSign($data);
            //微信支付类
        $wxOrder = WxPayApi::unifiedOrderApp(self::ToUrlXml($data));
        if(!empty($wxOrder['return_code']) && $wxOrder['return_code']=="SUCCESS"){
            if($wxOrder['result_code']=="SUCCESS"){
                return parent::ajaxReturn('success',MsgCode::$success,['url'=>$wxOrder['code_url'],'otrade'=>$order['otrade'],'time'=>$order['time']]);
            }else{
                return parent::ajaxReturn($wxOrder['err_code_des'],MsgCode::$error);
            }
        }else{
            return parent::ajaxReturn($wxOrder['return_msg'],MsgCode::$error);
        }
    }
    public static function wxPayApp($order)
    {
        $wxpayConfig=config('wxpay');
        if(empty($wxpayConfig['status']) || !$wxpayConfig['status'])
            return parent::ajaxReturn('微信支付暂不可用',MsgCode::$error);
        $nonce_str=Str::random();
        $data=[
            'appid'             =>  $wxpayConfig['appid'],
            'mch_id'            =>  $wxpayConfig['mchid'],
            'body'              =>  $order['otitle'],
            'nonce_str'         =>  $nonce_str,
            'notify_url'        =>  $wxpayConfig['notify_url'],
            'out_trade_no'      =>  $order['otrade'],
            'spbill_create_ip'  =>  request()->ip(),
            'total_fee'         =>  $order['oprice'] * 100,
            'product_id'        =>  $order['otrade'],
            'trade_type'        =>  'NATIVE',
            'time_start'        =>  date('YmdHis',$order['expire_time']-1800),
            'time_expire'       =>  date('YmdHis',$order['expire_time']),
        ];
        $data['sign']=self::MakeSign($data);
            //微信支付类
        $wxOrder = WxPayApi::unifiedOrderApp(self::ToUrlXml($data));
        if(!empty($wxOrder['return_code']) && $wxOrder['return_code']=="SUCCESS"){
            if($wxOrder['result_code']=="SUCCESS"){
                $payInfo=[
                    'appid' =>  $wxpayConfig['appid'],
                    'partnerid' =>  "".$wxpayConfig['mchid'],
                    'prepayid' =>  $wxOrder['prepay_id'],
                    'noncestr' =>  $wxOrder['nonce_str'],
                    'package' =>  'Sign=WXPay',
                    'timestamp' =>  "".$order['expire_time'],
                ];
                $payInfo['sign']=self::MakeSign($payInfo);

                return parent::ajaxReturn('success',MsgCode::$success,['body'=>$payInfo,'otrade'=>$order['otrade'],'time'=>$order['time']]);
            }else{
                return parent::ajaxReturn($wxOrder['err_code_des'],MsgCode::$error);
            }
        }else{
            return parent::ajaxReturn($wxOrder['return_msg'],MsgCode::$error);
        }
    }
    public static function wxPayH5($order)
    {
        $wxpayConfig=config('wxpay');
        $wxpayMpConfig=config('xy_wechat_mp');
        if(empty($wxpayConfig['status']) || !$wxpayConfig['status'])
            return parent::ajaxReturn('微信支付暂不可用',MsgCode::$error);
        if(empty($wxpayMpConfig['status']) || !$wxpayMpConfig['status'])
            return parent::ajaxReturn('微信支付暂不可用',MsgCode::$error);
        $nonce_str=Str::random();
        $data=[
            'appid'             =>  $wxpayMpConfig['appid'],
            'mch_id'            =>  $wxpayConfig['mchid'],
            'body'              =>  $order['otitle'],
            'nonce_str'         =>  $nonce_str,
            'notify_url'        =>  $wxpayConfig['notify_url'],
            'out_trade_no'      =>  $order['otrade'],
            'spbill_create_ip'  =>  request()->ip(),
            'total_fee'         =>  $order['oprice'] * 100,
            'product_id'        =>  $order['otrade'],
            'trade_type'        =>  'MWEB',
            'time_start'        =>  date('YmdHis',$order['expire_time']-1800),
            'time_expire'       =>  date('YmdHis',$order['expire_time']),
            'scene_info'        =>  json_encode([
                    'h5_info'=>[
                        "type"=>"Wap",
                        "wap_url"=>config('web.h5'),
                        "wap_name"=>config('web.name')
                    ]
                ],JSON_UNESCAPED_UNICODE)
        ];
        $data['sign']=self::MakeSign($data);
            //微信支付类
        $wxOrder = WxPayApi::unifiedOrderApp(self::ToUrlXml($data));
        if(!empty($wxOrder['return_code']) && $wxOrder['return_code']=="SUCCESS"){
            if($wxOrder['result_code']=="SUCCESS"){
                return parent::ajaxReturn('success',MsgCode::$success,['body'=>$wxOrder['mweb_url'],'otrade'=>$order['otrade'],'time'=>$order['time'],'is_wx'=>0]);
            }else{
                return parent::ajaxReturn($wxOrder['err_code_des'],MsgCode::$error);
            }
        }else{
            return parent::ajaxReturn($wxOrder['return_msg'],MsgCode::$error);
        }
    }
    public static function wxPayH5Jsapi($order)
    {
        $wxpayConfig=config('wxpay');
        $wxpayMpConfig=config('xy_wechat_mp');
        if(empty($wxpayConfig['status']) || !$wxpayConfig['status'])
            return parent::ajaxReturn('微信支付暂不可用',MsgCode::$error);
        if(empty($wxpayMpConfig['status']) || !$wxpayMpConfig['status'])
            return parent::ajaxReturn('微信支付暂不可用',MsgCode::$error);
        $UserWxModel=UserWxModel::where(['uid'=>$order['uid']])->find();
        if(!$UserWxModel||!$UserWxModel->wx_openid)
            return parent::ajaxReturn('请先绑定微信公众号',MsgCode::$error);
        $nonce_str=Str::random();
        $data=[
            'appid'             =>  $wxpayMpConfig['appid'],
            'mch_id'            =>  $wxpayConfig['mchid'],
            'body'              =>  $order['otitle'],
            'out_trade_no'      =>  $order['otrade'],
            'nonce_str'         =>  $nonce_str,
            'notify_url'        =>  $wxpayConfig['notify_url'],
            'spbill_create_ip'  =>  request()->ip(),
            'total_fee'         =>  $order['oprice'] * 100,
            'product_id'        =>  $order['otrade'],
            'trade_type'        =>  'JSAPI',
            'openid'            =>  $UserWxModel->wx_openid,
            'time_expire'       =>  date('YmdHis',$order['expire_time']),
        ];
        $data['sign']=self::MakeSign($data);
            //微信支付类
        $wxOrder = WxPayApi::unifiedOrderApp(self::ToUrlXml($data));
        if(!empty($wxOrder['return_code']) && $wxOrder['return_code']=="SUCCESS"){
            if($wxOrder['result_code']=="SUCCESS"){
                $payInfo=[
                    'appId'         =>  $wxpayMpConfig['appid'],
                    'package'      =>  'prepay_id='.$wxOrder['prepay_id'],
                    'nonceStr'      =>  $wxOrder['nonce_str'],
                    'signType'      =>  'MD5',
                    'timeStamp'     =>  "".$order['expire_time'],
                ];
                $payInfo['sign']=self::MakeSign($payInfo);
                return parent::ajaxReturn('success',MsgCode::$success,['body'=>$payInfo,'otrade'=>$order['otrade'],'time'=>$order['time'],'is_wx'=>1]);
            }else{
                return parent::ajaxReturn($wxOrder['err_code_des'],MsgCode::$error);
            }
        }else{
            return parent::ajaxReturn($wxOrder['return_msg'],MsgCode::$error);
        }
    }
    public static function wxPayWechatminiprogram($order)
    {
        $wxpayConfig=config('wxpay');
        if(empty($wxpayConfig['status']) || !$wxpayConfig['status'])
            return parent::ajaxReturn('微信支付暂不可用',MsgCode::$error);
        $wxpayMpConfig=config('xy_wechatminiprogram');
        if(empty($wxpayMpConfig['status']) || !$wxpayMpConfig['status'])
            return parent::ajaxReturn('微信小程序暂不可用',MsgCode::$error);
        $UserWxModel=UserWxModel::where(['uid'=>$order['uid']])->find();
        if(!$UserWxModel||!$UserWxModel->mp_openid)
            return parent::ajaxReturn('未获取到用户微信信息',MsgCode::$error);
        $nonce_str=Str::random();
        $data=[
            'appid'             =>  $wxpayMpConfig['appid'],
            'mch_id'            =>  $wxpayConfig['mchid'],
            'body'              =>  $order['otitle'],
            'out_trade_no'      =>  $order['otrade'],
            'nonce_str'         =>  $nonce_str,
            'notify_url'        =>  $wxpayConfig['notify_url'],
            'spbill_create_ip'  =>  request()->ip(),
            'total_fee'         =>  $order['oprice'] * 100,
            'product_id'        =>  $order['otrade'],
            'trade_type'        =>  'JSAPI',
            'openid'            =>  $UserWxModel->mp_openid,
            'time_expire'       =>  date('YmdHis',$order['expire_time']),
        ];
        $data['sign']=self::MakeSign($data);
            //微信支付类
        $wxOrder = WxPayApi::unifiedOrderApp(self::ToUrlXml($data));
        if(!empty($wxOrder['return_code']) && $wxOrder['return_code']=="SUCCESS"){
            if($wxOrder['result_code']=="SUCCESS"){
                $payInfo=[
                    'appId'         =>  $wxpayMpConfig['appid'],
                    'package'      =>  'prepay_id='.$wxOrder['prepay_id'],
                    'nonceStr'      =>  $wxOrder['nonce_str'],
                    'signType'      =>  'MD5',
                    'timeStamp'     =>  "".$order['expire_time'],
                ];
                $payInfo['sign']=self::MakeSign($payInfo);
                return parent::ajaxReturn('success',MsgCode::$success,['body'=>$payInfo,'otrade'=>$order['otrade'],'time'=>$order['time'],'is_wx'=>1]);
            }else{
                return parent::ajaxReturn($wxOrder['err_code_des'],MsgCode::$error);
            }
        }else{
            return parent::ajaxReturn($wxOrder['return_msg'],MsgCode::$error);
        }
    }
    public static function toutiaoPay($order)
    {
        //读取支付宝配置
        $toutiaoPayConfig=config('xy_toutiaopay');
        if(empty($toutiaoPayConfig['status']) || !$toutiaoPayConfig['status'])
            return parent::ajaxReturn('字节小程序支付暂不可用',MsgCode::$error);
        $options = new \stdClass;
        $options->app_id            = $toutiaoPayConfig['appid'];
        $options->out_order_no      = $order['otrade'];
        $options->total_amount      = $order['oprice']*100;
        $options->subject           = $order['otitle'];
        $options->body              = $order['otitle'];
        $options->notify_url        = $toutiaoPayConfig['notify_url'];
        $options->sign              = self::toutiaoSign(json_decode(json_encode($options,JSON_UNESCAPED_UNICODE),true),$toutiaoPayConfig['salt']);
        $ret=URL::post('https://developer.toutiao.com/api/apps/ecpay/v1/create_order',json_encode($options,JSON_UNESCAPED_UNICODE));
        if ($ret) {
            $result=json_decode($ret,true);
            if(isset($result['err_no'])){
                if($result['err_no']===0){
                    return parent::ajaxReturn('success',MsgCode::$success,['otrade'=>$order['otrade'],'time'=>$order['time'],'body'=>$result['data']]);
                }else{
                    return parent::ajaxReturn($result['err_tips'],MsgCode::$error);
                }
            }
        }
        return parent::ajaxReturn('生成订单失败，请重试',MsgCode::$error);
    }
    public static function baiduPay($order)
    {
        //读取支付宝配置
        $baiduPayConfig=config('xy_baidupay');
        if(empty($baiduPayConfig['status']) || !$baiduPayConfig['status'])
            return parent::ajaxReturn('百度小程序支付暂不可用',MsgCode::$error);
        $options = new \stdClass;
        $options->dealId      = $baiduPayConfig['dealId'];
        $options->appKey      = $baiduPayConfig['key'];
        $options->totalAmount = $order['oprice']*100;
        $options->tpOrderId   = $order['otrade'];
        $options->dealTitle   = $order['otitle'];
        $options->signFieldsRange=1;
        $options->rsaSign     = BaiduPay::sign(json_decode(json_encode($options,JSON_UNESCAPED_UNICODE),true),$baiduPayConfig['rsaPrivateKey']);
        return parent::ajaxReturn('success',MsgCode::$success,['otrade'=>$order['otrade'],'time'=>$order['time'],'body'=>$options]);
    }
    public static function toutiaoSign($map,$salt) {
        $rList =[];
        foreach($map as $k => $v) {
            if ($k == "other_settle_params" || $k == "app_id" || $k == "sign" || $k == "thirdparty_id")
                continue;
            $value = trim(strval($v));
            $len = strlen($value);
            if ($len > 1 && substr($value, 0,1)=="\"" && substr($value,$len, $len-1)=="\"")
                $value = substr($value,1, $len-1);
            $value = trim($value);
            if ($value == "" || $value == "null")
                continue;
            array_push($rList, $value);
        }
        array_push($rList, $salt);
        sort($rList, 2);
        return md5(implode('&', $rList));
    }
    /**
     * 格式化参数格式化成url参数
     */
    public static function ToUrlXml($data)
    {
        $buff = "<xml>";
        foreach ($data as $k => $v) $buff.="<".$k.">".$v."</".$k.">";
        $buff .= "</xml>";
        return $buff;
    }
    /**
     * 格式化参数格式化成url参数
     */
    public static function ToUrlParams($data)
    {
        $buff = "";
        foreach ($data as $k => $v)
            if($k != "sign" && $v != "" && !is_array($v))
                $buff .= $k . "=" . $v . "&";
        $buff = trim($buff, "&");
        return $buff;
    }
    /**
     * 生成签名
     * @return 签名，本函数不覆盖sign成员变量，如要设置签名需要调用SetSign方法赋值
     */
    public static function MakeSign($data)
    {
        //签名步骤一：按字典序排序参数
        ksort($data);
        $string = self::ToUrlParams($data);
        // $string = http_build_query($data);
        //签名步骤二：在string后加入KEY
        $string = $string . "&key=".config('wxpay.key');
        //签名步骤三：MD5加密
        $string = md5($string);
        //签名步骤四：所有字符转为大写
        $result = strtoupper($string);
        return $result;
    }
}
