<?php

/**
 * Class Alipay
 */
class Alipay extends MY_Controller
{
    const PRIVATE_KEY = 'MIIEowIBAAKCAQEAxdbFM6LBjcNzHpO9fs04qVJwS7lIo8HHO4xNXjcOp2EyDdITGfnCEX2C3a/wGYOYBWSLKdFsILdOy+MqmycxzToLaKAaJHmBUWjNrLaIaGXm9HDxlKOfZdpMpH7OYrqY8DLHFIN9zc8AWOxyLc+R57fiHn0IfHILt9WWkIoPEizBAbw9QvS8R3uL+kiL4eHytzFOSnKN7szwZqmvk4K0c4CntUJwkmcDRgVr4cH8qTd1p7XMOxjjDYK/jrdMFzbWC++sjrGauSnq/ZQPKU+P/29/W0ZpeDuks4dgVCewoca8TcslqXvwAUWcAvy02CIKVZp1exu2nzjBR75fLc2oKwIDAQABAoIBABN6FWgD+fIu78Ju4RT+tzlUOGH8F76ncSnXojZITVUFKJxbti20fPqj1KJmk8ivP+QoBdtUFsURxtwjvSoRLcH6mOzv9iLpI2YUX0tFnSBKB/bAt8feY+7vEuSO51qo7C2Zkife2h/M5Ufb31HLQZ4CaGx/+rnlsGmkyXHpZZpwSSmZlRcWr/vXD/PTmNkyKZ91Yuz9hjOEbjs2TdQJGlzlf1gl9J7IdaVnlLL7fMqv+Qk6qa7J0uaM4VfxOvwMkIsbHTkGzWQhcxgL0ejSo9j4fOAoUzdqmcwujoz+xNNXNqOlhNwUuw93+WUOu690xjHbDyG+6EFZOtC9+SGJVCECgYEA6OItjOgMPbBYF7S0wNrLoQL7C2J+nnJZjLhFOXAveisHLYxpF1gq5/5w3GNZS38yfbTqQ1ENG1bPz/iDTo0uUINvA6dND3PLixPEgyLDdvBHVpvhFXWufUmXBGYlpte32J7dHmHctBo5/8cERJg9IhCBi6T5ztISgcJkzEDRPOcCgYEA2XoSeHZfuQ3kS6+dIVWwKA63W2lxWU4AuyUWLQnQrChrqOnytjPX8Xb8brKeBxlTEKjZEYGiVFD5aFUwOVKApFYL1fjZk5D1+VO2teZOpnxWHKj4UaO6p9vhA7RX/LD6+NZIoczgLj7Zva5lSM1yGBibz3VlmG+cKduoOFJN7h0CgYEAyEURVPaM6FQJPcGqG5tMuBdfGqhGKS4/MlOZPE7slUwBbTsteOTaaQ2Xsv9A4DrvickWGHPQKK2cIsYc7WVd6eFNi7/I9jvnU5/ZQ8iWfWcegi2lABZmytmJJEBPqs4iDQh5MVKJQNy4+ewFEJQ3Jl85eISUSza+sZYhpsEq7wsCgYBFSa840f4NZ2+k7X6ScEp/eLDSXvXODhwNg/NcxhPFxdsHJgI+KqZSOCaU3jOa72aXmDQQb8zYMDRGGV4T5UU3FnMO6QnpCfZUSWec7JOCV3rYBr2WxSNi95rpIzwlNf2/6gWaBzwlf8C/viBm4Y3IP47kufJ0bprCe0lNKGvLwQKBgB7zM5feb3oBFOcy8FSKnSLOYMgbWPcuDdwCH7FKCDH8eRk3q/xacnX/e9fzpx/e3Bq5ZCamypFenkxcc3zkr02FTLqFTnVyEydxY1xYoutumNQnheHCFgByLcjTuq75JKxrolRKXFmDNFQy4WsAICouooBZblYbnjXCcW3nKsT7';
//    const ALIPAY_PUBLIC_KEY = 'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAs7VXfgYyTCDcSmJd9d4z8z5GZXi5mxu3gfQH4aPlSIrlw9ojyNnY/nm0MXiRcL/2K08sR5dpYtuIy4D4Pzy8HlSEx+2oNt9ieCDreASwU9O9rHh/uIrFWcWk5Dfp6LRVstT44BQwIKGJP+8s5Qozsp0LNk90RF+4dG2w/2MHkzYqT5ZnlhEjTg8b2VrBdRO6U2AdatwSx/5KcTxgxOrEpySInaNu9Nspoep2hx9X1ot4/wMlTl0U+eKE+aCnKl0qa9tCAa5N2RPCY0gypfOEMotmnETjTxPR2bnIT916qgeVKaBvNpeWvUUj/sNninLjDuXYoIAOPIkoI7+yTLKVOQIDAQAB';
    const TEST = false;
    const ALIPAY_APP_ID = '2018042060019228';
    const ALIPAY_APP_ID_TEST = '2016080400168035';
    const ALIPAY_AUTH_URL = 'https://openauth.alipay.com/oauth2/publicAppAuthorize.htm';
    const ALIPAY_AUTH_URL_TEST = 'https://openauth.alipaydev.com/oauth2/publicAppAuthorize.htm';
    const ALIPAY_INTERFACE_URL = 'https://openapi.alipay.com/gateway.do';
    const ALIPAY_INTERFACE_URL_TEST = 'https://openapi.alipaydev.com/gateway.do';

