<?php
defined('IN_WEB') or die('Include Error!');
/**
 * 支付相关
 */
class Payment
{
    private $_securityKey = '$sa2019@sz^6688$'; //下单的安全码

    /**
     * 验证码,用作下单的验证
     * @param $param
     * @return bool
     * Created by: Owen
     * Created on: 2020/3/27 19:11
     */
    protected function verify($param){
        $uid = oo::functions()->uint($param['uid']);
        $gid = oo::functions()->uint($param['gid']);
        $device = oo::functions()->escape($param['device']);
        $ggameid = oo::functions()->uint($param['ggameid']);
        $sign = oo::functions()->escape($param['sign']);
        $verify = md5($uid.'|'.$gid.'|'.$device.'|'.$ggameid.'|'.$this->_securityKey);
        return $verify == $sign ? true : false;
    }

    /**
     * 发货验证
     * @param $param
     * @return bool
     * Created by: Owen
     * Created on: 2020/3/27 19:11
     */
    protected function verifySuc($param){
        $sign = oo::functions()->escape($param['sign']);
        if (!$sign) {
            return false;
        }
        $uid = oo::functions()->uint($param['uid']);
        $time = oo::functions()->uint($param['time']);
        $orderId = oo::functions()->escape($param['orderId']);
        $transactionId = '';
        if(isset($param['transactionId'])){
            $transactionId = $param['transactionId'];
        }
        $str = $uid.'$2019$'.$orderId.'$'.$time.'&^%'.$transactionId;
        $verifyStr = md5($str);
        return $sign == $verifyStr ? true : false;
    }

    /**
     * 创建订单号
     * @param $param
     * @return false|string
     * Created by: Owen
     * Created on: 2020/3/27 19:12
     */
    public function createOrder($param){
        $uid = oo::functions()->uint($param['uid']);
        $gid = oo::functions()->uint($param['gid']);//商品ID
        $ggameid = oo::functions()->uint($param['ggameid']);//游戏平台ID
        if(empty($uid) || empty($gid) || empty($ggameid) ){
            return oo::response(-1,[],'参数错误');
        }
        if(!self::verify($param)){
            return oo::response(-10,[],'签名异常');
        }
        $data = oo::commonOprModel('payment')->createOrder($param);
        return json_encode($data);
    }

    /**
     * 支付
     * @param $param
     * @return false|string
     * Created by: Owen
     * Created on: 2019/11/14 18:20
     */
    public function success($param){
        if ($param['sign'] && !$this->verifySuc($param)) {
            oo::logs()->debug3(["err"=>'支付上报签名异常',"param"=>$param,'act' => 'success'],'paymentfail_err.log');
            return oo::response(-2,[],'签名异常');
        }
        $data = oo::commonOprModel('payment')->payment($param);
        return $data;
    }

    /**
     * 新版支付
     * @param $param
     * @return string
     * Created by: Owen
     * Created on: 2020/4/26 17:13
     */
    public function successNew($param){
        $sign = oo::functions()->escape($param['sign']);
        if (empty($sign)) {
            oo::logs()->debug3(["err"=>'支付上报签名参数缺失',"param"=>$param, 'act' => 'successNew'],'paymentfail_err.log');
            return oo::response(-2,[],'签名异常');
        }
        $uid       = oo::functions()->uint($param['uid']);
        if(!funs::concurrentLock($uid,'successNew',6)){
            oo::logs()->debug3(["err"=>'支付上报签请求频繁',"param"=>$param, 'act' => 'successNew'],'paymentfail_err.log');
            return json_encode(['code'=>-500,'msg'=>'order be locked']);
        }
        $time      = oo::functions()->uint($param['time']);
        $extraData = oo::functions()->escape($param['extraData']);
        if(isset($param['transactionId'])){
            $transactionId = $param['transactionId'];
        }
        $str = $uid.'$2019$'.$extraData.'$'.$time.'&^%'.$transactionId;
        $verifyStr = md5($str);
        if(!funs::concurrentLock($uid,$verifyStr,6)){
            return json_encode(['code'=>-500]);
        }
        if ($verifyStr != $sign) {
            oo::logs()->debug3(["err"=>'支付上报签名异常',"param"=>$param, 'act' => 'successNew'],'paymentfail_err.log');
            return oo::response(-2,[],'签名异常');
        }
        return oo::commonOprModel('payment')->payment2($param);
    }

