<?php

namespace Biz\Pay;

use App\Api\Model\AccountDetail;
use App\Commons\Model\Pay_order;
use App\Commons\Model\View_payment;
use Biz\Account\AccountManager;
use Biz\Money\AddOrCutMoney;
use Exception;
use stdClass;

/**
 * 基础支付类
 */
abstract class NewBasePayment
{

    /**
     * 网关地址
     * @var [type]
     */
    protected $getWay;

    /**
     * 支付名称或代三
     * @var [type]
     */
    protected $paymentName;

    /**
     * 支付配置文件
     * @var [type]
     */
    protected $paymentConfig;

    /**
     * 通知地址
     * @var [type]
     */
    protected $notifyUrl;

    /**
     * 跳转地址 同步
     * @var [type]
     */
    protected $redirectUrl;

    /**
     * 编码
     * @var string
     */
    protected $charset = 'utf-8';

    /**
     * 支付信息
     * @var
     */
    protected $payInfo;

    /**
     * 驱动数据对像
     * @var [type]
     */
    protected $dataAccess;

    /**
     * 私有证书路径
     * @var [type]
     */
    protected $privateCertPath;

    /**
     * 公有证书路径
     * @var [type]
     */
    protected $publicCertPath;

    /**
     * 后台配置的商户信息将在初始化时自动解析完成
     * @var [type]
     */
    protected $sellerInfo;

    /**
     * 异步通知成功的返回串
     * @var
     */
    protected $success = 'success';

    /**
     * 当前用户信息
     * @var mixed
     */
    protected $userInfo;

    /**
     * 设定支付接口允许的域名
     * @var [type]
     */
    protected $domain;

    /**
     * 返回类型
     * @var [type]
     */
    protected $returnType;

    /**
     * 是否手机版
     *
     * @var [type]
     */
    protected $isMobile;

    /**
     * 开启调试模式
     * @var integer
     */
    protected $debug = 0;

    /**
     * 提交订单信息
     * @var array
     */
    protected $orderInfo;

    /**
     * 订单发起URL
     * @var
     */
    protected $apiUrl = '';

    /**
     * 发起请求类型ENUM['POST,GET,JSON']
     * @var
     */
    protected $method = "POST";

    /**
     * 商户ID
     * @var
     */
    protected $merchant_id;

    /**
     * 商户密钥
     * @var
     */
    protected $merchant_secret;

    /**
     * 是否二次跳转
     * @var bool
     */
    public $jump = false;

    /**
     * 接收通知
     * @param array $data
     * @return void
     */

    abstract function notify(array $data);

    /**
     * 返回跳转
     * @param array $data
     * @return void [type] [description]
     */
    abstract function redirect(array $data);

    /**
     * 检查支付信息
     * @return void [type]            0=失败，1=成功
     */
    abstract function check();

    /**
     * 构建订单提交数组
     * @return array
     */
    abstract function buildOrder(): array;

    /**
     * 生成签名函数
     * @param array $param
     * @param string $merchantSecret
     * @return mixed
     */
    abstract function buildSign(array $param, $merchantSecret);

    /**
     * 基础配置
     * @return void
     */
    abstract function config();

    /**
     * 初始化
     * @param PaymentDataAccess $dataAccess
     * @throws Exception
     */
    public function __construct(PaymentDataAccess $dataAccess)
    {
        $this->userInfo = (new AccountManager())->getCurrentUser();
        $this->domain = $_SERVER['HTTP_HOST'];
        $httpSchema = $_SERVER['REQUEST_SCHEME'] ?? 'http';
        $prefix = $prefix2 = "{$httpSchema}://{$this->domain}";
        $this->paymentName = $dataAccess->paymentName;
        if ($dataAccess->paymentName) {
            if (!$this->userInfo) Render('', -4001);
            $this->getConfig();
            $dataAccess->orderSn = $this->paymentConfig['order_prefix'] . OrderID();
            if ($this->paymentConfig['notify_url']) {
                $_prefix = self::getDomain($this->paymentConfig['notify_url']);
                if ($_prefix) $prefix = $_prefix;
            }
            if ($this->paymentConfig['callback_url']) {
                $_prefix = self::getDomain($this->paymentConfig['callback_url']);
                if ($_prefix) $prefix2 = $_prefix;
            }
            $bla = explode('||', $this->paymentConfig['black_list']);
            if (in_array($this->userInfo->account, $bla)) {
                Render('', -5990);
            }
        }
        $this->notifyUrl = "{$prefix}/Payment-Pay/Notify.{$dataAccess->paymentName}";
        $this->redirectUrl = "{$prefix2}/Payment-Pay/Redirect.{$dataAccess->paymentName}";
        $this->dataAccess = $dataAccess;
        $this->isMobile = is_mobile();
        $this->config();
        $this->init();
    }

