<?php
/**
 * Shengpay.php UTF-8
 * 盛付通微信支付函数
 *
 * @date    : 2017年05月03日上午12:40:40
 * @license 这不是一个自由软件,未经授权不许任何使用和传播。
 * @author  : ou <ozf@huosdk.com>
 * @version : HUOSDK 7.0
 */

namespace huolib\pay\driver;

use huolib\constant\PaywayConst;
use huolib\pay\Driver;
use think\Exception;
use think\Log;

class Shengpay extends Driver {
    private $config;

    /**
     * 构造函数
     */
    public function __construct() {
        // 包含配置文件
        if (file_exists(GLOBAL_CONF_PATH."extra/pay/shengpay/config.php")) {
            $_config = include GLOBAL_CONF_PATH."extra/pay/shengpay/config.php";
        } else {
            $_config = array();
        }
        $this->config = array(
            'url'                   => "https://api.shengpay.com/html5-gateway/express.htm?page=mobile",
            'senderId'              => $_config['senderId'],
            'key'                   => $_config['key'],
            'rsa_public_key'        => $_config['rsa_public_key'],
            'default_mem_real_name' => $_config['default_mem_real_name'],
            'default_mem_mobile'    => $_config['default_mem_mobile'],
        );
        $this->notify_url = $_config['notify_url'];
    }

    /**
     * 移动APP支付函数
     *
     * @access public
     *
     */
    public function clientPay() {
        // TODO: Implement clientPay() method.
    }

    /**
     * 移动端支付函数
     *
     * @return bool
     */
    public function mobilePay() {
        $_ext['product_id'] = $this->product_id;
        $_data = array(
            "merchantNo"            => $this->config['senderId'],
            "charset"               => 'UTF-8',
            "requestTime"           => date("YmdHis", time()),
            "outMemberId"           => $this->mem_id,
            "outMemberRegistTime"   => date("YmdHis", $this->mem_reg_time),
            "outMemberRegistIP"     => $this->getIp(),
            "outMemberVerifyStatus" => empty($this->mem_real_name) ? '0' : '1',
            "outMemberName"         => empty($this->mem_real_name) ? $this->config['default_mem_real_name']
                : $this->mem_real_name,
            "outMemberMobile"       => empty($this->mem_mobile) ? $this->config['default_mem_mobile']
                : $this->mem_mobile,
            "merchantOrderNo"       => $this->order_id,
            "productName"           => $this->product_name,
            "productDesc"           => $this->product_desc,
            "currency"              => 'CNY',
            "amount"                => $this->real_amount,
            "pageUrl"               => $this->return_url,
            "notifyUrl"             => $this->notify_url,
            "userIP"                => $this->getIp(),
            "exts"                  => json_encode($_ext),
            "signType"              => "MD5"
        );
        $_sign = '';
        foreach ($_data as $val) {
            if ($val !== '') {
                $_sign = $_sign.$val.'|';
            }
        }
        $_sign = $_sign.$this->config['key'];
        $_data['signMsg'] = strtoupper(md5($_sign));
        $html_text = $this->buildRequestForm($_data, "post", $this->config['url']);
        header("Content-type:text/html;charset=utf-8");

        return $this->clientAjax(PaywayConst::PAYWAY_SHENGPAY, $html_text, 1, 1, 1);
    }

    /**
     * @param $param
     * @param $method
     * @param $action
     *
     * @return string
     */
    function buildRequestForm($param, $method, $action) {
        $_sHtml = "<form id='shengpaysubmit' name='shengpaysubmit' action='".$action."' method='".$method."'>";
        foreach ($param as $key => $val) {
            $_sHtml .= "<input type='hidden' name='".$key."' value='".$val."'/>";
        }
        $_sHtml = $_sHtml.'</form>';

        return $_sHtml;
    }

    /**
     * PC端支付函数
     *
     * @access public
     *
     *
     */
    public function pcPay() {
        return $this->mobilePay();
    }

    /**
     * 异步回调函数
     *
     * @access public
     */
    public function notifyUrl() {
        $_verify_result = $this->verifyNotify();
        if ($_verify_result === true) {
            /* 平台订单号 */
            $_out_trade_no = $_REQUEST["OrderNo"];;
            /* 支付宝交易号 */
            $_trade_no = $_REQUEST['TransNo'];
            /* 交易金额 */
            $_amount = $_REQUEST['TransAmount'];
            /*	该笔订单的备注、描述、明细等。对应请求时的body参数,原样通知回来。 */
            $_ext1 = htmlspecialchars_decode($_REQUEST['Ext1']);
            $_ext = json_decode($_ext1, true);
            $_product_id = $_ext['product_id'];
            // 交易状态
            $trade_status = $_REQUEST['TransStatus'];
            if ($trade_status === '01') {
                $_class = $this->order_class;
                $_func = $this->func;
                try {
                    if (class_exists($_class)) {
                        $_order = new $_class();
                        $_order->$_func($_product_id, $_out_trade_no, $_trade_no, $_amount, 'shengpay');
                    } else {
                        Log::write(
                            "func=".__FUNCTION__."&class=".__CLASS__."&order_class=".$_class
                            ."&func=".$_func, LOG::ERROR
                        );
                    }
                } catch (Exception $_e) {
                    Log::write(
                        "func=".__FUNCTION__."&class=".__CLASS__."&order_class=".$_class
                        ."&func=".$_func."&err=".$_e->getMessage()."&errCode=".$_e->getCode(), LOG::ERROR
                    );
                }
            }
            echo "OK";
            // 下面写验证通过的逻辑 比如说更改订单状态等等 $_POST['out_trade_no'] 为订单号;
        } else {
            echo "fail";
        }
    }