    /**
     * 新版支付
     * @param $param
     * @return string
     * Created by: Owen
     * Created on: 2020/4/26 17:13
     */
    public function successTwo($param){
        $sign      = oo::functions()->escape($param['sign']);
        $time      = oo::functions()->uint($param['time']);
        $extraData = oo::functions()->escape($param['extraData']);
        $uid       = oo::functions()->uint($param['uid']);
        if (empty($sign)) {
            oo::logs()->debug3(["err"=>'支付上报签名参数缺失',"param"=>$param,'act' => 'successTwo'],'paymentfail_err.log');
            return oo::response(-2,['sign'=>$sign],'签名异常');
        }
        if(empty($extraData)||empty($uid)||empty($time)){
            return oo::response(-1,[],'param error');
        }
        if(!funs::concurrentLock($uid.md5((string)$extraData),'successTwo',6)){
            oo::logs()->debug3(["err"=>'支付上报签请求频繁',"param"=>$param,'act' => 'successTwo'],'paymentfail_err.log');
            return json_encode(['code'=>-500,'msg'=>'order be locked']);
        }
        if(isset($param['transactionId'])){
            $transactionId = $param['transactionId'];
        }
        $str = $uid.'$2019$'.$extraData.'$'.$time.'&^%'.$transactionId;
        $verifyStr = md5($str);
        if ($verifyStr != $sign) {
            oo::logs()->debug3(["err"=>'支付上报签名错误',"param"=>$param,'act' => 'successTwo'],'paymentfail_err.log');
            oo::commonOprModel('payment')->createFailOrder($param);
            return oo::response(-2,[
                'sign' => $sign,
                'str'  => $str,
                'md5'  => $verifyStr,
                'uid'  => $uid,
                'time' => $time,
                'extraData' =>$extraData,
            ],'签名异常');
        }
        oo::logs()->debug3($param,"paymentLog");
        $ret = oo::commonOprModel('payment')->payment3($param);
        $retArr = json_decode($ret, true);
        if(isset($retArr['code']) && $retArr['code'] != 1){ //插入失败订单记录
            oo::commonOprModel('payment')->createFailOrder($param);
        }
        return $ret;
    }

    /**
     * 购买宝箱
     * @param $param
     * @return false|string
     * Created by: Owen
     * Created on: 2020/3/27 19:16
     */
    public function chest($param){
        $uid = oo::functions()->uint($param['uid']);
        $gid = oo::functions()->uint($param['gid']);
        if(empty($uid) || empty($gid)){
            return oo::response(-1,[],'参数错误');
        }
        $gsku = [301=>"woodenChest",302=>"goldenChest",303=>"magicalChest","304"=>"superChest"][$gid];
        if(empty($gsku)){
            return oo::response(-2,[],'商品异常');
        }
        $property  = oo::commonOprModel('member')->getUserAssetsInfo($uid);
        $level     = intval($property['levelId']);
        $cardChest = oo::commonOprModel('goods')->getCardChestConfig($level);
        $goodMoney = $cardChest[$gsku];
        if($goodMoney > intval($property['money'])){
            return oo::response(-3,[],'金币不足');
        }
      	oo::commonOprRedis('common')->incr(okeys::incr($gsku));
        $tips = ["woodenChest"=>"木质宝箱","goldenChest"=>"白银宝箱","magicalChest"=>"黄金宝箱","304"=>"高级黄金宝箱"][$gsku];
        oo::commonOprModel('member')->optProperty($uid,['money'=>$goodMoney],'-',400,"购买宝箱:".$tips);
        $type = [301=>1,302=>2,303=>3,304=>4][$gid];
        oo::commonOprModel('props')->addUserProps($uid,$type,1,0,400);
        return oo::response(1);
    }