    /**
     * 设置返回类型
     * @param string $type
     */
    abstract function setReturnType($type = 'HTML');

    /**
     * 发起支付函数
     * @return mixed
     */
    abstract function goPay();

    /**
     * 返回DATAACCESS
     */
    public function DataAccess()
    {
        return $this->dataAccess;
    }

    /**
     * 获取配置信息
     * @return void [type] [description]
     * @throws Exception
     */
    public function getConfig()
    {
        if (empty($this->paymentName)) {
            throw new Exception("支付名不能为空", 1);
        }
        $this->paymentConfig = M('view_payment')->where('gateway_identifier', $this->paymentName)->find();
        if (!$this->paymentConfig) {
            throw new Exception("支付不存在", 1);
        }
        $this->paymentConfig['notify_url'] = self::getDomain($this->paymentConfig['notify_url']);
        $this->paymentConfig['callback_url'] = self::getDomain($this->paymentConfig['callback_url']);
    }

    /**
     * 系统初始化
     * @return void [type] [description]
     */
    public function init()
    {

    }

    /**
     * 更新用户账户余额函数
     * @param string $order_no
     * @param string $payer
     * @param string $channel_name
     * @param float $price
     * @param float $real_price
     * @param string $bill_no
     * @return mixed
     */
    protected function handleUserMoney(string $order_no, string $payer, string $channel_name, float $price, float $real_price = 0, $bill_no = '')
    {
        if (!$order_no) {
            return -5997;
        }
        $order_info = (new Pay_order())->where('pay_orders.order_no', $order_no)
            ->leftJoin('pay_channels', 'pay_channels.id', '=', 'pay_orders.channel_id')
            ->select('pay_orders.*', 'pay_channels.gift_price_rate', 'pay_channels.gift_black_list')
            ->first();
        if ($order_info->status == 1) return 2;//如已确认订单直接返回
        $data['status'] = 1;
        if (!empty($bill_no)) {
            $data['bill_no'] = $bill_no;
        }
        $data['notify_query'] = 'REQUEST=>' . http_build_query($_REQUEST) . '||json=>' . file_get_contents('php://input');
        $data['updated_at'] = date('Y-m-d H:i:s');
        if ($real_price) {
            $data['real_price'] = $real_price;
        }
        $operator = "auto";
        $reason = "在线充值";
        $detail = sprintf("用户【%s】于%s完成在线支付，订单号：%s，支付金额：%s元。", $payer, date('Y-m-d H:i:s'), $order_no, $price);
        $aoc = new AddOrCutMoney();
        _beginTransaction();
        $ret = lm('Pay_order', 'commons')->where('order_no', $order_no)->update($data);
        if ($ret !== 1) {
            _rollBack();
            return $ret;
        }
        $accountDetail = new AccountDetail();
        $account_identity = $order_info->payer_id;
        $accountDetail = $accountDetail->where('account_identity', $account_identity)->first();
        if (!$accountDetail) return -5991;
        $moneyRecharge = lm('MoneyRecharge', 'api')->where('order_id', $order_no)->first();
        if (!$moneyRecharge)
            $ret = $aoc->addMoneyRechargeRec($accountDetail, $order_info->payer, $order_no, $order_info->price, '在线充值', $operator, $reason, $reason, 1, 1);
        else
            $ret = lm('MoneyRecharge', 'api')->where('order_id', $order_no)->update(['status' => 1]);
        if (is_int($ret) && $ret < 1) {
            _rollBack();
            return $ret;
        }
        $ret = $aoc->addMoneyDetailRec($accountDetail, $order_info->payer, $order_no, $order_info->price, 1, 6, $operator, $detail, $reason);
        if (is_int($ret)) {
            _rollBack();
            return $ret;
        }
        $ret = $aoc->incAccountDetailMoney($accountDetail, $order_info->price);
        if ($ret !== 1) {
            _rollBack();
            return $ret;
        }

        $gift_price_rate = explode('||', $order_info->gift_price_rate);
        if (!empty($gift_price_rate)) {
            $gbla = explode('||', $order_info->gift_black_list);
            $num = intval($gift_price_rate['0']) ?? 0;
            $rate = intval($gift_price_rate['1']) ?? 0;
            if (!in_array($payer, $gbla) && $rate && $num <= $price) {
                $gift_price = $price * $rate / 100;
                $gift_price = floatval($gift_price);
                $gift_order_no = $order_no . "-G";
                $reason = '在线充值赠送';
                $detail = sprintf("用户【%s】于%s获得充值赠送，订单号：%s，赠送金额：%s元。", $payer, date('Y-m-d H:i:s'), $gift_order_no, $gift_price);
                $accountDetail->cash = floatval($accountDetail->cash + $order_info->price);
                $ret = $aoc->addMoneyRechargeRec($accountDetail, $order_info->payer, $gift_order_no, $gift_price, '在线充值赠送', $operator, $reason, $reason);//资金明细
                if (is_int($ret)) {
                    _rollBack();
                    return $ret;
                }
                $ret = $aoc->addMoneyDetailRec($accountDetail, $order_info->payer, $gift_order_no, $gift_price, 1, 13, $operator, $detail, $reason);//流水记录
                if (is_int($ret)) {
                    _rollBack();
                    return $ret;
                }
                $ret = $aoc->incAccountDetailMoney($accountDetail, $gift_price);
                if ($ret !== 1) {
                    _rollBack();
                    return $ret;
                }
            }

        }


        _commit();
        return 1;
    }