    /**
     * @var string
     */
    private $alipayAppID = self::ALIPAY_APP_ID;

    /**
     * @var string
     */
    private $alipayAuthURL = self::ALIPAY_AUTH_URL;

    /**
     * @var string
     */
    private $alipayInterfaceURL = self::ALIPAY_INTERFACE_URL;

    /**
     * @var int|string
     */
    private $user_id = 0;

    /**
     * Alipay constructor.
     */
    public function __construct()
    {
        parent::__construct();
        $this->user_id = checklogin();
        if ($this->user_id <= 0) {
            jumpto(USER_CENTER . 'login');
            exit();
        }
        if (self::TEST == true) {
            $this->alipayAppID = self::ALIPAY_APP_ID_TEST;
            $this->alipayAuthURL = self::ALIPAY_AUTH_URL_TEST;
            $this->alipayInterfaceURL = self::ALIPAY_INTERFACE_URL_TEST;
        }
    }

    /**
     * Redirect
     * @param string $url
     */
    private function redirect($url = '')
    {
        header(sprintf('Location: %s', $url));
        exit;
    }

    /**
     * Input
     * @param string $key
     * @param string $default
     * @return string
     */
    private function input($key = '', $default = '')
    {
        return isset($_REQUEST[$key]) ? $_REQUEST[$key] : $default;
    }

