| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548 | <?php/** * Notify.php UTF-8 * 通知CP * * @date    : 2018/4/28 1:58 * * @license 这不是一个自由软件,未经授权不许任何使用和传播。 * @author  : wuyonghong <wyh@huosdk.com> * @version : HUOSDK 8.0 */namespace huo\controller\pay;use huo\controller\agent\AgentCache;use huo\controller\common\Base;use huo\controller\conf\PaywayConf;use huo\controller\finance\Income;use huo\controller\game\Game;use huo\controller\integral\MemIa;use huo\controller\member\MemCache;use huo\controller\member\MemWallet;use huo\controller\request\Request;use huo\controller\wallet\WalletRequest;use huo\model\game\GameextModel;use huo\model\log\OrderCpLogModel;use huo\model\member\MemGameModel;use huo\model\member\MemoauthModel;use huolib\constant\AgentConst;use huolib\constant\CommonConst;use huolib\constant\IaConst;use huolib\constant\OrderConst;use huolib\constant\WalletConst;use huolib\pay\Pay;use huolib\status\CommonStatus;use huolib\status\IntegralStatus;use huolib\status\OrderStatus;use huolib\status\SettleStatus;use huolib\tool\StrUtils;use huolib\tool\Time;use huomp\controller\game\GameMini;use huomp\model\weixin\OaMchModel;use huoMpAd\MpReportData;use think\Config;use think\Exception;use think\Log;class Notify extends Base {    protected function retSucMsg($code, $data = []) {        $_msg = OrderStatus::getMsg($code);        return $this->huoSuccess($code, $_msg, $data);    }    protected function retErrMsg($code) {        $_err_msg = OrderStatus::getMsg($code);        return $this->huoError($code, $_err_msg);    }    /**     * CP通知     *     * @param string $order_id     *     * @return array|mixed     */    public function notify($order_id = '') {        if (empty($order_id)) {            return $this->retErrMsg(OrderStatus::ORDER_ID_EMPTY);        }        $_order_data = SdkOrderCache::ins()->getInfoByOrderId($order_id);        if (false == $_order_data) {            return $this->retErrMsg(OrderStatus::ORDER_NOT_EXISTS);        }        if (OrderConst::PAY_STATUS_SUC != $_order_data['status']) {            Log::write(                "func=".__FUNCTION__."&class=".__CLASS__."&code=".OrderStatus::ORDER_NOT_PAY.'&order_data.'                .json_encode($_order_data),                LOG::LOG            );            return $this->retErrMsg(OrderStatus::ORDER_NOT_PAY);        }        if (OrderConst::CP_STATUS_SUC == $_order_data['cp_status']) {            return $this->retSucMsg(OrderStatus::NO_ERROR);        }        $_param = $this->setCpParam($_order_data);        $_cp_url = (new Game())->getCpPaybackUrl($_order_data['app_id']);        if (empty($_cp_url)) {            Log::write(                "func=".__FUNCTION__."&class=".__CLASS__."&code=".OrderStatus::NOTIFY_URL_EMPTY.'&order_data.'                .json_encode($_order_data),                LOG::ERROR            );            return $this->retErrMsg(OrderStatus::NOTIFY_URL_EMPTY);        }        $_nc_data = $this->notifyCp($_cp_url, $_param);        if (empty($_nc_data)) {            return $this->retErrMsg(OrderStatus::UNKNOWN_ERROR);        }        /* 更新订单信息 */        $_order_data['cp_status'] = $_nc_data[1];        $_order_data['notify_cnt'] += $_nc_data[0];        $_order_data['last_notify_time'] = time();        if (OrderConst::CP_STATUS_SUC == $_nc_data[1]) {            $_order_data['finish_time'] = time();            $_rs = SdkOrderCache::ins()->updateOrder($_order_data['order_id'], $_order_data);            if (true == $_rs) {                $this->updateAfterNotify($_order_data);                $_code = OrderStatus::NO_ERROR;            } else {                $_code = OrderStatus::INNER_ERROR;            }        } else {            // 兼容前端接口查单和支付通知同时修改cp通知状态导致重复问题            $_order_data = SdkOrderCache::ins()->getInfoByOrderId($order_id);            if (OrderConst::CP_STATUS_SUC == $_order_data['cp_status']) {                $_code = OrderStatus::NO_ERROR;                return $this->retSucMsg($_code);            }            $_order_data['is_handle'] = OrderConst::ORDER_IS_HANDLE;            SdkOrderCache::ins()->updateOrder($_order_data['order_id'], $_order_data);            $_code = OrderStatus::NOTIFY_FAIL;            $_class_name = '\\huoOrderRepeat\\controller\\OrderRepeat';            if (Config::get('ORDER_REPEAT_QUEUE') && class_exists($_class_name)) {                (new $_class_name())->cpNotifyQueue($_order_data['order_id']);            }        }        /* 插入通知Log */        $_data['pay_id'] = get_val($_order_data, 'id', 0);        $_data['order_id'] = get_val($_order_data, 'order_id', '');        $_data['cp_order_id'] = get_val($_order_data, 'cp_order_id', 0);        $_data['status'] = get_val($_order_data, 'status', '');        $_data['cp_status'] = get_val($_order_data, 'cp_status', 0);        $_data['cp_payback_url'] = $_cp_url;        $_data['params'] = $_param;        $_data['ext'] = get_val($_order_data, 'ext', '');        $_data['notify_cnt'] = get_val($_order_data, 'notify_cnt', '');        $_oc_model = new OrderCpLogModel();        $_oc_model->insertLog($_data);        return $this->retSucMsg($_code);    }    /**     * @param $_order_data     */    public function updateAfterNotify($_order_data) {        // TODO: wuyonghong 2018/4/28 通知后更新        }    /**     * @param $cp_url     * @param $param     *     * @return array     */    public function notifyCp($cp_url, $param) {        $_i = 0;        $_cp_status = 1;        while (1) {            $_i++;            $_cp_rs = Request::cpPayback($cp_url, $param);            if ($_cp_rs > 0) {                $_cp_status = 2;                break;            } else {                $_cp_status = 3;                sleep(1);            }            if ($_i == 3) {                break;            }        }        return [$_i, $_cp_status];    }    /**     * 设置通知CP参数     *     * @param array $order_data     *     * @return bool|string     */    public function setCpParam($order_data = []) {        $_cp_rq_data['app_id'] = get_val($order_data, 'app_id');        $_cp_rq_data['cp_order_id'] = get_val($order_data, 'cp_order_id');        $_cp_rq_data['mem_id'] = get_val($order_data, 'mg_mem_id', 0);/* 使用游戏玩家ID  */        $_cp_rq_data['order_id'] = get_val($order_data, 'order_id');        $_cp_rq_data['order_status'] = get_val($order_data, 'status');        $_cp_rq_data['pay_time'] = get_val($order_data, 'create_time');        $_cp_rq_data['product_id'] = get_val($order_data, 'product_id');        $_cp_rq_data['product_name'] = get_val($order_data, 'product_name');        $_cp_rq_data['product_price'] = get_val($order_data, 'amount');        $_cp_rq_data['ext'] = get_val($order_data, 'ext');        $_param = StrUtils::argSort($_cp_rq_data);        $_signstr = StrUtils::createLinkString($_param);        /* 获取游戏信息 */        $_app_key = (new Game())->getAppKey($_cp_rq_data['app_id']);        if (empty($_app_key)) {            return false;        }        $_sign = md5($_signstr."&app_key=".$_app_key);        $_cp_rq_data['sign'] = $_sign;        return $_signstr."&sign=".$_sign;    }    /**     * 支付回调处理     *     * @param $product_id     * @param $order_id     * @param $trade_no     * @param $amount     * @param $payway     */    public function payNotify($product_id, $order_id, $trade_no, $amount, $payway) {        $_notify_data['product_id'] = $product_id;        $_notify_data['order_id'] = $order_id;        $_notify_data['trade_no'] = $trade_no;        $_notify_data['amount'] = $amount;        $_notify_data['payway'] = $payway;        $_soc_class = SdkOrderCache::ins();        if (empty($order_id)) {            Log::write(                "func=".__FUNCTION__."&class=".__CLASS__."&step1&code=".OrderStatus::ORDER_ID_EMPTY.'¬ify_data.'                .http_build_query($_notify_data),                LOG::ERROR            );            return false;        }        if (empty($amount)) {            Log::write(                "func=".__FUNCTION__."&class=".__CLASS__."&step2&code=".OrderStatus::ORDER_AMOUNT_IS_ZERO                .'¬ify_data.'                .http_build_query($_notify_data),                LOG::ERROR            );            return false;        }        $_order_data = $_soc_class->getInfoByOrderId($order_id);        if (false == $_order_data) {            Log::write(                "func=".__FUNCTION__."&class=".__CLASS__."&step3&code=".OrderStatus::ORDER_NOT_EXISTS.'¬ify_data.'                .http_build_query($_notify_data),                LOG::ERROR            );            return false;        }        $_amount = number_format($amount, 2, '.', '');        $_order_amount = number_format($_order_data['real_amount'], 2, '.', '');        if (($_amount < $_order_amount)) {            Log::write(                "func=".__FUNCTION__."&class=".__CLASS__."&step4&code=".OrderStatus::NOTIFY_AMOUNT_ERROR.'¬ify_data.'                .http_build_query($_notify_data).'&order_data='.http_build_query($_order_data),                LOG::ERROR            );            return false;        }        if (OrderConst::PAY_STATUS_SUC == $_order_data['status']) {            Log::write(                "func=".__FUNCTION__."&class=".__CLASS__."&step5&code=".OrderStatus::ORDER_HAS_PAY.'¬ify_data.'                .http_build_query($_notify_data).'&order_data='.http_build_query($_order_data),                LOG::LOG            );            return false;        }        /* 更新订单支付状态 */        $_order_data['status'] = OrderConst::PAY_STATUS_SUC;        $_order_data['payway'] = $payway;        $_order_data['remark'] = $trade_no;        $_order_data['pay_time'] = time();        $_rs = $_soc_class->updateOrder($_order_data['order_id'], $_order_data);        if (false == $_rs) {            return false;        }        /* Modified by wuyonghong BEGIN 2018/3/26 ISSUES:5314 LTV  */        /* 充值时计算LTV */        $_ltv_class = new \ltv\Ltv();        $_mem_data = (new \huo\model\member\MemberModel())->getInfoById(            $_order_data['mem_id']        );        $_ltv_class->charge(            $_mem_data['app_id'],            $_mem_data['agent_id'],            $_order_data['app_id'],            $_order_data['amount'],            $_order_data['update_time'],            $_mem_data['create_time']        );        /* END 2018/3/26 ISSUES:5314 */        /* 通知CP */        $this->doAfterPayNotify($order_id);        // 买量数据回传        try {            (new MpReportData())->payReport($order_id);        } catch (\Exception $exception) {            \think\Log::write(['pppppp', $exception->getTraceAsString(), 'error', true]);        }        return true;    }    /**     * 支付成功后 需要做的操作     *     * @param $order_id     *     * @return array     */    public function doAfterPayNotify($order_id) {        /* 更新游戏信息 */        $this->upGameAfterPay($order_id);        /* 更新玩家信息 */        $_rs = $this->upMemAfterPay($order_id);        if (CommonStatus::NO_ERROR != $_rs['code']) {            return $this->huoReturn($_rs);        }        /* 计算渠道收益 */        $this->upAgentAfterPay($order_id);        /* 异步处理数据 */        (new \huo\controller\queue\Order())->fromSdkOrder($order_id);        /* 通知CP */        $_rdata = $this->notify($order_id);        return $this->huoReturn($_rdata);    }    /**     * 更新渠道数据     *     * @param $order_id     */    public function upAgentAfterPay($order_id) {        /* 计算渠道收益 */        (new Income())->incomeFromSdkOrder($order_id);    }    /**     * 更新玩家数据     *     * @param $order_id     */    public function upMemAfterPay($order_id) {        $_soc_class = SdkOrderCache::ins();        $_order_data = $_soc_class->getInfoByOrderId($order_id);        /* 扣除平台币 平台币扣除不成功返回 */        if (StrUtils::compareNumber($_order_data['ptb_amount'], CommonConst::CONST_ZERO_COMPARE) > 0) {            $_wr_class = new WalletRequest();            $_wr_class->setDataFromSdkOrder($_order_data);            $_order_data['status'] = OrderConst::PAY_STATUS_SUC;            $_wr_class->setStatus($_order_data['status']);            $_rs = (new MemWallet())->createPoOrder($_wr_class);            if (SettleStatus::NO_ERROR != $_rs) {                /* 记录所有Log */                return $this->huoError($_rs, SettleStatus::getMsg($_rs));            } else {                $_order_data['pay_time'] = time();                $_soc_class->updateOrder($order_id, $_order_data);            }        }        /* 扣除游戏币 游戏币扣除不成功返回 */        if (StrUtils::compareNumber($_order_data['gm_amount'], CommonConst::CONST_ZERO_COMPARE) > 0) {            $_wr_class = new WalletRequest();            $_wr_class->setDataFromSdkOrder($_order_data);            $_order_data['status'] = OrderConst::PAY_STATUS_SUC;            $_wr_class->setStatus($_order_data['status']);            $_rs = (new MemWallet())->createGmoOrder($_wr_class);            if (SettleStatus::NO_ERROR != $_rs) {                /* 记录所有Log */                return $this->huoError($_rs, SettleStatus::getMsg($_rs));            } else {                $_order_data['pay_time'] = time();                $_soc_class->updateOrder($order_id, $_order_data);            }        }        /* 充值成功获取积分 */        $_mem_id = $_order_data['mem_id'];        if (!empty($_mem_id)) {            $_rs = (new MemIa($_mem_id))->doItgAct(IaConst::IA_DAY_FIRST_CHARGE, $order_id);            if (CommonStatus::NO_ERROR != $_rs['code']) {                if (IntegralStatus::ITG_IA_ERROR != $_rs['code']) {                    Log::write(                        "func=".__FUNCTION__."&class=".__CLASS__."&returndata=".json_encode($_rs).'&order_data='                        .http_build_query($_order_data),                        LOG::LOG                    );                } else {                    Log::write(                        "func=".__FUNCTION__."&class=".__CLASS__."&returndata=".json_encode($_rs).'&order_data='                        .http_build_query($_order_data),                        LOG::ERROR                    );                }            }        }        /* 更新玩家信息 */        $_mc_class = MemCache::ins();        $_me_data = $_mc_class->getMeInfoById($_mem_id);        $_me_data['last_money'] = $_order_data['amount'];        $_me_data['sum_money'] += $_order_data['amount'];        // 玩家游戏充值        $_mem_game_model = new MemGameModel();        $_mem_game_model->where(['id' => $_order_data['mg_mem_id']])                        ->setInc('sum_money', $_order_data['amount']);        list($_today_start, $_today_end) = Time::today();        if ($_today_start > $_me_data['last_pay_time']) {            /* 非本日充值 */            $_me_data['day_money'] = $_order_data['amount'];        } else {            $_me_data['day_money'] += $_order_data['amount'];        }        list($_week_start, $_week_end) = Time::week();        if ($_week_start > $_me_data['last_pay_time']) {            /* 非本周充值 */            $_me_data['week_money'] = $_order_data['amount'];        } else {            $_me_data['week_money'] += $_order_data['amount'];        }        list($_month_start, $_month_end) = Time::month();        if ($_month_start > $_me_data['last_pay_time']) {            /* 非本月充值 */            $_me_data['month_money'] = $_order_data['amount'];        } else {            $_me_data['month_money'] += $_order_data['amount'];        }        $_me_data['order_suc_cnt'] += 1;        $_me_data['last_pay_time'] = $_order_data['pay_time'];        $_mc_class->updateMeCache($_mem_id, $_me_data);        /* Modified by chenbingling BEGIN 2019/12/2 ISSUES:10837 实名认证统计 */        (new \huoIdentify\controller\Pay())->updateMoney($_order_data['mem_id'], $_order_data['amount']);        /* END 2019/12/2 ISSUES:10837 */        $_code = CommonStatus::NO_ERROR;        return $this->huoError($_code, SettleStatus::getMsg($_code));    }    /**     * @param string $payway     *     * @param string $product_id     *     * @param int    $app_id   应用ID     * @param string $order_id 订单id     *     * @return bool     */    public function notifyUrl($payway, $product_id = '', $app_id = 0, $order_id = '') {        try {            $_pay_class = Pay::ins()->get($payway);        } catch (Exception $e) {            Log::write(                "func=".__FUNCTION__."&class=".__CLASS__."&payway=".$payway.'&data='.json_encode($_REQUEST),                LOG::ERROR            );            exit('fail');        }        $_config = [];        switch ($product_id) {            case WalletConst::WALLET_PRODUCT_MEM_PTB:            case WalletConst::WALLET_PRODUCT_MEM_GM:            case WalletConst::WALLET_PRODUCT_AGENT_PTB:            case WalletConst::WALLET_PRODUCT_ACCOUNT:                {                    $_order_class = '\\huo\\controller\\wallet\\Notify';                    $_func = 'payNotify';                }                break;            case WalletConst::WALLET_PRODUCT_MP:                $_order_class = '\\huo\\controller\\pay\\Notify';                $_func = 'payNotify';                $_pay_class->setOrderClass($_order_class);                $_pay_class->setFunc($_func);                $_config = (new GameMini())->getPayConfByMpAppId($app_id);                return $_pay_class->notifyUrl($_config);            case WalletConst::WALLET_PRODUCT_WXKF:                $_order_class = '\\huo\\controller\\pay\\Notify';                $_func = 'payNotify';                $_pay_class->setOrderClass($_order_class);                $_pay_class->setFunc($_func);                $_config = $_config = (new OaMchModel())->getPayConfByOaId($app_id);;                return $_pay_class->notifyUrl($_config);            default:            {                $_order_class = '\\huo\\controller\\pay\\Notify';                $_func = 'payNotify';                $_order_info = SdkOrderCache::ins()->getInfoByOrderId($order_id);                $_app_id = get_val($_order_info, 'app_id', CommonConst::CONST_ZERO);                $_config = (new PaywayConf())->getConfByAppPayway($_app_id, $payway);            }        }        $_pay_class->setOrderClass($_order_class);        $_pay_class->setFunc($_func);        return $_pay_class->notifyUrl($_config);    }    /**     *  更新游戏信息     *     * @param $order_id     *     * @return  :     * @author  : chengshibin <csb@huosdk.com>     * @date    : 2019/2/18 18:33     * @since   : HUOSDK 8.0     * @modified: 2019/2/18 18:33     */    public function upGameAfterPay($order_id) {        $_order_data = SdkOrderCache::ins()->getInfoByOrderId($order_id);        $_app_id = $_order_data['app_id'];        /* 充值成功获取积分 */        $_mem_id = $_order_data['mem_id'];        /* 更新玩家信息 */        $_mc_class = MemCache::ins();        $_mem_data = $_mc_class->getInfoById($_mem_id);        $_me_data = $_mc_class->getMeInfoById($_mem_id);        /* 更新游戏扩展信息 */        $_game_ext_class = new GameextModel();        $_game_ext_data = $_game_ext_class->getDetail($_app_id);        $_game_ext_data['sum_money'] += $_order_data['amount'];        $_game_ext_data['sum_real_money'] += $_order_data['real_amount'];        /*首充总额*/        if (0 == $_me_data['last_pay_time']) {            $_game_ext_data['first_pay_money'] += $_order_data['amount'];            /*首付当日总额*/            if (date('Y-m-d') == date('Y-m-d', $_mem_data['create_time'])) {                $_game_ext_data['first_pay_sum_money'] += $_order_data['amount'];                $_game_ext_data['reg_sum_money'] += $_order_data['amount'];            }        }        $_game_ext_class->updateData($_game_ext_data, $_app_id);        $_code = CommonStatus::NO_ERROR;        return $this->huoError($_code, SettleStatus::getMsg($_code));    }}
 |