<?php
/**
 * 支付宝支付
 */

namespace app\common\pay;

use think\Request;
use app\common\Pay;

/**
 * Class QgjfBase
 * @notice 所有传入参数必须为字符串类型
 * @package app\common\pay
 */
class QgjfBase extends Pay
{
    // 支付结果
    const PAY_SUCCESS = 1;
    const PAY_NOTPAY = 0;
    const PAY_FAIL = 2;
    const PAY_REFUND = 3;

    // 回调地址
    protected $request_url = 'https://pay.jinfupass.com/gateway/pay';

    //支付参数
    protected $version = '1.0';    //  版本号
    protected $mch_id = '';    //	商户号
    protected $pay_type = '';    //	通道类型
    protected $fee_type = 'CNY';    //	货币类型
    protected $total_amount = '';    //	订单金额
    protected $out_trade_no = '';    //	商户订单号
    protected $device_info = '';    //	设备号
    protected $notify_url = '';    //	通知地址
    protected $body = '';    //	商品描述
    protected $attach = '';    //	附加信息
    protected $time_start = '';    //	订单生成时间
    protected $time_expire = '';    //	订单失效时间
    protected $limit_credit_pay = '0';    //	支付方式限制
    protected $hb_fq_num = '';    //	花呗分期
    protected $hb_fq_percent = '';    //	手续费承担方
    protected $key = ''; // key
    protected $minipg = '0'; //是否小程序支付
    protected $openid = ''; //openid， 只有公众号支付需要
    protected $appid = ''; //appid， 只有微信公众号支付需要


    protected $code='';
    protected $error='';

    public function getCode()
    {
        return $this->code;
    }

    public function getError()
    {
        return $this->error;
    }

    public function __construct()
    {

    }

    protected function setAccountInfo()
    {
        $this->mch_id = $this->account->params->mch_id;
        $this->key = $this->account->params->key;

        $this->appid = sysconf('wechat_appid') ? sysconf('wechat_appid') : '';
        $this->openid = session('openid') ? session('openid') : '';
    }

    /**
     * 参数签名
     * @return string
     */
    protected function sign()
    {
        $this->setAccountInfo();
        $signSource = sprintf("version={$this->version}&mch_id={$this->mch_id}&pay_type={$this->pay_type}&total_amount={$this->total_amount}&out_trade_no={$this->out_trade_no}&notify_url={$this->notify_url}&key={$this->key}");
        $sign = md5($signSource);
        return $sign;
    }

    /**
     * 请求参数封装
     * @return array
     */
    protected function getPostData()
    {
        $this->setAccountInfo();
        $data = [
            'version' => $this->version,
            'minipg' => $this->minipg,
            'mch_id' => $this->mch_id,
            'pay_type' => $this->pay_type,
            'fee_type' => $this->fee_type,
            'total_amount' => $this->total_amount,
            'out_trade_no' => $this->out_trade_no,
            'device_info' => $this->device_info,
            'notify_url' => $this->notify_url,
            'body' => $this->body,
            'attach' => $this->attach,
            'time_start' => $this->time_start,
            'time_expire' => $this->time_expire,
            'limit_credit_pay' => $this->limit_credit_pay,
            'hb_fq_num' => $this->hb_fq_num,
            'hb_fq_percent' => $this->hb_fq_percent,
            'sp_client_ip' => $_SERVER['REMOTE_ADDR'],
            'appid' => $this->appid,
            'openid' => $this->openid,
            'sign' => $this->sign(),
        ];

        return $data;
    }

    /**
     * 请求
     * @param $url
     * @param $data
     * @return mixed
     */
    protected function post($url,$data)
    {
        $ch = curl_init();
        if($this->account->params->refer){
            curl_setopt($ch, CURLOPT_REFERER, $this->account->params->refer); //防封域名
        }
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_HEADER, 0);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        $response = curl_exec($ch);
        if (curl_errno($ch)) {
            print curl_error($ch);
        }
        curl_close($ch);
//        echo '<pre>';
//        echo $response;
//        var_dump($data);
        $res = json_decode($response, true);

        return $res;
    }

    /**
     * 下单
     * @return mixed
     */
    protected function request(){

        $result = $this->post($this->request_url,$this->getPostData());

        if ($result['result_code'] == 1) {
            $this->code    = 0;
            $obj          = new \stdClass();
            $obj->pay_url = $result['code_url'];
            $obj->content_type = 1;
            return $obj;
        }else{
            $this->code  = 500;
            $this->error = $result['return_msg'];
            return false;
        }
    }

    /**
     * 验签
     * @param $result
     * @return bool
     */
    protected function checkSign($result)
    {
        $this->setAccountInfo();
        $out_trade_no = $result['out_trade_no'];//商户系统订单号，原样返回
        $fee_type = 'CNY';//默认人民币：CNY
        $pay_type = $result['pay_type'];//支付类型 ，比如 201 202
        $total_amount = $result['total_amount'];//订单金额，单位为分
        $device_info = $result['device_info'];//终端设备号
        $postSign = $result['sign'];//MD5签名，32位小写

        $signSource = sprintf("mch_id=%s&out_trade_no=%s&fee_type=%s&pay_type=%s&total_amount=%s&device_info=%s&key=%s", $this->mch_id, $out_trade_no, $fee_type, $pay_type, $total_amount, $device_info, $this->key); //连接字符串加密处理
        $sign = md5($signSource);

        return $sign == $postSign;
    }

    /**
     * 支付后续操作
     * @param $result
     * @param $order
     */
    protected function complete($result, &$order)
    {
        $this->setAccountInfo();
        $trade_state = $result['trade_state'];//1：支付成功，0：未支付，2：失败，3：已退款
        if ($trade_state == self::PAY_SUCCESS) {
            return $this->completeOrder($order);
        }

        return false;
    }
    
    /**
     * 页面回调
     */
    public function page_callback($params, $order)
    {
        header("Location:" . url('/orderquery',['orderid'=>$order->trade_no]));
    }

    /**
     * 服务器回调
     */
    public function notify_callback($params, $order)
    {
        if ($this->checkSign($params)) {
            //此处作逻辑处理
            if ($this->complete($params, $order)) {
                echo('success');
                return true;
            }
        }
        echo('FAIL');
        exit;
    }

}