  	/**
     * 购买喇叭
     * @param $param
     * @return string
     * Created by: Owen
     * Created on: 2019/11/20 20:00
     */
    public function speaker($param){
        $uid = oo::functions()->uint($param['uid']);
        if(empty($uid)){
            return oo::response(-1,[],'参数错误');
        }
        $coins =  oo::commonOprModel('goods')->getGoodCoins($uid,'coins01');
        $coins = ceil($coins/2);
        $property = oo::commonOprModel('member')->getUserAssetsInfo($uid);
        $money = intval($property['money']);
        if($money<$coins){
            return oo::response(-2,[],'金币不足');
        }
        oo::commonOprModel('member')->optProperty($uid,array('money'=>$coins),'-',401,"购买喇叭");
        $num = oo::commonOprRedis('common')->hGet(okeys::chatMaxNum(),$uid);
        oo::commonOprRedis('common')->hSet(okeys::chatMaxNum(),$uid,intval($num)-10);
        return oo::response(1,['num'=>1-intval($num)+10]);
    }

    /**
     * 购买矿工小游戏
     * @param $param
     * @return string
     * Created by: Owen
     * Created on: 2020/5/12 12:21
     */
    public function miningGame($param){
        $uid = oo::functions()->uint($param['uid']);
        if(empty($uid)){
            return oo::response(-1,[],'参数错误');
        }
        $version = oo::commonOprModel('user')->getUserVersion($uid);
        if(oo::compareVersion($version,'1.7.2')){
            return oo::commonOprModel('payment')->buyMiningGameCountByDiamond($uid);
        }
        return oo::commonOprModel('payment')->buyMiningGameCount($uid);
    }

    /**
     * 购买星星兑换次数
     * @param $param
     * @return string
     * Created by: Owen
     * Created on: 2020/6/11 10:28
     */
    public function starExchange($param){
        $uid = oo::functions()->uint($param['uid']);
        $propsId= oo::functions()->uint($param['propsId']);
        if(empty($uid) || empty($propsId)){
            return oo::response(-1,[],'参数错误');
        }
        return oo::commonOprModel('payment')->starExchange($uid,$propsId);
    }

    /**
     * 购买连环礼包
     * @param $param
     * @return string
     * Created by: Owen
     * Created on: 2020/5/12 12:21
     */
    public function buyGift($param){
        $uid = oo::functions()->uint($param['uid']);
        $gid = oo::functions()->uint($param['gid']);
        if(!funs::concurrentLock($uid,'payment_buyGift')){
            return oo::response(errorCode::API_FREQUENT_REQUESTS,[],'频繁请求');
        }
        if(empty($uid) || empty($gid)){
            return oo::response(errorCode::REQUEST_PARAM_ERROR,[],'参数错误');
        }
        $aid  = oo::commonOprRedis('activity')->get(okeys::bindChainGift($uid));
        if($aid){
            $ret = oo::commonOprModel('payment')->buyGiftNew($uid,$aid,$gid);
        }else{//没有活动返回默认奖励
            $ret = oo::commonOprModel('payment')->buyGift($uid,$gid);
        }
        return $ret;
    }

    /**
     * Notes:购买超级连环礼包(金币购买或者免费)
     * User: wsc
     * Time: 2020/11/25 19:31
     * @param $param
     * @return string
     */
    public function buySuperSerialPack($param){
        $uid = oo::functions()->uint($param['uid']);
        $gid = oo::functions()->uint($param['gid']);
        if(!funs::concurrentLock($uid,'payment_buySuperSerialPack')){
            return oo::response(errorCode::API_FREQUENT_REQUESTS,[],'频繁请求');
        }
        if(empty($uid) || empty($gid)){
            return oo::response(errorCode::REQUEST_PARAM_ERROR,[],'参数错误');
        }
        if($gid>760){
            $aid  = oo::commonOprRedis('activity')->get(okeys::bindSuperSerialPack2($uid));
        }else{
            $aid  = oo::commonOprRedis('activity')->get(okeys::bindSuperSerialPack($uid));
        }
        $ret = oo::commonOprModel('payment')->buySuperSerialPack($uid,$aid,$gid);
        return $ret;
    }
    /**
     * 支付加倍转盘 免费
     * @param $param
     * @return string
     * Created by: Hss
     * Created on: 2020/7/21 17:46
     */
    public function payBet($param){
        $uid = oo::functions()->uint($param['uid']);
        if(empty($uid)){
            return oo::response(-1,[],'参数错误');
        }

        return oo::commonOprModel('payment')->payBet($uid,'免费');
    }