    /**
     * 模拟表单提交处理函数
     * @param array $order_info
     * @param  string $action 提交方式
     * @return string
     */
    public function handlePost(array $order_info, $action = "POST")
    {
        if ($this->debug) {
            $inputType = "text";
            $script = '';
        } else {
            $inputType = "hidden";
            $script = 'setTimeout(()=>{document.getElementById("submitForm").submit();},200)';
        }
        $orderInfo = $order_info ? $order_info : $this->buildOrder();
        $url = $this->apiUrl;
        if (is_array($orderInfo) && count($orderInfo) > 0) {
            $forms = '';
            foreach ($orderInfo as $k => $v) {
                $forms .= "<input type={$inputType} name='{$k}' value='{$v}' />";
            }
            /*  $forms = trim($forms, PHP_EOL . "\t\t\t");*/
        }
        if (empty($url)) {
            $url = $this->getWay;
        }
        $str = "<html>
    <head>
        <title>Payment By CreditCard online</title>
        <meta http-equiv='Content-Type' content='text/html; charset={$this->charset}'>
    </head>
    <body>
        <form action='{$url}' method='{$action}' id='submitForm' name='E_FORM'>
            {$forms}
        </form>
        <script type='text/javascript'>
            {$script}
        </script>
    </body>
</html>
		";
        //toLog($str);
        return $str;
    }

    /**
     * 提取证书中的公钥和私钥KEy，以数据形式返回
     * @return array [type] [description]
     * @throws Exception
     */
    public function certPatchKey()
    {
        $priContent = file_get_contents($this->privateCertPath);
        $pubContent = file_get_contents($this->publicCertPath);
        $priKey = openssl_get_privatekey($priContent);
        $pubKey = openssl_pkey_get_public($pubContent);
        if (empty($priKey) || empty($pubKey)) {
            throw new Exception("支付的私钥和公钥不能为空", 1);
        }
        return array('private' => $priKey, 'public' => $pubKey);
    }

    /**
     * 处理CURL提交函数
     * @param  [type] $url    [description]
     * @param  array $data [description]
     * @param array $header
     * @param bool $ssl
     * @return bool|int|string [type]         [description]
     */
    function goPayCurl($url, $data = array(), $header = array(), $ssl = false)
    {
        if (is_array($data)) {
            $data = http_build_query($data);
        }
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, $ssl);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, $ssl);
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
        if (is_array($header) && count($header) > 0) {
            curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
            curl_setopt($ch, CURLOPT_HEADER, 0);
        }
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
        // curl_setopt($ch, CURLOPT_HTTPHEADER, 1);
        $result = curl_exec($ch);