    /**
     * 验证盛付通发来的请求是否合法
     *
     * @return bool|int  合法:true  ,其它false
     */
    function verifyNotify() {
        try {
            $Name = $_REQUEST["Name"];
            $Version = $_REQUEST["Version"];
            $Charset = $_REQUEST["Charset"];
            $TraceNo = $_REQUEST["TraceNo"];
            $MsgSender = $_REQUEST["MsgSender"];
            $SendTime = $_REQUEST["SendTime"];
            $InstCode = $_REQUEST["InstCode"];
            $OrderNo = $_REQUEST["OrderNo"];
            $OrderAmount = $_REQUEST["OrderAmount"];
            $TransNo = $_REQUEST["TransNo"];
            $TransAmount = $_REQUEST["TransAmount"];
            $TransStatus = $_REQUEST["TransStatus"];
            $TransType = $_REQUEST["TransType"];
            $TransTime = $_REQUEST["TransTime"];
            $MerchantNo = $_REQUEST["MerchantNo"];
            $ErrorCode = $_REQUEST["ErrorCode"];
            $ErrorMsg = $_REQUEST["ErrorMsg"];
            $Ext1 = htmlspecialchars_decode($_REQUEST["Ext1"]);
            $SignType = $_REQUEST["SignType"];
            $SignMsg = $_REQUEST["SignMsg"];
            //第一步进行相关的验签操作
            $encryptCode = '';
            $encryptCode .= $this->isEmpty($Name) ? "" : $Name."|";
            $encryptCode .= $this->isEmpty($Version) ? "" : $Version."|";
            $encryptCode .= $this->isEmpty($Charset) ? "" : $Charset."|";
            $encryptCode .= $this->isEmpty($TraceNo) ? "" : $TraceNo."|";
            $encryptCode .= $this->isEmpty($MsgSender) ? "" : $MsgSender."|";
            $encryptCode .= $this->isEmpty($SendTime) ? "" : $SendTime."|";
            $encryptCode .= $this->isEmpty($InstCode) ? "" : $InstCode."|";
            $encryptCode .= $this->isEmpty($OrderNo) ? "" : $OrderNo."|";
            $encryptCode .= $this->isEmpty($OrderAmount) ? "" : $OrderAmount."|";
            $encryptCode .= $this->isEmpty($TransNo) ? "" : $TransNo."|";
            $encryptCode .= $this->isEmpty($TransAmount) ? "" : $TransAmount."|";
            $encryptCode .= $this->isEmpty($TransStatus) ? "" : $TransStatus."|";
            $encryptCode .= $this->isEmpty($TransType) ? "" : $TransType."|";
            $encryptCode .= $this->isEmpty($TransTime) ? "" : $TransTime."|";
            $encryptCode .= $this->isEmpty($MerchantNo) ? "" : $MerchantNo."|";
            $encryptCode .= $this->isEmpty($ErrorCode) ? "" : $ErrorCode."|";
            $encryptCode .= $this->isEmpty($ErrorMsg) ? "" : $ErrorMsg."|";
            $encryptCode .= $this->isEmpty($Ext1) ? "" : $Ext1."|";
            $encryptCode .= $this->isEmpty($SignType) ? "" : $SignType."|";
            if (isset($SignMsg) && isset($SignType) && strcasecmp("RSA", $SignType) == 0) {//RSA验签
                $publicKey
                    = <<<EOT
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC69veKW1X9GETEFr49gu9PN8w7
H6alWec8wmF8SoP3tqQLAflZp8g83UZPX2UWhClnm53P5ZwesaeSTHkXkSI0iSjw
d27N07bc8puNgB5BAGhJ80KYqTv3Zovl04C8AepVmxy9iFniJutJSYYtsRcnHYyU
NoJai4VXhJsp5ZRMqwIDAQAB
-----END PUBLIC KEY-----
EOT;
                //线上的盛付通公钥
                $signResult = openssl_verify(
                    $encryptCode, base64_decode($SignMsg), $publicKey, OPENSSL_ALGO_MD5
                ); // 响应的验签
                if ($signResult) {
                    return true;
                } else {
                    return false;
                }
            } else {
                return false;
            }
        } catch (Exception $e) {
            Log::write(
                "shengpay sign verify err=".$e->getMessage()."&errCode=".$e->getCode(), LOG::ERROR
            );
        }

        return false;
    }

    private function isEmpty($var) {
        if (isset($var) && $var != "") {
            return false;
        } else {
            return true;
        }
    }

    /**
     * 接收支付成功回调
     *
     * @access public
     *
     *
     */
    public function returnUrl() {
        $_status = 2;

        return $this->clientAjax(PaywayConst::PAYWAY_SHENGPAY, '22', $_status, 1, 1);
    }

    /**
     * 查询订单
     *
     * @access public
     *
     * @param string $order_id       商户系统内部订单号
     * @param string $transaction_id 第三方支付的订单号
     * @param null   $ext            扩展信息
     *
     */
    public function orderQuery($order_id, $transaction_id, $ext = null) {
        // TODO: Implement orderQuery() method.
    }
}