    /**
     * 通行證升級
     * @param $param
     * @return string
     * Created by: Owen
     * Created on: 2020/10/23 15:48
     */
    public function trafficPermitLevel($param){
        $uid = oo::functions()->uint($param['uid']);
        $num = oo::functions()->uint($param['num']);
        if(empty($uid) || empty($num)){
            return oo::response(-1,[],'参数错误');
        }
        if(!funs::concurrentLock($uid,'trafficPermitLevel')){
            return oo::response(errorCode::API_FREQUENT_REQUESTS,[],'频繁操作');
        }
        return oo::commonOprModel('activitynew')->buyTrafficPermitLevel($uid,$num);
    }

    /**
     * 矿工小游戏复活
     * @param $param
     * @return string
     * Created by: Owen
     * Created on: 2020/11/5 9:57
     */
    public function miningGameResurrection($param){
        $uid = oo::functions()->uint($param['uid']);
        $levelId = oo::functions()->uint($param['levelId']);
        if(empty($uid) || empty($levelId)){
            return oo::response(-1,[],'参数错误');
        }
        if(!funs::concurrentLock($uid,'miningGameResurrection')){
            return oo::response(errorCode::API_FREQUENT_REQUESTS,[],'频繁操作');
        }
        return oo::commonOprModel('mining')->gameResurrection($uid,$levelId);
    }

    /**
     * 矿工小游戏过关金币
     * @param $param
     * @return string
     * Created by: Owen
     * Created on: 2020/11/5 10:00
     */
    public function miningGameUpLevel($param){
        $uid  = oo::functions()->uint($param['uid']);
        $levelId = oo::functions()->uint($param['levelId']);
        $free = oo::functions()->uint($param['isFree']);
        if(empty($uid) || empty($levelId)){
            return oo::response(-1,[],'参数错误');
        }
        if(!funs::concurrentLock($uid,'miningGameUpLevel')){
            return oo::response(errorCode::API_FREQUENT_REQUESTS,[],'频繁操作');
        }
        return oo::commonOprModel('mining')->gameUpLevel($uid,$levelId,$free);
    }

    /**
     * 钻石夺宝
     * @param $param
     * @return string
     * Created by: Owen
     * Created on: 2020/11/23 18:28
     */
    public function luckyDrawByDiamond($param){
        $uid = oo::functions()->uint($param['uid']);
        $num = oo::functions()->uint($param['num']);
        if(empty($uid) || empty($num)){
            return oo::response(-1,[],'参数错误');
        }
        if(!funs::concurrentLock($uid,'luckyDrawByDiamond')){
            return oo::response(errorCode::API_FREQUENT_REQUESTS,[],'频繁操作');
        }
        return oo::commonOprModel('luckydraw')->luckyDrawByDiamond($uid,$num);
    }

    /**
     * 订阅同步
     * @param $param
     * @return false|string
     * Created by: Owen
     * Created on: 2020/12/3 18:19
     */
    public function syncSubscribe($param){
        $uid       = oo::functions()->uint($param['uid']);
        if(!funs::concurrentLock($uid,'syncSubscribe',6)){
            return json_encode(['code'=>-500,'msg'=>'order be locked']);
        }
        $transactionId = $param['transactionId'];
        $receipt       = $param['receipt'];
        if(empty($uid) || empty($receipt) || empty($receipt)){
            return oo::response(-1,[],'参数错误');
        }
        $sid = $param['sid']??1;
        if($sid == 1){
            return oo::commonOprModel('payment')->syncAndroidSubscribe($uid,$transactionId,$receipt);
        }else{
            return oo::commonOprModel('payment')->syncIosSubscribe($uid,$transactionId,$receipt);
        }
    }
}