    /**
     * CURL Get
     * @param $url
     * @return mixed
     */
    private function curlGet($url)
    {
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 5);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
        $return = curl_exec($curl);
        curl_close($curl);
        return $return;
    }

    /**
     * Database User
     * @param string $sql
     * @return array|resource
     */
    private function databaseUser($sql = '')
    {
        $mysqlUser = mysql_connect('njesfdbmastervip.house365.com', 'root', 'idontcare');
        mysql_select_db('user', $mysqlUser);
        $result = mysql_query($sql, $mysqlUser);
        $result = mysql_fetch_array($result);
        mysql_close($mysqlUser);
        return $result;
    }

    /**
     * Database House
     * @param string $sql
     * @return array|resource
     */
    private function databaseHouse($sql = '')
    {
        $mysqlUser = mysql_connect('njesfdbmastervip.house365.com', 'root', 'idontcare');
        mysql_select_db('house', $mysqlUser);
        $result = mysql_query($sql, $mysqlUser);
        $result = mysql_fetch_array($result);
        mysql_close($mysqlUser);
        return $result;
    }

    /**
     * Get Insert SQL
     * @param string $table
     * @param array $data
     * @return string
     */
    private function getInsertSQL($table = '', $data = array())
    {
        $insertKey = array();
        $insertValue = array();
        foreach ($data as $key => $value) {
            $value = strip_tags($value);
            array_push($insertKey, sprintf('`%s`', $key));
            array_push($insertValue, sprintf('"%s"', $value));
        }
        $insertKey = implode(',', $insertKey);
        $insertValue = implode(',', $insertValue);
        $sql = sprintf('INSERT INTO `%s` (%s) VALUES (%s)', $table, $insertKey, $insertValue);
        return $sql;
    }

    /**
     * Get URL
     * @param string $baseURL
     * @param array $parameter
     * @return string
     */
    private function getURL($baseURL = '', $parameter = array())
    {
        if (empty($parameter)) {
            return $baseURL;
        }
        if (!is_array($parameter)) {
            return $baseURL;
        }
        $array = array();
        foreach ($parameter as $key => $value) {
            array_push($array, sprintf('%s=%s', $key, urlencode($value)));
        }
        return sprintf('%s?%s', $baseURL, implode('&', $array));
    }

    /**
     * SHA256 With RSA
     * @param string $data
     * @return string
     */
    private function sha256WithRSA($data = '')
    {
        $privateKey = chunk_split(self::PRIVATE_KEY, 64);
        $privateKey = trim($privateKey);
        $privateKey = sprintf('-----BEGIN RSA PRIVATE KEY-----%s%s%s-----END RSA PRIVATE KEY-----', PHP_EOL, $privateKey, PHP_EOL);
        $privateKeyID = openssl_pkey_get_private($privateKey);
        openssl_sign($data, $sign, $privateKeyID, 'sha256WithRSAEncryption');
        openssl_free_key($privateKeyID);
        $sign = base64_encode($sign);
        return $sign;
    }

    /**
     * Get Sign
     * @param array $data
     * @return string
     */
    private function getSign($data = array())
    {
        if (!is_array($data)) {
            return '';
        }
        if (isset($data['sign'])) {
            unset($data['sign']);
        }
        foreach ($data as $key => $value) {
            if (is_string($value) && trim($value) == '') {
                unset($data[$key]);
            }
        }
        ksort($data);
        $array = array();
        foreach ($data as $key => $value) {
            array_push($array, sprintf('%s=%s', $key, $value));
        }
        $string = implode('&', $array);
        return $this->sha256WithRSA($string);
    }

    /**
     * Get Transaction ID
     * @return string
     */
    private function getTransactionID()
    {
        $string = '';
        for ($index = 0; $index < 8; $index++) {
            $string .= rand(10000000, 99999999);
        }
        return $string;
    }

    /**
     * Get Authorize Scope
     * @return string
     */
    private function getAuthorizeScope()
    {
        $scopeList = array(
            'auth_base' => true, // 用户信息授权
            'auth_user' => true, // 获取用户信息、网站支付宝登录
            'auth_userinfo' => false, // 获取用户信息、网站支付宝登录
            'auth_zhima' => true, // 获取芝麻信息
            'auth_ecard' => false, // 商户会员卡
            'auth_invoice_info' => false, // 支付宝闪电开票
            'auth_puc_charge' => false // 生活缴费
        );
        $array = array();
        foreach ($scopeList as $key => $value) {
            if ($value == true) {
                array_push($array, $key);
            }
        }
        return implode(',', $array);
    }

