<?php

namespace payment;

use think\facade\Db;
use app\service\PayLogService;

/**
 * 虎皮椒微信支付
 */
class HupijiaoWxPay {
    //插件配置参数
    private $config;

    public function __construct($params = []) {
        $this->config = $params;
    }

    /**
     * 配置信息
     */
    public function Config() {
        // 基础信息
        $base = [
            'name' => '虎皮椒微信支付',
            'version' => '1.0.1',
            'apply_version' => '不限',
            'apply_terminal' => ['pc','h5','weixin'],// 适用终端 默认全部 ['pc', 'h5', 'app', 'alipay', 'weixin', 'baidu']
            'desc' => '个人微信支付接口，无需提现，100%资金安全，官方清算，金额无限制，支持各种网站系统。是个人收款的最佳解决方案。<a href="https://admin.xunhupay.com/sign-in.html" target="_blank">立即申请</a>',  // 插件描述（支持html）
            'author' => '迅虎网络',  // 开发者
            'author_url' => 'https://www.wpweixin.net/',  // 开发者主页
        ];

        // 配置信息
        $element = [
            [
                'element' => 'input',
                'type' => 'text',
                'default' => '',
                'name' => 'app_id',
                'placeholder' => 'AppID',
                'title' => 'AppID',
                'is_required' => 0,
                'message' => '请填写虎皮椒分配的AppID',
            ],
            [
                'element' => 'input',
                'type' => 'text',
                'default' => '',
                'name' => 'app_secret',
                'placeholder' => 'AppSecret',
                'title' => 'AppSecret',
                'is_required' => 0,
                'message' => '请填写虎皮椒分配的AppSecret',
            ],
            [
                'element' => 'input',
                'type' => 'text',
                'default' => 'https://api.xunhupay.com/payment/do.html',
                'name' => 'gateway_url',
                'placeholder' => '网关地址',
                'title' => '网关地址',
                'is_required' => 0,
                'message' => '请填写虎皮椒支付网关地址',
            ]
        ];

        return [
            'base' => $base,
            'element' => $element,
        ];
    }


    /**
     * 支付入口
     */
    public function Pay($params = []) {
        // 参数
        if (empty($params)) {
            return DataReturn('参数不能为空', -1);
        }

        // 配置信息
        if (empty($this->config)) {
            return DataReturn('支付缺少配置', -1);
        }
        $parameter=$this->GetPayParams($params);

        // 支付请求记录
        PayLogService::PayLogRequestRecord($params['order_no'], ['request_params'=>$parameter]);

        $response=$this->HttpRequest($this->config['gateway_url'],$parameter);
        $response=json_decode($response,true);
        if(isset($response['errcode'])&&$response['errcode']==0){
            return DataReturn('success', 0, $response['url']);
        }
        return DataReturn($response['errmsg'], -1);
    }

    /**
     * 支付回调处理
     */
    public function Respond($params = []) {
        //支付异步回调
        if(isset($_POST['hash'])){
            file_put_contents(dirname(__FILE__).'/log.txt',json_encode($_POST)."\r\n",FILE_APPEND);
            $respose=$_POST;
            $this->checkRespose($respose);
            return DataReturn('支付成功', 0, $this->ReturnData($respose));
        }
        //查询订单支付状态
        if(isset($_GET['order_no'])){
            $order_no=$_GET['order_no'];
            $payData=Db::name('PayLog')->where('log_no',$order_no)->order('id desc')->find();
            if(!$payData){
                return DataReturn('订单暂无支付信息！', -100);
            }
            $data=[
                'trade_no'=>$payData['trade_no'],
                'buyer_user'=>$payData['buyer_user'],
                'out_trade_no'=>$order_no,
                'subject'=>$payData['subject'],
                'pay_price'=>$payData['pay_price'],
            ];
            return DataReturn('支付成功', 0,$data);
        }
        //同步-因同步不携带验签参数，所以需要ajax查询订单是否支付
        return DataReturn('处理异常错误', -100);
    }

    /**
     * 退款处理
     */
    public function Refund($params = []){
        return DataReturn('该支付方式暂未提供退款接口', -1);
    }

    /**
     * 返回数据统一格式
     */
    private function ReturnData($data) {
        // 返回数据固定基础参数
        $data['trade_no']       = $data['transaction_id'];  // 支付平台 - 订单号
        $data['buyer_user']     = $data['appid'];           // 支付平台 - 用户
        $data['out_trade_no']   = $data['trade_order_id'];  // 本系统发起支付的 - 订单号
        $data['subject']        = $data['plugins'];         // 本系统发起支付的 - 商品名称
        $data['pay_price']      = $data['total_fee'];       // 本系统发起支付的 - 总价
        return $data;
    }

    /**
     * 查询
     */

    /**
     * 获取支付参数
     */
    private function GetPayParams($params = []){
        $data = [
            'version' => '1.1',
            'appid' => $this->config['app_id'],
            'trade_order_id'=> $params['order_no'],
            'payment' => 'wechat',
            'total_fee' => round($params['total_price'],2),
            'title' => $params['name'].'-订单号:'.$params['order_no'],
            'time' => time(),
            'notify_url'=> $params['notify_url'],
            'return_url'=> $params['call_back_url'].'?order_no='.$params['order_no'],
            'nonce_str' => md5(time()),
            'plugins'=>$params['name']
        ];
        $data['hash']=$this->GenerateHash($data);
        return $data;
    }

    /**
     * 生成hash
     */
    private function GenerateHash($data=[]){
        if(array_key_exists('hash',$data)){
            unset($data['hash']);
        }
        ksort($data);
        $string=$this->FormatUrlParams($data).$this->config['app_secret'];
        return md5($string);
    }

    /**
     * 格式化参数
     */
    private function FormatUrlParams($data=[]){
        $buff = "";
        foreach ($data as $k => $v) {
            if ($k != "hash" && $v !== "" && !is_array($v)) {
                $buff .= $k . "=" . $v . "&";
            }
        }
        $buff = trim($buff, "&");
        return $buff;
    }

    /**
     * http请求
     */
    private function HttpRequest($url, $data = '',$headers = []) {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS , $data);
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        $output = curl_exec($ch);
        $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);    // 获取响应状态码
        $error = curl_error($ch);
        curl_close($ch);
        if ($http_code != 200) {
            exit("error:{$error}");
        }
        return $output;
    }

    /**
     * 校验参数
     */
    private function CheckRespose($data){
        if($data['status']!='OD'){
            exit($data['status']);
        }
        //校验签名
        if(!$this->CheckHash($data)){
            exit('签名校验失败');
        }
    }

    /**
     * 校验签名
     */
    private function CheckHash($data){
        $hish=$this->GenerateHash($data);
        if($hish==$data['hash']){
            return true;
        }
        return false;
    }

}

?>