//        $errno = curl_errno($ch);
        curl_close($ch);
        if ($result == NULL) {
            return 0;
        }
        return $result;
    }

    /**
     * 提示信息
     * @param  [type]  $msg  [description]
     * @param  integer $code [description]
     * @return void [type]        [description]
     */
    function showNotice($msg, $code = -1)
    {
        if (strtolower($this->returnType) == 'json') {
            JsonReturn('', $code, $msg);
        } else {
            exit($msg);
        }
    }

    /**
     * 成功信息
     * @param  [type] $data [description]
     * @return void [type]       [description]
     */
    function jsonSuccess($data)
    {
        if ($this->returnType == 'json') {
            JsonReturn($data, 1, 'success');
        }
    }

    /**
     * 获取ip信息
     */
    function getRealIp()
    {
        $ip = false;
        if (!empty($_SERVER["HTTP_CLIENT_IP"])) {
            $ip = $_SERVER["HTTP_CLIENT_IP"];
        }
        if (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
            $ips = explode(", ", $_SERVER['HTTP_X_FORWARDED_FOR']);
            if ($ip) {
                array_unshift($ips, $ip);
                $ip = FALSE;
            }
            for ($i = 0; $i < count($ips); $i++) {
                if (!eregi("^(10|172\.16|192\.168)\.", $ips[$i])) {
                    $ip = $ips[$i];
                    break;
                }
            }
        }
        return ($ip ? $ip : $_SERVER['REMOTE_ADDR']);
    }

    /**
     * 订单写入数据表（pay_orders）
     * @param array $orderInfo
     * @return int|void
     */
    function addOrder(array $orderInfo)
    {
        $this->log($orderInfo['gateway_name'] . '-Pay', '开始写入订单信息');
        if ($this->debug) return;
        if (empty($orderInfo['order_no']) || empty($orderInfo['payer']) || empty($orderInfo['price']) || !$orderInfo['payer_id']) {
            JsonReturn('', -1, '传参有误！');
        }
        $order_info = lm('Pay_order', 'Commons')->where('order_no', $orderInfo['order_no'])->find();
        if ($order_info) {
            JsonReturn('', -2, '您已成功提交该订单，请不要重复操作！');
        }
        $payer = $orderInfo['payer'];
        $price = $orderInfo['price'];
        $order_no = $orderInfo['order_no'];
        $operator = 'auto';
        $reason = '在线充值';
        $accountDetail = new AccountDetail();
//        $account_info = (new Account())->getAccountByToken();

        $account_identity = $this->userInfo['account_identity'];
        $accountDetail = $accountDetail->where('account_identity', $account_identity)->first();
        if (!$accountDetail) return -5991;
        $aoc = new AddOrCutMoney();
        _beginTransaction();
        $res = lm('Pay_order', 'Commons')->insert($orderInfo);
        if ($res < 1) {
            _rollBack();
            $this->log($orderInfo['gateway_name'] . '-Pay', '订单写入失败，请尝试重新提交！');
            JsonReturn('', -3, '订单写入失败，请尝试重新提交！');
        }
        $res = $aoc->addMoneyRechargeRec($accountDetail, $payer, $order_no, $price, '在线充值', $operator, $reason, $reason, 1, 0);
        if (is_int($res)) {
            _rollBack();
            $this->log($orderInfo['gateway_name'] . '-Pay', '订单REMARK写入失败，请尝试重新提交！');
            JsonReturn('', -4, '订单REMARK写入失败，请尝试重新提交！');
        }
        _commit();
        $this->log($orderInfo['gateway_name'] . '-Pay', '订单写入成功！订单号:' . $orderInfo['order_no'] . ',金额:' . $orderInfo['price']);
        return 1;
    }


    /**
     * 获取订单信息函数
     * @param string $order_no
     * @return Pay_order||null
     */
    protected
    function getOrder(string $order_no)
    {
        return $channel_info = lm('Pay_order', 'commons')
            ->leftJoin('pay_gateways', 'pay_gateways.id', '=', 'pay_orders.gateway_id')
            ->where('pay_orders.order_no', $order_no)
            ->first();
    }

    /**
     * 获取订单信息函数
     * @param string $bill_no
     * @return Pay_order||null
     */
    protected
    function getOrderByBillNo(string $bill_no)
    {
        return
            $channel_info = lm('Pay_order', 'commons')
                ->leftJoin('pay_gateways', 'pay_gateways.id', '=', 'pay_orders.gateway_id')
                ->where('bill_order_no', $bill_no)
                ->first();
    }

    /**
     * 生成订单表基本数据
     * @param array $orderInfo
     * @return array
     */
    function buildOrderInfo(array $orderInfo = []): array
    {
        return [
            'order_no' => $this->dataAccess->orderSn,
            'payer' => ($orderInfo['payer'] ?? $this->userInfo->account) ?? 'guest',
            'payer_id' => ($orderInfo['payer_id'] ?? $this->userInfo->account_identity) ?? null,
            'price' => $this->dataAccess->money,
            'status' => 0,
            'remark' => $this->dataAccess->extra ?? '',
            'ip' => $this->getRealIp(),
            'created_at' => date('Y-m-d H:i:s'),
            'operator' => 'auto',
            'gateway_id' => $this->dataAccess->gateway_id,
            'channel_id' => $this->dataAccess->channel_id,
        ];
    }

    /**
     * 返回支付通道信息
     * @param string $gateway_code
     * @param string $gateway_identifier
     * @return View_payment|null
     */
    protected function getChannelInfo(string $gateway_code, string $gateway_identifier)
    {
        return $channel_info = lm('View_payment', 'commons')
            ->where('gateway_identifier', $gateway_identifier)
            ->where('gateway_code', $gateway_code)
            ->first();
    }

    /**
     * 同步跳转
     * @param array $data
     * @return void [type] [description]
     */
    function callback(array $data = [])
    {
        $html = <<<EOT
        <script>setTimeout(function() {
          window.history.go(-2);
        },3000);</script>
EOT;
        echo '支付已受理。如有疑问请联系客服！3秒后返回支付页，请稍候...';
        echo $html;
    }

    /**
     * 验证签名函数
     * @param  array $param
     * @param string $sign
     * @param string $order_no
     * @param float $price
     * @param float $real_price
     * @param bool $is_bill_no
     * @param string $bill_no
     * @return void
     */
    protected function checkSign(array $param, string $sign, string $order_no, float $price, float $real_price = 0, bool $is_bill_no = false, $bill_no = '')
    {
        if (!$price) {
            die(Lang('Errors', 'Api')->get('error-5993'));
        }
        $order_info = $is_bill_no ? $this->getOrderByBillNo($order_no) : $this->getOrder($order_no);
        if (floatval($price) != floatval($order_info->price)) {
            $this->log($order_info->gateway_name . '-Notify', $order_no . ':' . Lang('Errors', 'Api')->get('error-5996'));
            die(Lang('Errors', 'Api')->get('error-5996'));
        }
        $order_no = $order_info->order_no;
        $gateway_code = $order_info->gateway_code;
        $gateway_identifier = $order_info->gateway_identifier;
//        dd($gateway_code, $gateway_identifier, $order_info);
        $channel_info = $this->getChannelInfo($gateway_code, $gateway_identifier);
        if (!$channel_info || !$order_no) {
            $this->log($gateway_identifier . '-Notify', $order_no . ':' . Lang('Errors', 'Api')->get('error-5994'));
            die(Lang('Errors', 'Api')->get('error-5994'));
        }
        if (!$bill_no) $bill_no = $order_no;
        $merchant_secret = $channel_info->merchant_md5_secret;
        $this->merchant_id = $channel_info->merchant_id;
        $newSign = $this->buildSign($param, $merchant_secret);
        if ($newSign === $sign) {
            $this->log($gateway_identifier . '-Notify', '订单' . $order_no . '已校验成功');
            $ret = $this->handleUserMoney($order_no, $order_info->payer, $channel_info->channel_name, $price, $real_price, $bill_no);
            if ($ret === 1) {
                $this->log($gateway_identifier . '-Notify', '订单已被确认！订单号：' . $order_no . ',订单金额：' . $price . '元。');
            } elseif ($ret === 2) {
                //已确认过
            } else {
                //更新账户金额出现异常
                $this->log($gateway_identifier . '-Notify', '订单确认失败:' . Lang('Errors', 'Api')->get('error' . $ret) . '！订单号：' . $order_no . ',订单金额：' . $price . '元,状态码：' . $ret);
            }
            die($this->success);
        } else {
            $obj = new Pay_order();
            $order_info = $obj->where('order_no', $order_no)->first();
            if ($order_info && $order_info->status == 0) {
                $obj->update(['notify_query' => 'REQUEST=>' . http_build_query($_REQUEST) . '||json=>' . file_get_contents('php://input')])
                    ->where(['order_no' => $order_no]);
            }
            $this->log($gateway_identifier . '-Notify', '订单信息被篡改！订单号：' . $order_no . ',订单金额：' . $price . '元，来自IP：' . $this->getRealIp());
            die($this->errMsg ?? '订单信息被篡改，如有疑问请联系客服！');
        }
    }

    /**
     * 订单入库，返回订单预支付信息函数
     * @param bool $skip_order
     * @param string $qrcode_url
     * @param string $type
     * @return void
     */
    protected function prePay(bool $skip_order = false, string $qrcode_url = '', $type = '')
    {
        $orderInfo = $skip_order ? new stdClass() : $this->buildOrder();
        $sysOrderInfo = $this->buildOrderInfo();
        $payInfo = new PayInfo();
        $payInfo->debug = $this->debug;
        $payInfo->orderInfo = $orderInfo;
        $payInfo->apiUrl = $this->apiUrl;
        $payInfo->jump = $skip_order ? 1 : 0;
        if ($qrcode_url) {
            $payInfo->orderInfo = $sysOrderInfo;
            $payInfo->orderInfo['qrcode_url'] = $qrcode_url;
            $payInfo->orderInfo['type'] = $type;
            ksort($payInfo->orderInfo);
            $payInfo->orderInfo['qrcode_sign'] = md5(http_build_query($payInfo->orderInfo));
            $httpSchema = $_SERVER['REQUEST_SCHEME'] ?? 'http';
            $payInfo->apiUrl = "{$httpSchema}://{$this->domain}/Payment-Pay/Qrcode";
            $payInfo->jump = 0;
        }
        !$this->method ?: $payInfo->method = $this->method;
        $payInfo->jump_url = (!$this->paymentConfig['en_jump']) ? '' : $this->paymentConfig->jump_url;
        $this->payInfo = $payInfo;
        //跳转对方网关时直接订单入库
        if ($this->paymentConfig['rand_price'])
            $this->dataAccess->money -= $this->dataAccess->rand_price;
        $this->log($this->paymentConfig['gateway_identifier'] . '-Pay', '订单提交数据：' . json_encode($orderInfo));
        $this->addOrder($sysOrderInfo);
        if ($this->jump) {
            $this->jump($payInfo);
            exit;
        }
        Render($this->payInfo, 1);
    }

    /**
     * 支付日志操作函数
     * @param $file_name
     * @param $contents
     * @return bool|int
     */
    protected function log($file_name, $contents)
    {
        $file_path = ROOT_PATH . '/Cache/log/' . $file_name . '.log';
        $contents = PHP_EOL . date('Y-m-d H:i:s') . ':' . $contents . PHP_EOL;
        return file_put_contents($file_path, $contents, FILE_APPEND);
    }

    /**
     * 格式化RSA密钥函数
     * @param $secretString
     * @param bool $is_pub_key
     * @return string
     */
    function formatRsaSecret($secretString, $is_pub_key = false)
    {
        $secretString = str_replace(['-----BEGIN PUBLIC KEY-----', '-----BEGIN PRIVATE KEY-----', '-----END PRIVATE KEY-----', '-----END PUBLIC KEY-----'], '', $secretString);
        $secretString = str_replace(['\n', '\r', '\t'], '', $secretString);
        $body = '';
        $pos = 0;
        $read = true;
        while ($read) {
            $sub = substr($secretString, $pos, 64);
            $pos += 64;
            $body .= $sub;
            $read = $sub ? true : false;
        }
        $header = $is_pub_key ? '-----BEGIN PUBLIC KEY-----' : '-----BEGIN PRIVATE KEY-----';
        $footer = $is_pub_key ? '-----END PUBLIC KEY-----' : '-----END PRIVATE KEY-----';
        return $header . PHP_EOL . $body . PHP_EOL . $footer;
    }

    /**
     * 默认的二次跳转类网关处理函数
     * @param PayInfo $pay_info
     */
    protected function jump(PayInfo $pay_info)
    {
        $order_info = $pay_info->orderInfo;
        echo $this->handlePost($order_info, $this->method);
    }

    /**
     * 返回网址域名部份函数
     * @param string $url
     * @return string
     */
    protected function getDomain(string $url)
    {
        preg_match('/http(s)?:\/\/[\d\w]+([\-]?[\w\d]+)?(\.[\d\w]+([\-]?[\w\d]+)?[:\d+]?)+\//is', $url, $found);
        return $found ? $found[0] : '';
    }
}

/**
 * 预支付订单信息类
 */
class PayInfo
{
    public $debug = 0;
    public $orderInfo;
    public $apiUrl;
    public $method = "POST";
    public $jump = 0;
    public $jump_url = "";
}