<?php
/**
 * Wxpay.php UTF-8
 *
 *
 * @date    : 2018/5/3 23:07
 *
 * @license 这不是一个自由软件,未经授权不许任何使用和传播。
 * @author  : wuyonghong <wyh@huosdk.com>
 * @version : HUOSDK 8.0
 */

namespace huolib\pay\driver;

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

class Wxpay extends Driver {
    /**
     * 构造函数
     *
     */
    public function __construct() {
    }

    /**
     * 移动APP支付函数
     * https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=8_5
     *
     * @return mixed
     */
    public function clientPay() {
        $_trade_type = 'APP';
        $_class = new WxNotifyCallBack();
        /* https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=9_1 */
        try {
            $_token = $_class->unifiedOrder(
                $this->order_id, $this->real_amount, $this->ip, $this->product_id, $this->product_desc,
                $this->notify_url, $_trade_type
            );

            return $this->clientAjax(PaywayConst::PAYWAY_WXPAY, $_token, 1, 2, 1);
        } catch (\WxPayException $e) {
            return false;
        }
    }

    /**
     * 小程序支付
     * https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=7_10&index=1
     *
     * @param array $config 配置
     *
     */
    public function mpPay($config = []) {
        $_trade_type = 'MPAPI';
        $_class = new WxNotifyCallBack();
        if (!empty($config)) {
            $_class->setConf($config);
        }
        /* https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=9_1 */
//        try {
        $_token = $_class->unifiedOrder(
            $this->order_id, $this->real_amount, $this->ip, $this->product_id, $this->product_desc,
            $this->notify_url, $_trade_type, $this->open_id
        );

        return $this->clientAjax(PaywayConst::PAYWAY_WXPAYMP, $_token, 1, 2, 1);
//        } catch (\WxPayException $e) {
////            return false;
////        }
    }

    /**
     * wap H5网页支付
     * https://pay.weixin.qq.com/wiki/doc/api/H5.php?chapter=15_4
     *
     * @param array $config
     *
     * @return array|bool
     */
    public function mobilePay($config = []) {
        $_trade_type = 'MWEB';
        $_class = new WxNotifyCallBack();
        if (!empty($config)) {
            $_class->setConf($config);
        }
        try {
            /* https://pay.weixin.qq.com/wiki/doc/api/H5.php?chapter=9_1 */
            $_token = $_class->unifiedOrder(
                $this->order_id, $this->real_amount, $this->ip, $this->product_id, $this->product_name,
                $this->notify_url, $_trade_type
            );
            if (!empty($_token) && isset($_token['return_code']) && 'SUCCESS' == $_token['return_code']
                && !empty($_token['mweb_url'])
            ) {
                if (isset($_SERVER['HTTP_REFERER']) && strstr($_SERVER['HTTP_REFERER'], DOCDOMAIN) !== false) {
                    $_pay_url = $_token['mweb_url'];
                    $_ch = curl_init();
                    curl_setopt($_ch, CURLOPT_URL, $_pay_url);
                    if (strpos($_pay_url, 'https') === 0) {
                        curl_setopt($_ch, CURLOPT_SSL_VERIFYPEER, false);
                        curl_setopt($_ch, CURLOPT_SSL_VERIFYHOST, 2);
                    }
                    $_headers['CLIENT-IP'] = $_SERVER['REMOTE_ADDR'];
                    $_headers['X-FORWARDED-FOR'] = $_SERVER['REMOTE_ADDR'];
                    $_header_arr = array();
                    foreach ($_headers as $n => $v) {
                        $_header_arr[] = $n.':'.$v;
                    }
                    curl_setopt($_ch, CURLOPT_RETURNTRANSFER, 1);
                    curl_setopt($_ch, CURLOPT_HTTPHEADER, $_header_arr);  //构造IP
                    curl_setopt($_ch, CURLOPT_CONNECTTIMEOUT, 5); // 连接超时(秒)
                    //微信那边填的微信授权域
                    curl_setopt($_ch, CURLOPT_REFERER, H5MSITE);
                    curl_setopt($_ch, CURLOPT_TIMEOUT, 5); // 执行超时(秒)
                    $_out_put = curl_exec($_ch);
                    if ($_out_put === false) {
                        echo curl_error($_ch);
                        die;
                    }
                    curl_close($_ch);
                    //匹配出支付链接
                    preg_match('/weixin(.*)"/', $_out_put, $_match);
                    if (!isset($_match[1])) {
                        throw new Exception('无法获取支付链接:'.$_out_put);
                    }
                    $_client_pay_url = 'weixin'.$_match[1];
                    $_url = $_client_pay_url;
                } else {
                    $_url = $_token['mweb_url'].'&redirect_url='.urlencode($this->return_url);
                }
                /*备用调起支付url*/
                $_spare_url = $_token['mweb_url'].'&redirect_url='.urlencode($this->return_url);

                return $this->clientAjax(PaywayConst::PAYWAY_WXPAYH5, $_url, 1, 1, 1, $_spare_url);
            }

            return false;
        } catch (\WxPayException $e) {
            return false;
        }
    }