//    /**
//     * Check Sign
//     * @param array $data
//     * @return bool
//     */
//    private function checkSign($data = array())
//    {
//        $resultType = array(
//            'error_response',
//            'alipay_system_oauth_token_response',
//            'zhima_credit_score_brief_get_response'
//        );
//        $signData = isset($data[0]) ? $data[0] : '';
//        foreach ($resultType as $value) {
//            if (isset($data[$value])) {
//                $signData = $data[$value];
//            }
//        }
//        foreach ($signData as $key => $value) {
//            $signData[$key] = urlencode($value);
//        }
//        $signData = urldecode(json_encode($signData));
//        $publicKey = chunk_split(self::ALIPAY_PUBLIC_KEY, 64);
//        $publicKey = trim($publicKey);
//        $publicKey = sprintf('-----BEGIN PUBLIC KEY-----%s%s%s-----END PUBLIC KEY-----', PHP_EOL, $publicKey, PHP_EOL);
//        $publicKey = openssl_pkey_get_public($publicKey);
//        $sign = isset($data['sign']) ? $data['sign'] : '';
//        $sign = base64_decode($sign);
//        $verify = openssl_verify($signData, $sign, $publicKey, 'sha256WithRSAEncryption');
//        openssl_free_key($publicKey);
//        if ($verify == 1) {
//            return true;
//        }
//        return false;
//    }

    /**
     * Submit Interface
     * @param array $data
     * @return array
     */
    private function submitInterface($data = array())
    {
        $data['app_id'] = $this->alipayAppID;
        $data['format'] = 'JSON';
        $data['charset'] = 'UTF-8';
        $data['sign_type'] = 'RSA2';
        $data['timestamp'] = date('Y-m-d H:i:s');
        $data['version'] = '1.0';
        $data['sign'] = $this->getSign($data);
        $url = $this->getURL($this->alipayInterfaceURL, $data);
        $result = $this->curlGet($url);
        if (empty($result)) {
            $this->redirect('/');
        }
        $result = json_decode($result, true);
//        if (!$this->checkSign($result)) {
//            $this->redirect('/');
//        }
        return $result;
    }

    /**
     * Fail
     */
    public function fail()
    {
        $data = array(
            'title' => '认证失败',
            'message' => '请检查姓名和身份证号是否有误'
        );
        $alipayOpenID = $this->input('open_id', '');
        if (!empty($alipayOpenID)) {
            $sqlUser = sprintf('select telno from personal_user where auth_type="1" and auth_open_id="%s" limit 1', $alipayOpenID);
            $resultUser = $this->databaseUser($sqlUser);
            $mobile = isset($resultUser['telno']) ? $resultUser['telno'] : '';
            if (empty($mobile)) {
                $data['message'] = sprintf('该支付宝账号已被其他账户绑定。');
            } else {
                $mobile = substr($mobile, 0, 3) . '****' . substr($mobile, 7);
                $data['message'] = sprintf('该支付宝账号已被%s绑定。', $mobile);
            }
        }
        $this->load->view('alipay_fail', $data);
    }

    /**
     * Save Information
     */
    public function saveInforamtion()
    {
        $alipayName = $this->input('truename');
        $alipayIdNumber = $this->input('idno');
        // Is Other
        $sqlUser = sprintf('select telno,id from personal_user where auth_type="1" and idno="%s" limit 1', $alipayIdNumber);
        $resultUser = $this->databaseUser($sqlUser);
        if (isset($resultUser['id'])) {
            $phone = isset($resultUser['telno']) ? $resultUser['telno'] : '';
            if (empty($phone)) {
                echo json_encode(array(
                    'status' => 0,
                    'message' => mb_convert_encoding(sprintf('该身份证号已被其他账号绑定，请使用该账号登录，如不是您本人绑定，请致电025-52206365-6082'), 'UTF-8', 'GBK')
                ));
            } else {
                $phoneShow = sprintf('%s****%s', substr($phone, 0, 3), substr($phone, 7));
                echo json_encode(array(
                    'status' => 0,
                    'message' => mb_convert_encoding(sprintf('该身份证号已被账号%s绑定，请使用该账号登录，如不是您本人绑定，请致电025-52206365-6082', $phoneShow), 'UTF-8', 'GBK')
                ));
            }
            return;
        }
        // Count Today
        $userID = checkLogin();
        $startTime = strtotime(date('Y-m-d'));
        $endTime = $startTime + (60 * 60 * 24) - 1;
        $sqlLogAlipay = sprintf('select count(id) as number from log_alipay where user_id="%s" and `time` between %s and %s', $userID, $startTime, $endTime);
        $resultLogAlipay = $this->databaseHouse($sqlLogAlipay);
        $count = isset($resultLogAlipay['number']) ? intval($resultLogAlipay['number']) : 0;
        if ($count >= 3) {
            echo json_encode(array(
                'status' => 0,
                'message' => mb_convert_encoding(sprintf('今天提交次数已达上限，请明天再来认证！'), 'UTF-8', 'GBK')
            ));
            return;
        }
        // Start
        $insertData = array(
            'user_id' => $userID,
            'time' => time()
        );
        $insertSQL = $this->getInsertSQL('log_alipay', $insertData);
        $this->databaseHouse($insertSQL);
        $_SESSION['alipayName'] = $alipayName;
        $_SESSION['alipayIdNumber'] = $alipayIdNumber;
        echo json_encode(array(
            'status' => 1
        ));
    }

    /**
     * Authorization
     */
    public function authorization()
    {
        $redirectURL = $this->getURL($this->alipayAuthURL, array(
            'app_id' => $this->alipayAppID,
            'scope' => $this->getAuthorizeScope(),
            'redirect_uri' => 'http://user.house365.com/alipay/authorizationCallback'
        ));
        $this->redirect($redirectURL);
//        $this->redirect('http://user.house365.com/alipay/authorizationCallback?app_id=' . $this->alipayAppID);
    }


    /**
     * Authorization Callback
     */
    public function authorizationCallback()
    {
        $userID = checkLogin();
        if (empty($userID)) {
            $this->redirect('/user/bind_zmxy');
        }
        $inputAppID = $this->input('app_id');
        if ($inputAppID != $this->alipayAppID) {
            $this->redirect('/user/bind_zmxy');
        }
        // Get Access Token
        $authorizationCode = $this->input('auth_code');
        $interfaceAuthorizationData = array(
            'method' => 'alipay.system.oauth.token',
            'grant_type' => 'authorization_code',
            'code' => $authorizationCode
        );
        $resultAuthorization = $this->submitInterface($interfaceAuthorizationData);
        $alipayUserID = isset($resultAuthorization['alipay_system_oauth_token_response']['user_id']) ? $resultAuthorization['alipay_system_oauth_token_response']['user_id'] : '';
//        $alipayAccessToken = isset($resultAuthorization['alipay_system_oauth_token_response']['access_token']) ? $resultAuthorization['alipay_system_oauth_token_response']['access_token'] : '';
//        // Get User Information
//        $interfaceUserInformationData = array(
//            'method' => 'alipay.user.info.share',
//            'auth_token' => $alipayAccessToken
//        );
//        $resultUserInformation = $this->submitInterface($interfaceUserInformationData);
//        $isCertified = isset($resultUserInformation['alipay_user_info_share_response']['is_certified']) && $resultUserInformation['alipay_user_info_share_response']['is_certified'] == 'T' ? true : false;
        $sqlUser = sprintf('select count(id) as number from personal_user where auth_type="1" and auth_open_id="%s" limit 1', $alipayUserID);
        $resultUser = $this->databaseUser($sqlUser);
        $countUser = isset($resultUser['number']) ? intval($resultUser['number']) : 0;
        if ($countUser > 0) {
            $this->redirect('/alipay/fail?open_id=' . $alipayUserID);
        }
        // Check Zhima Authorization
        $interfaceZhimaAuthorizationData = array(
            'method' => 'zhima.credit.score.brief.get',
            'biz_content' => json_encode(array(
                'transaction_id' => $this->getTransactionID(),
                'product_code' => 'w1010100000000002733',
                'cert_type' => 'IDENTITY_CARD',
                'cert_no' => $_SESSION['alipayIdNumber'],
                'name' => $_SESSION['alipayName'],
                'admittance_score' => '350'
            ))
        );
        $resultZhimaAuthorization = $this->submitInterface($interfaceZhimaAuthorizationData);
        $isCertified = isset($resultZhimaAuthorization['zhima_credit_score_brief_get_response']['is_admittance']) && $resultZhimaAuthorization['zhima_credit_score_brief_get_response']['is_admittance'] == 'Y' ? true : false;
        if (!$isCertified) {
            $this->redirect('/alipay/fail');
        }
        $sqlUser = sprintf('update personal_user set auth_type="1",truename="%s",idno="%s",auth_open_id="%s" where id="%s"', $_SESSION['alipayName'], $_SESSION['alipayIdNumber'], $alipayUserID, $userID);
        $this->databaseUser($sqlUser);
        // Push API
        $sqlUser = sprintf('select passport_uid,telno from personal_user where id="%s" limit 1', $userID);
        $resultUser = $this->databaseUser($sqlUser);
        $userUID = isset($resultUser['passport_uid']) ? $resultUser['passport_uid'] : '';
        $userPhone = isset($resultUser['telno']) ? $resultUser['telno'] : '';
        $interfaceURL = sprintf('http://api.house365.com/passport/passport_identity.php?passport_uid=%s&passport_phone=%s&idcard=%s&realname=%s', $userUID, $userPhone, $_SESSION['alipayIdNumber'], $_SESSION['alipayName']);
        $this->curlGet($interfaceURL);
        $this->redirect('/user/bind_zmxy');
    }
}
