<?php

/**
 * @Author: 琳飞
 * @Date:   2019-10-26 23:30:41
 * @Last Modified by:   琳飞
 * @Last Modified time: 2019-10-26 23:47:46
 * @E-mail: admin@eyabc.cn
 */
class Xiaowei
{
    /**
     * 配置
     * @var array
     */
    protected $config;
    /**
     * 支付网关
     * @var string
     */
    protected $apiurl = 'https://www.8817892.cn/';

    /**
     * 初始化构造方法
     * @access public
     * @param  array   $config
     */
    public function __construct($config)
    {
		// 支付网关
        $this->apiurl = isset($config['apiurl']) && !empty(trim($config['apiurl'])) ? $config['apiurl'] : $this->apiurl;
        // 支付配置
        $this->config = $this->getValue($config, ['appid', 'key', 'notifyUrl', 'returnUrl']);
    }

    /**
     * 批量获取值
     * @access protected
     * @param  array   $data    欲获取的数组
     * @param  array    $params 键名列表
     * @return array
     */
    protected function getValue($data, $params = [])
    {
        $list = [];
        foreach ($params as $value) {
            $list[$value] = isset($data[$value]) ? $data[$value] : null;
        }
        return $list;
    }

    /**
     * 创建支付请求
     * @access public
     * @param  array   $data
     * @return string  Html Form
     */
    public function createPayRequest($data)
    {
        // 异步回调地址
        $notify_url = $this->config['notifyUrl'];
        // 同步回调地址
        $return_url = $this->config['returnUrl'];
        // 商户订单号
        $out_trade_no = $data['out_trade_no'];
        // 订单名称
		$name = $out_trade_no;
        // 支付金额
        $money = sprintf("%.2f", $data['money']);
        // 站点名称
		$sitename = $out_trade_no;
		
        //构造要请求的参数数组
        $parameter = array(
            "pid"          => trim($this->config['appid']),
            "type"         => 'wxpay',
            "notify_url"   => $notify_url,
            "return_url"   => $return_url,
            "out_trade_no" => $out_trade_no,
            "name"         => $name,
            "money"        => $money,
            "sitename"     => $sitename,
        );

        //待请求参数数组
        $para  = $this->buildRequestPara($parameter);
		
        $sHtml = "<form id='epaysubmit' name='epaysubmit' action='{$this->apiurl}/pay/epay/order?_input_charset=utf-8' method='GET'>";
        while (list($key, $val) = each($para)) {
            $sHtml .= "<input type='hidden' name='" . $key . "' value='" . $val . "'/>";
        }
        //submit按钮控件请不要含有name属性
        $sHtml = $sHtml . "<input type='submit' value='正在提交'></form>";
        $sHtml = $sHtml . "<script>document.forms['epaysubmit'].submit();</script>";
        return $sHtml;
    }

    public function notify($data)
    {
        return $this->getSignVeryfy($data, $data["sign"]);
    }

    protected function buildRequestPara($para_temp)
    {
        //除去待签名参数数组中的空值和签名参数
        $para_filter = $this->paraFilter($para_temp);

        //对待签名参数数组排序
        $para_sort = $this->argSort($para_filter);

        //生成签名结果
        $mysign = $this->buildRequestMysign($para_sort);

        //签名结果与签名方式加入请求提交参数组中
        $para_sort['sign']      = $mysign;
        $para_sort['sign_type'] = 'MD5';

        return $para_sort;
    }

    protected function paraFilter($para)
    {
        $para_filter = array();
        while (list($key, $val) = each($para)) {
            if ($key == "sign" || $key == "sign_type" || $val == "") {
                continue;
            } else {
                $para_filter[$key] = $para[$key];
            }

        }
        return $para_filter;
    }

    protected function argSort($para)
    {
        ksort($para);
        reset($para);
        return $para;
    }

    protected function buildRequestMysign($para_sort)
    {
        //把数组所有元素，按照"参数=参数值"的模式用"&"字符拼接成字符串
        $prestr = $this->createLinkstring($para_sort);
		
        $mysign = $this->md5Sign($prestr, $this->config['key']);

        return $mysign;
    }

    protected function createLinkstring($para)
    {
        $arg = "";
        while (list($key, $val) = each($para)) {
            $arg .= $key . "=" . $val . "&";
        }
        //去掉最后一个&字符
        $arg = substr($arg, 0, count($arg) - 2);

        //如果存在转义字符，那么去掉转义
        if (get_magic_quotes_gpc()) {$arg = stripslashes($arg);}

        return $arg;
    }

    protected function md5Sign($prestr, $key)
    {
        $prestr = $prestr . $key;
        return md5($prestr);
    }

    protected function getSignVeryfy($para_temp, $sign)
    {
        //除去待签名参数数组中的空值和签名参数
        $para_filter = $this->paraFilter($para_temp);

        //对待签名参数数组排序
        $para_sort = $this->argSort($para_filter);

        //把数组所有元素，按照"参数=参数值"的模式用"&"字符拼接成字符串
        $prestr = $this->createLinkstring($para_sort);

        $isSgin = false;
        $isSgin = $this->md5Verify($prestr, $sign, $this->config['key']);

        return $isSgin;
    }

    protected function md5Verify($prestr, $sign, $key)
    {
        $prestr = $prestr . $key;
        $mysgin = md5($prestr);
        if ($mysgin == $sign) {
            return true;
        } else {
            return false;
        }
    }
}