    /**
     * PC端支付
     * 返回二维码下单地址
     * https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=6_5
     *
     * @param array $config
     *
     * @return bool
     */
    public function pcPay($config = []) {
        $_trade_type = 'NATIVE';
        $_class = new WxNotifyCallBack();
        if (!empty($config)) {
            $_class->setConf($config);
        }
        try {
            $_token = $_class->unifiedOrder(
                $this->order_id, $this->real_amount, $this->ip, $this->product_id, $this->product_desc,
                $this->notify_url, $_trade_type
            );
            if (!empty($_token) && isset($_token['code_url'])) {
                $_code_url = $_token['code_url'];

                return $this->clientAjax(PaywayConst::PAYWAY_WXPAYQR, $_code_url, 1, 1, 1);
            }
        } catch (\WxPayException $e) {
            return false;
        }

        return false;
    }

    /**
     * 微信内调用微信公众号支付
     * https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=7_4
     *
     * @param array $config 配置
     *
     * @return bool
     */
    public function jsPay($config = []) {
        $_trade_type = 'JSAPI';
        $_class = new WxNotifyCallBack();
        if (!empty($config)) {
            $_class->setConf($config);
        }
        try {
            /* https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_1 */
            $_token = $_class->unifiedOrder(
                $this->order_id, $this->real_amount, $this->ip, $this->product_id, $this->product_desc,
                $this->notify_url, $_trade_type, $this->open_id
            );
            if (!empty($_token)) {
                return $this->clientAjax(PaywayConst::PAYWAY_WXPAYJS, $_token, 1, 1, 1);
            }
        } catch (\WxPayException $e) {
            return false;
        }

        return false;
    }

    /**
     * 钱包充值回调函数
     */
    public function walletNotify() {
    }

    /**
     * 游戏币充值回调
     */
    public function gmNotify() {
    }

    /*
     * 异步回调函数
     */
    public function notifyUrl($config = []) {
        $notify = new WxNotifyCallBack();
        if (!empty($config)) {
            $notify->setConf($config);
        }
        $notify->selfHandle(false, $this->order_class, $this->func);
    }

    /*
     * 返回接收页面
     */
    public function returnUrl($order_id = '') {
        $_status = 1;

        return $this->clientAjax($this->payway, '', $_status, 1, 1);
    }

    /**
     * 查询订单
     * https://pay.weixin.qq.com/wiki/doc/api/H5.php?chapter=9_2&index=2
     *
     * @access public
     *
     * @param string $order_id       商户系统内部订单号
     * @param string $transaction_id 第三方支付的订单号
     * @param null   $ext            扩展信息
     *
     * @return bool|string
     */
    public function orderQuery($order_id, $transaction_id, $ext = null) {
        $_config = get_val($ext, 'config', []);
        $_class = new WxNotifyCallBack();
        if (!empty($_config)) {
            $_class->setConf($_config);
        }
        $_rs = $_class->orderQuery($order_id, $transaction_id);

        return $_rs;
    }
}