<?php
/**
 * 支付统一入口
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2019/9/24
 * Time: 19:41
 */

/**
 * 支付统一入口
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2019/9/24
 * Time: 19:41
 */
if(file_exists(EXTEND_PATH . "Wxpay/lib/WxPay.Api.php")){
    require_once EXTEND_PATH . "Wxpay/lib/WxPay.Api.php";
}
if(file_exists(EXTEND_PATH . "Qqpay/lib/QqPay.Api.php")){
    require_once EXTEND_PATH . "Qqpay/lib/QqPay.Api.php";
}
if(file_exists(EXTEND_PATH . "Bdpay/BdPay.Config.php")){
    require_once EXTEND_PATH . "Bdpay/BdPay.Config.php";
}
if(file_exists(EXTEND_PATH . "AliSDK/AliPay.Config.php")){
    require_once EXTEND_PATH . "AliSDK/AliPay.Config.php";
}
if(file_exists(EXTEND_PATH . "Bdpay/nuomiopenplatform/library/sign/NuomiRsaSign.php")){
    require_once EXTEND_PATH . "Bdpay/nuomiopenplatform/library/sign/NuomiRsaSign.php";
}
if(file_exists(EXTEND_PATH . "AliSDK/AopClient.php")){
    require_once EXTEND_PATH . "AliSDK/AopClient.php";
}
if(file_exists(EXTEND_PATH . "AliSDK/request/AlipayTradeCreateRequest.php")){
    require_once EXTEND_PATH . "AliSDK/request/AlipayTradeCreateRequest.php";
}
if(file_exists(EXTEND_PATH . "AliSDK/request/AlipayTradePayRequest.php")){
    require_once EXTEND_PATH . "AliSDK/request/AlipayTradePayRequest.php";
}
if(file_exists(EXTEND_PATH . "AliSDK/request/AlipayTradeQueryRequest.php")){
    require_once EXTEND_PATH . "AliSDK/request/AlipayTradeQueryRequest.php";
}
if(file_exists(EXTEND_PATH . "AliSDK/request/AlipayTradeCancelRequest.php")){
    require_once EXTEND_PATH . "AliSDK/request/AlipayTradeCancelRequest.php";
}
if(file_exists(EXTEND_PATH . "AliSDK/request/AlipayTradeRefundRequest.php")){
    require_once EXTEND_PATH . "AliSDK/request/AlipayTradeRefundRequest.php";
}
if(file_exists(EXTEND_PATH . "AliSDK/request/AlipayTradeRefundRequest.php")){
    require_once EXTEND_PATH . "AliSDK/request/AlipayTradeRefundRequest.php";
}
if(file_exists(EXTEND_PATH . "Ttpay/TtPay.Config.php")){
    require_once EXTEND_PATH . "Ttpay/TtPay.Config.php";
}
if(file_exists(EXTEND_PATH . "Ttpay/TtPayClient.php")){
    require_once EXTEND_PATH . "Ttpay/TtPayClient.php";
}
if(file_exists(EXTEND_PATH . "Kspay/KsPay.Config.php")){
    require_once EXTEND_PATH . "Kspay/KsPay.Config.php";
}
if(file_exists(EXTEND_PATH . "Kspay/KsPayClient.php")){
    require_once EXTEND_PATH . "Kspay/KsPayClient.php";
}
if(file_exists(EXTEND_PATH . "AliSDK/request/AlipayTradeAppPayRequest.php")){
    require_once EXTEND_PATH . "AliSDK/request/AlipayTradeAppPayRequest.php";
}
if(file_exists(EXTEND_PATH . "AliSDK/request/AlipayTradeWapPayRequest.php")){
    require_once EXTEND_PATH . "AliSDK/request/AlipayTradeWapPayRequest.php";
}
if(file_exists(EXTEND_PATH . "AliSDK/request/AlipayTradePagePayRequest.php")){
    require_once EXTEND_PATH . "AliSDK/request/AlipayTradePagePayRequest.php";
}
if(file_exists(EXTEND_PATH . "Ybpay/lib/YopClient3.php")){
    require_once EXTEND_PATH . "Ybpay/lib/YopClient3.php";
}
if(file_exists(EXTEND_PATH . "Wechatpay/lib/Wechatpay.Transfer.Api.php")){
    require_once EXTEND_PATH . "Wechatpay/lib/Wechatpay.Transfer.Api.php";
}
if(file_exists(EXTEND_PATH . "Wechatpay/lib/Wechatpay.TransferNew.Api.php")){
    require_once EXTEND_PATH . "Wechatpay/lib/Wechatpay.TransferNew.Api.php";
}
if (file_exists(EXTEND_PATH . "Ysepay/pay/YseConfig.php")) {
    require_once EXTEND_PATH . "Ysepay/pay/YseConfig.php";
}

if (file_exists(EXTEND_PATH . "Ysepay/pay/YsePay.php")) {
    require_once EXTEND_PATH . "Ysepay/pay/YsePay.php";
}

use iyibai\services\ConfigService;
use think\facade\Db;
use think\facade\Log;

class Pay
{
    private $order_info;
    private $order_number;
    private $pay_price;
    private $total_money;
    private $mch_id;
    private $shop_id;
    private $pay_user_id;
    private $pay_platform;
    private $platform;
    private $create_time;
    private $union_pay = 0;
    private $yb_pay = 0;
    private $yse_pay = 0; //银盛支付
    private $shop_name = '';
    private $error_msg_arr = [
        'INVALID_REQUEST' => '支付参数错误',
        'NOAUTH' => '商户无此接口权限',
        'NOTENOUGH' => '余额不足',
        'ORDERPAID' => '订单已支付，请联系商家',
        'ORDERCLOSED' => '订单已关闭，请重新下单',
        'SYSTEMERROR' => '系统异常，请稍后重试',
        'APPID_NOT_EXIST' => '支付参数APPID不存在',
        'MCHID_NOT_EXIST' => '支付参数MCHID不存在',
        'APPID_MCHID_NOT_MATCH' => '微信支付商户号和小程序APPID未关联',
        'LACK_PARAMS' => '系统异常，缺少必要的请求参数',
        'OUT_TRADE_NO_USED' => '系统异常，商户订单号重复',
        'SIGNERROR' => '签名错误，请重置支付密钥',
        'XML_FORMAT_ERROR' => '系统异常，XML格式错误',
        'REQUIRE_POST_METHOD' => '系统异常，请使用post方法',
        'POST_DATA_EMPTY' => '系统异常，post数据为空',
        'NOT_UTF8' => '系统异常，编码格式错误',
    ];

    public function __construct($order_number = '')
    {
        if (!empty($order_number)) {
            $this->order_info = Db::name('sys_order')->where('order_no', $order_number)->find();
            if (empty($this->order_info)) {
                $this->order_info = Db::name('sys_order')->where('out_trade_no', $order_number)->order('id desc')->find();
                $this->pay_price = Db::name('sys_order')->where('out_trade_no', $order_number)->sum('pay_money');
                $this->total_money = 0;
            } else {
                $this->pay_price = $this->order_info['pay_money'];
                // 对于多商户多个店铺同时下单
                $this->total_money = Db::name('sys_order')->where('out_trade_no', $this->order_info['out_trade_no'])->sum('pay_money');
            }
            $this->order_number = $this->order_info['out_trade_no'];
            $this->mch_id = $this->order_info['mch_id'];
            $this->shop_id = $this->order_info['shop_id'];
            $this->pay_platform = $this->order_info['pay_type'];
            $this->platform = $this->order_info['platform'];
            $this->create_time = $this->order_info['create_time'];
            $GLOBALS['mch_id'] = $this->mch_id;
            $GLOBALS['platform'] = $this->platform;
            $systemService = new \iyibai\services\SystemService();
            if ($this->platform == 0) {
                //微信小程序银联支付
                $is_open = $systemService->getAddonsStatus($this->mch_id, 'yb_plugin_unionpayv7');
                if ($is_open != 0) {
                    $this->union_pay = 1;
                }
            }
            if ($this->platform == 0 || $this->platform == 4) {
                //微信小程序易宝支付
                $is_open = $systemService->getAddonsStatus($this->mch_id, 'yb_plugin_ybpayv7');
                if ($is_open != 0) {
                    $this->yb_pay = 1;
                }
            }
            if ($this->platform == 0 || $this->platform == 4) {
                //微信小程序银盛支付
                $is_open = $systemService->getAddonsStatus($this->mch_id, 'yb_plugin_yse_payv7');
                if ($is_open != 0) {
                    $this->yse_pay = 1;
                }
            }
            //店铺名称
            $about_info = ConfigService::getConfigValue('site_about', $this->mch_id);
            $this->shop_name = !empty($about_info['name']) ? $about_info['name'] : '';
        }
        //支付用户
        if (!empty($this->order_info)) {
            $this->pay_user_id = empty($this->order_info['sub_buyer_id']) ? $this->order_info['buyer_id'] : $this->order_info['sub_buyer_id'];
        }

        /*if (isset($this->order_info['is_help_pay'])) {
            if ($this->order_info['is_help_pay'] == 1) {
                //代付
                $help_pay_order = Db::name('help_pay_order')->where('order_id', $this->order_info['id'])->find();
                $this->pay_user_id = empty($help_pay_order['sub_user_id']) ? $help_pay_order['user_id'] : $help_pay_order['sub_user_id'];
            }
        }*/
    }

    /**
     * 生成订单外部交易订单号
     * @return string
     */
    private function createOrderNo()
    {
        $no = time() . rand(111, 999);
        return $no;
    }

    /**
     * 微信支付
     * @param string $body
     * @param $pay_type 1/小程序支付 2/公众号 3/H5支付
     * @return array
     * @throws WxPayException
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function Wxpay($body = '', $pay_type = 1, $return_url = '')
    {
        $rs = array('code' => 200, 'info' => array(), 'msg' => '');
        if (empty($this->order_info)) {
            $rs['code'] = 0;
            $rs['msg'] = '订单不存在';
            return $rs;
        }
        if ($this->platform != 10) {
            if ($this->union_pay == 1) {
                //微信银联支付
                $rs = $this->UnionPay($body, $pay_type);
                return $rs;
            }
            if ($this->yb_pay == 1) {
                //微信易宝支付
                $rs = $this->YbPay($body, $pay_type);
                return $rs;
            }
            if ($this->yse_pay == 1) {
                $YsfApiService = new \addons\yse_pay\service\YsfApiService($this->mch_id, $pay_type, $this->platform);
                $YsfApiService->appIdAddOrUpdate();
                //微信易宝支付
                $rs = $this->YsePay($body, $pay_type);
                Log::write('cccc' . json_encode($rs, JSON_UNESCAPED_UNICODE));
                return $rs;
            }
        }

        $user = Db::name('sys_user')->where('id', $this->pay_user_id)->find();
        $GLOBALS['pay_type'] = $pay_type;
        $attach['mch_id'] = $this->mch_id;
        $attach['pay_type'] = $pay_type;
        $attach['platform'] = $this->platform;

        // body长度不能超127，规则：店名-销售商品类目
        $order_goods = Db::name('sys_order_goods')
            ->field('goods_name')
            ->where(['sys_order_id' => $this->order_info['id']])
            ->select()->toArray();

        if (empty($order_goods)) {
            if ($pay_type == 1) {
                $body = "微信小程序支付";
            } elseif ($pay_type == 2) {
                $body = "微信公众号支付";
            } elseif ($pay_type == 3) {
                $body = "微信H5支付";
            } elseif ($pay_type == 4) {
                $body = "微信APP支付";
            }
        } else {
            // 商品名称处理
            $good_name = '';
            foreach ($order_goods as $k => $v) {
                if ($k == 0) {
                    $good_name = $good_name . $v['goods_name'];
                } else {
                    $good_name = $good_name . ',' . $v['goods_name'];
                }
            }
            $body = $this->shop_name . '-' . $good_name;
            // body长度不能超127
            $body = mb_strlen($body, 'UTF8') > 40 ? mb_substr($body, 0, 40, 'utf-8') . '等' : $body;
        }

        /*if (empty($this->shop_name)) {
            if ($pay_type == 1) {
                $body = "微信小程序支付";
            } elseif ($pay_type == 2) {
                $body = "微信公众号支付";
            } elseif ($pay_type == 3) {
                $body = "微信H5支付";
            } elseif ($pay_type == 4) {
                $body = "微信APP支付";
            }
        } else {
            $body = $this->shop_name;
        }*/

        //初始化值对象
        $input = new \WxPayUnifiedOrder();
        $input->SetBody($body);
        $input->SetDetail($body);
        $input->SetTotal_fee($this->pay_price * 100);
        $input->SetOut_trade_no($this->order_number);
        //商品标签
        $goods_tag = $this->GetPayGoodsTag();
        if (!empty($goods_tag)) {
            $input->SetGoods_tag($goods_tag);
        }
        if ($pay_type == 1 || $pay_type == 2) {
            $input->SetOpenid($user['openid']);
            $input->SetTrade_type("JSAPI");
        } elseif ($pay_type == 3) {
            $spbill_create_ip = get_client_ip($type = 0, $adv = true);
            $input->SetSpbill_create_ip($spbill_create_ip);//终端ip
            $input->SetTrade_type("MWEB");
            $input->SetScene_info('{"h5_info": {"type":"Wap","wap_url": "","wap_name": ""}}');
        } elseif ($pay_type == 4) {
            $input->SetTrade_type("APP");
        } elseif ($pay_type == 5) {
            $input->SetProduct_id($this->order_info['out_trade_no']);
            $input->SetTrade_type("NATIVE");
        }
        $input->SetAttach(json_encode($attach));
        // 向微信统一下单，并返回 unifiedorder，它是一个array数组1
        $unifiedorder = \WxPayApi::unifiedOrder($input);
        //下单错误
        if ($unifiedorder['return_code'] == "FAIL") {
            $rs['code'] = 0;
            $rs['msg'] = $unifiedorder['return_msg'] == '签名错误' ? '签名错误，请重置支付密钥' : $unifiedorder['return_msg'];
            return $rs;
        }
        if ($unifiedorder['result_code'] == "FAIL") {
            $rs['code'] = 0;
            $rs['msg'] = isset($this->error_msg_arr[$unifiedorder['err_code']]) ? $this->error_msg_arr[$unifiedorder['err_code']] : $unifiedorder['err_code_des'];
            return $rs;
        }
        if ($pay_type == 1 || $pay_type == 2) {
            $parameters = \WxPayApi::getJsApiParameters($unifiedorder);
        } elseif ($pay_type == 3) {
            if (!empty($return_url)) {
                $unifiedorder['mweb_url'] = $unifiedorder['mweb_url'] . '&redirect_url=' . urlencode($return_url);
                $unifiedorder['pay_type'] = $this->pay_platform;
            }
            $parameters = $unifiedorder;
        } elseif ($pay_type == 4) {
            $parameters = \WxPayApi::getAppParameters($unifiedorder);
        } elseif ($pay_type == 5) {
            $qrcode = new \QrCode\QRcode();
            $parameters = $qrcode::dataImgBase64($unifiedorder['code_url'], QR_ECLEVEL_L, 8);
        }
        $rs['info'] = $parameters;
        return $rs;
    }

    /**
     * 微信商户号活动标签
     * @return string
     */
    private function GetPayGoodsTag()
    {
        $goods_tag = '';
        $order_type = substr($this->order_number, 0, 1);
        if ($order_type == 'P' || $order_type == 'S' || $order_type == 'B' || $order_type == 'G' || $order_type == 'I') {
            //普通、秒杀、砍价、拼团、积分订单
            if ($this->order_info['order_type'] == 'normal') {
                if ($this->order_info['order_goods_type'] == 'normal') {
                    $goods_tag = 'GOODS';
                } elseif ($this->order_info['order_goods_type'] == 'electron_coupon') {
                    $goods_tag = 'ELECTRONIC';
                } elseif ($this->order_info['order_goods_type'] == 3 || $this->order_info['order_goods_type'] == 4) {
                    $goods_tag = 'KNOWLEDGE';
                } elseif ($this->order_info['order_goods_type'] == 5) {
                    $goods_tag = 'HOTEL';
                }
            } elseif ($this->order_info['order_type'] == 'activity_bargain') {
                $goods_tag = 'BARGAIN';
            } elseif ($this->order_info['order_type'] == 'activity_seckill') {
                $goods_tag = 'SECKILL';
            } elseif ($this->order_info['order_type'] == 'activity_group') {
                $goods_tag = 'GROUP';
            } elseif ($this->order_info['order_type'] == 'activity_integralmall') {
                $goods_tag = 'INTEGRAL';
            }
        } elseif ($order_type == 'Y') {
            //预约订单
            $goods_tag = 'SERVICES';
        } elseif ($order_type == 'C') {
            //储值订单
            $goods_tag = 'CHARGE';
        } elseif ($order_type == 'F') {
            //表单订单
            $goods_tag = 'FORM';
        }
        return $goods_tag;
    }

    /**
     * 银联支付
     * @param string $body
     * @param $pay_type 1/小程序支付 2/公众号 3/H5支付
     * @return array
     * @throws WxPayException
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function UnionPay($body = '', $pay_type)
    {
        $rs = array('code' => 200, 'info' => array(), 'msg' => '');
        if (empty($this->order_info)) {
            $rs['code'] = 0;
            $rs['msg'] = '订单不存在';
            return $rs;
        }
        $user = Db::name('sys_user')->where('id', $this->pay_user_id)->find();
        $GLOBALS['pay_type'] = $pay_type;
        $attach['mch_id'] = $this->mch_id;
        $attach['pay_type'] = $pay_type;
        $attach['platform'] = $this->platform;
        if ($pay_type == 1) {
            $body = "微信小程序银联支付" . $body;
        } elseif ($pay_type == 2) {
            $body = "微信公众号银联支付" . $body;
        }
        //初始化值对象
        $input = new \WxPayUnionUnifiedOrder();
        $input->SetBody($body);
        $input->SetTotal_fee($this->pay_price * 100);
        $input->SetOut_trade_no($this->order_number);
        $input->SetSub_Openid($user['openid']);
        if ($pay_type == 1) {
            $input->SetIs_minipg("1");
        }
        $input->SetAttach(json_encode($attach));
        // 向微信统一下单，并返回 unifiedorder，它是一个array数组1
        $unifiedorder = \WxPayApi::unionUnifiedOrder($input);

        //下单错误
        if ($unifiedorder['status'] != "0") {
            $rs['code'] = 0;
            $rs['msg'] = $unifiedorder['message'];
            return $rs;
        }
        if ($unifiedorder['result_code'] != "0") {
            $rs['code'] = 0;
            $rs['msg'] = $unifiedorder['err_msg'];
            return $rs;
        }
        $parameters = json_decode($unifiedorder['pay_info'], true);
        unset($parameters['status']);
        unset($parameters['callback_url']);
        $rs['info'] = $parameters;
        return $rs;
    }

    /**
     * 易宝支付
     * @param string $body
     * @param $pay_type 1/小程序支付 2/公众号 3/H5支付
     * @return array
     * @throws WxPayException
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function YbPay($body = '', $pay_type)
    {
        $rs = array('code' => 200, 'info' => array(), 'msg' => '');
        if (empty($this->order_info)) {
            $rs['code'] = 0;
            $rs['msg'] = '订单不存在';
            return $rs;
        }
        $user = Db::name('sys_user')->where('id', $this->pay_user_id)->find();
        $GLOBALS['pay_type'] = $pay_type;
        $attach['mch_id'] = $this->mch_id;
        $attach['pay_type'] = $pay_type;
        $attach['platform'] = $this->platform;
        if ($pay_type == 1) {
            $input['payTool'] = 'MINI_PROGRAM';
            $body = "微信小程序易宝支付" . $body;
        } elseif ($pay_type == 2) {
            $input['payTool'] = 'WECHAT_OPENID';
            $body = "微信公众号易宝支付" . $body;
        }
        $input['orderId'] = $this->order_number;
        $input['orderAmount'] = $this->pay_price;
        $input['openId'] = $user['openid'];
        $input['payType'] = 'WECHAT';
        $goodsParamExt['goodsName'] = $body;
        $goodsParamExt['goodsDesc'] = '';
        $input['goodsParamExt'] = json_encode($goodsParamExt, true);
        $yopClient3 = new \YopClient3();
        $unifiedorder = $yopClient3->sendApiOrder($input);
        //下单错误
        if ($unifiedorder['state'] == "FAILURE") {
            $rs['code'] = 0;
            $rs['msg'] = $unifiedorder['error']['message'];
            return $rs;
        }
        if ($unifiedorder['state'] == "SUCCESS" && $unifiedorder['result']['code'] != "CAS00000") {
            $rs['code'] = 0;
            $rs['msg'] = $unifiedorder['result']['message'];
            return $rs;
        }
        $parameters = json_decode($unifiedorder['result']['resultData'], true);
        $rs['info'] = $parameters;
        return $rs;
    }
    /**
     * 银盛支付
     * @param string $body
     * @param $pay_type 1/小程序支付 2/公众号 3/H5支付
     * @return array
     * @throws WxPayException
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function YsePay($body = '', $pay_type)
    {
        $rs = array('code' => 200, 'info' => array(), 'msg' => '');
        if (empty($this->order_info)) {
            $rs['code'] = 0;
            $rs['msg'] = '订单不存在';
            return $rs;
        }
        $user = Db::name('sys_user')->where('id', $this->pay_user_id)->find();
        $GLOBALS['pay_type'] = $pay_type;
        $input['out_trade_no'] = $this->order_info['out_trade_no'];
        $input['total_amount'] = $this->pay_price;
        $input['yse_pay_setting'] = isset($this->order_info['extend']['yse_pay_setting']) ? $this->order_info['extend']['yse_pay_setting'] : [];
        $input['sub_openid'] = $user['openid'];
        $ysePay = new \YsePay();
        $unifiedorder = [];
        if ($this->order_info['platform'] == 0) {
            $unifiedorder = $ysePay->wxminipg_pay($input);
        } elseif ($this->order_info['platform'] == 5) {
            $unifiedorder = $ysePay->wxPublic_pay($input);
        }
        Log::write('银盛支付返回结果',json_encode($unifiedorder,true));
        if ($unifiedorder['code'] == 0) {
            $rs['code'] = 0;
            $rs['msg'] = $unifiedorder['msg'];
            return $rs;
        }

        $rs['info'] = isset($unifiedorder['data']['jsapi_pay_info']) ? json_decode($unifiedorder['data']['jsapi_pay_info'], true) : [];
        return $rs;
    }
    /**
     * QQ支付
     * @param string $body
     * @return array
     * @throws QqPayException
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function Qqpay($body = '', $return_url = '')
    {
        $rs = array('code' => 200, 'info' => array(), 'msg' => '');
        if (empty($this->order_info)) {
            $rs['code'] = 0;
            $rs['msg'] = '订单不存在';
            return $rs;
        }
        //$user = Db::name('sys_user')->where('id', $this->order_info['user_id'])->find();
        $GLOBALS['pay_type'] = $this->pay_platform;
        $attach['mch_id'] = $this->mch_id;
        $attach['pay_type'] = $this->pay_platform;
        //初始化值对象
        $input = new \QqPayUnifiedOrder();
        $input->SetBody('QQ支付' . $body);
        $input->SetTotal_fee($this->pay_price * 100);
        $input->SetOut_trade_no($this->order_number);
        $input->SetAttach(json_encode($attach));
        if ($this->pay_platform == 6) {
            //QQ钱包支付
            $input->SetTrade_type("MINIAPP");
            $unifiedorder = \QqPayApi::unifiedOrder($input);
        } elseif ($this->pay_platform == 0) {
            //QQ微信支付
            $spbill_create_ip = get_client_ip($type = 0, $adv = true);
            $input->SetSpbill_create_ip($spbill_create_ip);//终端ip
            $input->SetTrade_type("MWEB");
            $input->SetScene_info('{"h5_info": {"type":"Wap","wap_url": "","wap_name": ""}}');
            $unifiedorder = \QqPayApi::unifiedOrderWx($input);
        }
        // 向微信统一下单，并返回 unifiedorder，它是一个array数组1
        //下单错误
        if ($unifiedorder['return_code'] == "FAIL") {
            $rs['code'] = 0;
            $rs['msg'] = $unifiedorder['return_msg'];
            return $rs;
        }
        if ($unifiedorder['result_code'] == "FAIL") {
            $rs['code'] = 0;
            $rs['msg'] = $unifiedorder['err_code_des'];
            return $rs;
        }
        if ($this->pay_platform == 6) {
            $parameters = \QqPayApi::getJsApiParameters($unifiedorder);
        } elseif ($this->pay_platform == 0) {
            if (!empty($return_url)) {
                $unifiedorder['mweb_url'] = $unifiedorder['mweb_url'] . '&redirect_url=' . urlencode($return_url);
            }
            $unifiedorder['referer'] = get_localhost_domain(false, true);
            $parameters = $unifiedorder;
        }

        $rs['info'] = $parameters;
        return $rs;
    }

    /**
     * QQ订单查询
     * @param string $refund_desc
     * @param $pay_type
     * @return array
     * @throws WxPayException
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function Qqquery()
    {
        $rs = array('code' => 200, 'info' => array(), 'msg' => '');
        if ($this->pay_platform == 6) {
            $rs['code'] = 0;
            $rs['msg'] = 'QQ支付暂不支持查询';
            return $rs;
        }
        if (empty($this->order_info)) {
            $rs['code'] = 0;
            $rs['msg'] = '订单不存在';
            return $rs;
        }
        $GLOBALS['pay_type'] = $this->pay_platform;
        //初始化值对象
        $input = new \QqPayOrderQuery();
        $input->SetOut_trade_no($this->order_number);
        // 向微信统一下单，并返回 unifiedorder，它是一个array数组1
        $queryorder = \QqPayApi::orderQueryWx($input);
        //下单错误
        if ($queryorder['return_code'] == "FAIL") {
            $rs['code'] = 0;
            $rs['msg'] = $queryorder['return_msg'];
            return $rs;
        }
        if ($queryorder['result_code'] == "FAIL") {
            $rs['code'] = 0;
            $rs['msg'] = $queryorder['err_code_des'];
            return $rs;
        }
        if ($queryorder['trade_state'] != "SUCCESS") {
            $rs['code'] = 0;
            $rs['msg'] = $queryorder['trade_state_desc'];
            return $rs;
        }
        $rs['info'] = $queryorder;
        return $rs;
    }

    /**
     * 百度地址
     * @param string $dealTitle
     * @return array
     * @throws Exception
     */
    public function Bdpay($dealTitle = '')
    {
        $rs = array('code' => 200, 'info' => array(), 'msg' => '');
        $config = new \BbPayConfig();
        $signParammeters = array(
            'dealId' => $config->GetDealId(),
            'appKey' => $config->GetAppKey(),
            'tpOrderId' => $this->order_number,
            'totalAmount' => $this->pay_price * 100
        );
        //生成签名
        $sign = \NuomiRsaSign::genSignWithRsa($signParammeters, $config->GetPrivateKey());
        $signParammeters['sign'] = $sign;
        //验证签名
        $checkSign = \NuomiRsaSign::checkSignWithRsa($signParammeters, $config->GetPublicKey());
        if (!$checkSign) {
            $rs['code'] = 0;
            $rs['msg'] = '签名验证错误';
            return $rs;
        }
        $bizInfo = array(
            'tpData' => array(
                'dealId' => $config->GetDealId(),
                'appKey' => $config->GetAppKey(),
                'tpOrderId' => $this->order_number,
                'totalAmount' => $this->pay_price * 100,
                'rsaSign' => $signParammeters['sign'],
                'returnData' => array(
                    'mch_id' => $this->mch_id
                )
            )
        );
        $parammeters = array(
            'dealId' => $config->GetDealId(),
            'appKey' => $config->GetAppKey(),
            'tpOrderId' => $this->order_number,
            'totalAmount' => $this->pay_price * 100,
            'dealTitle' => '百度支付' . $dealTitle,
            'signFieldsRange' => '1',
            'rsaSign' => $signParammeters['sign'],
            'bizInfo' => json_encode($bizInfo)
        );
        $rs['info'] = $parammeters;
        return $rs;
    }

    /**
     * 支付宝支付
     * @param string $subject
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function Alipay($subject = '')
    {
        $rs = array('code' => 200, 'info' => array(), 'msg' => '');
        $user = Db::name('sys_user')->where('id', $this->pay_user_id)->find();
        $GLOBALS['pay_type'] = 1;
        $body['mch_id'] = $this->mch_id;
        $body['pay_type'] = 1;
        $body['platform'] = $this->platform;
        $config = new \AliPayConfig();
        $aopClient = new \AopClient();
        $aopClient->appId = $config->GetAppId();
        $aopClient->rsaPrivateKey = $config->GetPrivateKey();
        $aopClient->alipayrsaPublicKey = $config->GetPublicKey();
        $aopClient->signType = $config->GetSignType();
        $request = new \AlipayTradeCreateRequest ();
        $request->setNotifyUrl($config->GetNotifyUrl());
        $extend_params = [];
        if ($this->order_info['order_goods_type'] == 7) {
            $extend_params['food_order_type'] = 'qr_order';
        }
        $biz_content = array(
            'out_trade_no' => $this->order_number,
            'total_amount' => $this->pay_price,
            'subject' => '支付宝支付' . $subject,
            'body' => json_encode($body),
            'buyer_id' => $user['unionid'],
        );
        if (!empty($extend_params)) {
            $biz_content['extend_params'] = $extend_params;
        }
        $request->setBizContent(json_encode($biz_content));
        $response = $aopClient->execute($request);
        $response = json_decode(json_encode($response, true), true);
        if ($response['alipay_trade_create_response']['code'] == '10000') {
            $rs['info'] = $response['alipay_trade_create_response']['trade_no'];
            return $rs;
        } else {
            $rs['code'] = 0;
            $rs['msg'] = json_encode($response['alipay_trade_create_response'], JSON_UNESCAPED_UNICODE);
            return $rs;
        }
    }

    /**
     * 头条支付
     * @param string $subject
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function Ttpay($subject = '')
    {
        $rs = array('code' => 200, 'info' => array(), 'msg' => '');
        $ttConfig = new \TtPayConfig();
        if ($ttConfig->GetIsOpenGuaranteePay() == 1) {
            //担保支付
            $data['out_order_no'] = $this->order_number;
            $data['total_amount'] = $this->pay_price * 100;
            $data['subject'] = '头条支付' . $subject;
            $data['body'] = '头条支付' . $subject;
            $cp_extra['mch_id'] = $this->mch_id;
            $data['cp_extra'] = json_encode($cp_extra, true);
            $ttPayClient = new \TtPayClient();
            $response = $ttPayClient->createOrder($data, $ttConfig);
            if ($response['err_no'] != 0) {
                $rs['code'] = 0;
                $rs['msg'] = $response['err_tips'];
                return $rs;
            }
            $pay['orderInfo'] = $response['data'];
            $pay['service'] = 5;
            $rs['info'] = $pay;
            return $rs;
        } else {
            $user = Db::name('sys_user')->where('id', $this->pay_user_id)->find();
            //收银台支付
            $data['merchant_id'] = $ttConfig->GetMerchantId();
            $data['app_id'] = $ttConfig->GetAppId();
            $data['sign_type'] = $ttConfig->GetSignType();
            $data['timestamp'] = time() . '';
            $data['version'] = '2.0';
            $data['trade_type'] = 'H5';
            $data['product_code'] = 'pay';
            $data['payment_type'] = 'direct';
            $data['out_order_no'] = $this->order_number;
            $data['uid'] = $user['openid'];
            $data['total_amount'] = $this->pay_price * 100;
            $data['currency'] = 'CNY';
            $data['subject'] = '头条支付' . $subject;
            $data['body'] = '头条支付' . $subject;
            $data['trade_time'] = $this->create_time . '';
            $data['valid_time'] = '6000';
            $data['notify_url'] = get_localhost_domain(false, true);
            if ($this->pay_platform == 0) {
                /*微信支付*/
                $data['wx_type'] = 'MWEB';
                $wx_res = $this->Wxpay('头条', 3);
                if ($wx_res['code'] == 200) {
                    $data['wx_url'] = $wx_res['info']['mweb_url'];
                    $data['alipay_url'] = '';
                } else {
                    return $wx_res;
                }
            } elseif ($this->pay_platform == 2) {
                /*支付宝支付*/
                $GLOBALS['pay_type'] = 2;
                $body['mch_id'] = $this->mch_id;
                $body['pay_type'] = 2;
                $body['platform'] = $this->platform;
                $aliConfig = new \AliPayConfig();
                $aopClient = new \AopClient();
                $aopClient->appId = $aliConfig->GetAppId();
                $aopClient->rsaPrivateKey = $aliConfig->GetPrivateKey();
                $aopClient->alipayrsaPublicKey = $aliConfig->GetPublicKey();
                $aopClient->signType = $aliConfig->GetSignType();
                $request = new \AlipayTradeAppPayRequest();
                $request->setNotifyUrl($aliConfig->GetNotifyUrl());
                $biz_content = array(
                    'body' => json_encode($body),
                    'subject' => '头条支付' . $subject,
                    'out_trade_no' => $this->order_number,
                    'total_amount' => $this->pay_price,
                    'product_code' => 'QUICK_MSECURITY_PAY',
                );
                $request->setBizContent(json_encode($biz_content));
                $response = $aopClient->sdkExecute($request);
                $data['wx_url'] = '';
                $data['alipay_url'] = $response;
            }
            ksort($data);
            $signStr = '';
            foreach ($data as $key => $value) {
                if (empty($value)) {
                    continue;
                }
                $signStr .= $key . '=' . $value . '&';
            }
            $signStr = trim($signStr, '&');
            $data['sign'] = md5($signStr . $ttConfig->GetSecret());
            $data["risk_info"] = json_encode(['ip' => get_client_ip(0, true)]);
            $pay['orderInfo'] = $data;
            $pay['service'] = $this->pay_platform == 0 ? 3 : 4;
            $rs['info'] = $pay;
            return $rs;
        }
    }

    /**
     * 快手支付
     * @param string $subject
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function Kspay($subject = '')
    {
        $rs = array('code' => 200, 'info' => array(), 'msg' => '');
        //$ksConfig = new \KsPayConfig();
        $user = Db::name('sys_user')->where('id', $this->pay_user_id)->find();
        //担保支付
        $data['out_order_no'] = $this->order_number;
        $data['open_id'] = $user['openid'];
        $data['total_amount'] = $this->pay_price * 100;
        $data['subject'] = '快手支付' . $subject;
        $data['detail'] = '快手支付' . $subject;
        $attach['mch_id'] = $this->mch_id;
        $data['attach'] = json_encode($attach, true);
        $ksPayClient = new \KsPayClient();
        $response = $ksPayClient->createOrder($data);
        if ($response['result'] != 1) {
            $rs['code'] = 0;
            $rs['msg'] = $response['error_msg'];
            return $rs;
        }
        $pay['serviceId'] = '1';
        $pay['orderInfo'] = $response['order_info'];
        $rs['info'] = $pay;
        return $rs;
    }

    /**
     * 手机WAP支付
     * @param string $subject
     * @param $return_url
     * @return array
     * @throws WxPayException
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function WapPay($subject = '', $return_url)
    {
        $rs = array('code' => 200, 'info' => array(), 'msg' => '');
        if ($this->pay_platform == 0) {
            /*微信支付*/
            $wx_res = $this->Wxpay('手机WAP支付', 3, $return_url);
            return $wx_res;
        } elseif ($this->pay_platform == 2) {
            /*支付宝支付*/
            $GLOBALS['pay_type'] = 3;
            $body['mch_id'] = $this->mch_id;
            $body['pay_type'] = 3;
            $body['platform'] = $this->platform;
            $aliConfig = new \AliPayConfig();
            $aopClient = new \AopClient();
            $aopClient->appId = $aliConfig->GetAppId();
            $aopClient->rsaPrivateKey = $aliConfig->GetPrivateKey();
            $aopClient->alipayrsaPublicKey = $aliConfig->GetPublicKey();
            $aopClient->signType = $aliConfig->GetSignType();
            $request = new \AlipayTradeWapPayRequest();
            $request->setNotifyUrl($aliConfig->GetNotifyUrl());
            $request->setReturnUrl($return_url);
            $biz_content = array(
                'body' => json_encode($body),
                'subject' => '手机WAP支付' . $subject,
                'out_trade_no' => $this->order_number,
                'total_amount' => $this->pay_price,
                'product_code' => 'QUICK_WAP_WAY',
            );
            $request->setBizContent(json_encode($biz_content));
            $response = $aopClient->pageExecute($request);
            $info['pay_content'] = $response;
            $info['pay_type'] = $this->pay_platform;
            $rs['info'] = $info;
            return $rs;
        }
    }

    /**
     * 手机App支付
     * @param string $subject
     * @param $return_url
     * @return array
     * @throws WxPayException
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function AppPay($subject = '')
    {
        $rs = array('code' => 200, 'info' => array(), 'msg' => '');
        if ($this->pay_platform == 0) {
            /*微信支付*/
            $wx_res = $this->Wxpay('手机APP支付', 4);
            return $wx_res;
        } elseif ($this->pay_platform == 2) {
            /*支付宝支付*/
            $GLOBALS['pay_type'] = 2;
            $body['mch_id'] = $this->mch_id;
            $body['pay_type'] = 2;
            $body['platform'] = $this->platform;
            $aliConfig = new \AliPayConfig();
            $aopClient = new \AopClient();
            $aopClient->appId = $aliConfig->GetAppId();
            $aopClient->rsaPrivateKey = $aliConfig->GetPrivateKey();
            $aopClient->alipayrsaPublicKey = $aliConfig->GetPublicKey();
            $aopClient->signType = $aliConfig->GetSignType();
            $request = new \AlipayTradeAppPayRequest ();
            $request->setNotifyUrl($aliConfig->GetNotifyUrl());
            $biz_content = array(
                'body' => json_encode($body),
                'subject' => 'APP支付' . $subject,
                'out_trade_no' => $this->order_number,
                'total_amount' => $this->pay_price,
                'product_code' => 'QUICK_MSECURITY_PAY',
            );
            $request->setBizContent(json_encode($biz_content));
            $response = $aopClient->sdkExecute($request);
            //$data['alipay_url'] = $response;
            $rs['info'] = $response;
            return $rs;
        }
    }

    /**
     * 当面付支付
     * @param string $body
     * @return array
     * @throws WxPayException
     */
    public function MicroPay($body = '')
    {
        $rs = array('code' => 200, 'info' => array(), 'msg' => '');
        if (empty($this->order_info)) {
            $rs['code'] = 0;
            $rs['msg'] = '订单不存在';
            return $rs;
        }
        if ($this->pay_platform == 0) {
            /*微信支付*/
            $GLOBALS['pay_type'] = 6;
            $attach['mch_id'] = $this->mch_id;
            $attach['pay_type'] = 6;
            $attach['platform'] = $this->platform;
            if (empty($this->shop_name)) {
                $body = "微信当面付";
            } else {
                $body = $this->shop_name;
            }
            //初始化值对象
            $input = new \WxPayMicroPay();
            $input->SetAuth_code($this->order_info['auth_code']);
            $input->SetBody($body);
            $input->SetDetail($body);
            $input->SetTotal_fee($this->pay_price * 100);
            $input->SetOut_trade_no($this->order_number);
            //商品标签
            $goods_tag = $this->GetPayGoodsTag();
            if (!empty($goods_tag)) {
                $input->SetGoods_tag($goods_tag);
            }
            $input->SetAttach(json_encode($attach));
            // 向微信统一下单，并返回 unifiedorder，它是一个array数组1
            $unifiedorder = \WxPayApi::micropay($input);
            //exit(json_encode($unifiedorder));
            //下单错误
            if ($unifiedorder['return_code'] == "FAIL") {
                $rs['code'] = 0;
                $rs['msg'] = $unifiedorder['return_msg'] == '签名错误' ? '签名错误，请重置支付密钥' : $unifiedorder['return_msg'];
                return $rs;
            }
            if ($unifiedorder['result_code'] == "FAIL") {
                $rs['code'] = 0;
                $rs['msg'] = isset($this->error_msg_arr[$unifiedorder['err_code']]) ? $this->error_msg_arr[$unifiedorder['err_code']] : $unifiedorder['err_code_des'];
                return $rs;
            }
            $rs['info'] = $unifiedorder;
            return $rs;
        } elseif ($this->pay_platform == 2) {
            //支付宝
            $rs = array('code' => 200, 'info' => array(), 'msg' => '');
            if (empty($this->shop_name)) {
                $subject = "微信当面付";
            } else {
                $subject = $this->shop_name;
            }
            $GLOBALS['pay_type'] = 6;
            $body['mch_id'] = $this->mch_id;
            $body['pay_type'] = 6;
            $body['platform'] = $this->platform;
            $config = new \AliPayConfig();
            $aopClient = new \AopClient();
            $aopClient->appId = $config->GetAppId();
            $aopClient->rsaPrivateKey = $config->GetPrivateKey();
            $aopClient->alipayrsaPublicKey = $config->GetPublicKey();
            $aopClient->signType = $config->GetSignType();
            $request = new \AlipayTradePayRequest();
            $request->setNotifyUrl($config->GetNotifyUrl());
            $extend_params = [];
            if ($this->order_info['order_goods_type'] == 7) {
                $extend_params['sys_service_provider_id'] = 'qr_order';
            }
            $biz_content = array(
                'out_trade_no' => $this->order_number,
                'total_amount' => $this->pay_price,
                'auth_code' => $this->order_info['auth_code'],
                'subject' => '支付宝支付' . $subject,
                'body' => json_encode($body),
                'scene' => 'bar_code'
            );
            if (!empty($extend_params)) {
                $biz_content['extend_params'] = $extend_params;
            }
            $request->setBizContent(json_encode($biz_content));
            $response = $aopClient->execute($request);
            $response = json_decode(json_encode($response, true), true);
            $rs['info'] = $response;
            if ($response['alipay_trade_pay_response']['code'] == '10000') {
                return $rs;
            } else {
                $rs['code'] = 0;
                $rs['msg'] = json_encode($response['alipay_trade_pay_response'], JSON_UNESCAPED_UNICODE);
                return $rs;
            }
        }
    }

    /**
     * 当面付撤销支付
     * @param string $body
     * @return array
     * @throws WxPayException
     */
    public function MicroReverse($body = '')
    {
        $rs = array('code' => 200, 'info' => array(), 'msg' => '');
        if (empty($this->order_info)) {
            $rs['code'] = 0;
            $rs['msg'] = '订单不存在';
            return $rs;
        }
        if ($this->pay_platform == 0) {
            /*微信支付*/
            $GLOBALS['pay_type'] = 6;
            //初始化值对象
            $input = new \WxPayReverse();
            $input->SetOut_trade_no($this->order_number);
            // 向微信统一下单，并返回 unifiedorder，它是一个array数组1
            $reverseorder = \WxPayApi::reverse($input);
            $rs['info'] = $reverseorder;
            //下单错误
            if ($reverseorder['return_code'] == "FAIL") {
                $rs['code'] = 0;
                $rs['msg'] = $reverseorder['return_msg'] == '签名错误' ? '签名错误，请重置支付密钥' : $reverseorder['return_msg'];
                return $rs;
            }
            if ($reverseorder['result_code'] == "FAIL") {
                $rs['code'] = 0;
                $rs['msg'] = isset($this->error_msg_arr[$reverseorder['err_code']]) ? $this->error_msg_arr[$reverseorder['err_code']] : $reverseorder['err_code_des'];
                return $rs;
            }
            return $rs;
        } elseif ($this->pay_platform == 2) {
            //支付宝
            $GLOBALS['pay_type'] = 6;
            $config = new \AliPayConfig();
            $aopClient = new \AopClient();
            $aopClient->appId = $config->GetAppId();
            $aopClient->rsaPrivateKey = $config->GetPrivateKey();
            $aopClient->alipayrsaPublicKey = $config->GetPublicKey();
            $aopClient->signType = $config->GetSignType();
            $request = new \AlipayTradeCancelRequest();
            $biz_content = array(
                'out_trade_no' => $this->order_number,
            );
            $request->setBizContent(json_encode($biz_content));
            $response = $aopClient->execute($request);
            $response = json_decode(json_encode($response, true), true);
            $rs['info'] = $response;
            if ($response['alipay_trade_cancel_response']['code'] == '10000') {
                return $rs;
            } else {
                $rs['code'] = 0;
                $rs['msg'] = json_encode($response['alipay_trade_cancel_response'], JSON_UNESCAPED_UNICODE);
                return $rs;
            }
        }
    }

    /**
     * 微信退款
     * @param string $refund_desc
     * @param $pay_type
     * @return array
     * @throws WxPayException
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function Wxrefund($refund_desc = '', $pay_type)
    {
        $rs = array('code' => 200, 'info' => array(), 'msg' => '');

        if (empty($this->order_info)) {
            $rs['code'] = 0;
            $rs['msg'] = '订单不存在';
            return $rs;
        }
        if ($this->union_pay == 1) {
            //微信银联退款
            $rs = $this->UnionRefund($refund_desc, $pay_type);
            return $rs;
        }
        if ($this->yb_pay == 1) {
            //微信易宝退款
            $rs = $this->YbRefund($refund_desc, $pay_type);
            return $rs;
        }
        if ($this->yse_pay == 1) {
            //微信易宝退款
            $rs = $this->YseRefund($refund_desc, $pay_type);
            return $rs;
        }
        $GLOBALS['pay_type'] = $pay_type;
        if ($pay_type == 1) {
            $refund_desc = "微信小程序退款" . $refund_desc;
        } elseif ($pay_type == 2) {
            $refund_desc = "微信公众号退款" . $refund_desc;
        } elseif ($pay_type == 3) {
            $refund_desc = "微信H5退款" . $refund_desc;
        } elseif ($pay_type == 5) {
            $refund_desc = "微信PC退款" . $refund_desc;
        }
        //初始化值对象
        $input = new \WxPayRefund();
        $input->SetOut_trade_no($this->order_number);
        $input->SetOut_refund_no($this->createOrderNo());
        $refund_fee = $this->pay_price;
        if (!empty($this->order_info['pay_coupon_money'])) {
            $refund_fee = $refund_fee + $this->order_info['pay_coupon_money'];
        }

        $total_fee = $this->total_money;
        if ($total_fee) {
            // 对于多商户
            $input->SetTotal_fee($total_fee * 100);
        } else {
            $input->SetTotal_fee($refund_fee * 100);
        }

        $input->SetRefund_fee($refund_fee * 100);
        // 向微信统一下单，并返回 unifiedorder，它是一个array数组1
        $refundorder = \WxPayApi::refund($input);
        if (!$refundorder) {
            $rs['code'] = 0;
            $rs['msg'] = '退款失败，请检查证书是否正确';
            return $rs;
        }
        if (!$refundorder) {
            $rs['code'] = 0;
            $rs['msg'] = '退款失败，请检查证书是否正确';
            return $rs;
        }
        //下单错误
        if ($refundorder['return_code'] == "FAIL") {
            $rs['code'] = 0;
            $rs['msg'] = $refundorder['return_msg'];
            return $rs;
        }
        if ($refundorder['result_code'] == "FAIL") {
            $msg = $refundorder['err_code_des'];
            if ($refundorder['err_code'] == 'ORDERNOTEXIST') {
                $msg = '此订单客户未真正支付，请线下沟通退款'; // 订单不存在
            }
            $rs['code'] = 0;
            $rs['msg'] = $msg;
            return $rs;
        }
        return $rs;
    }

    /**
     * 订单退款查询
     * @param $pay_type
     * @return array
     * @throws WxPayException
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function WxrefundQuery($pay_type)
    {
        $rs = array('code' => 200, 'info' => array(), 'msg' => '');
        if (empty($this->order_info)) {
            $rs['code'] = 0;
            $rs['msg'] = '订单不存在';
            return $rs;
        }
        if ($this->union_pay == 1) {
            //微信银联退款
            //$rs = $this->UnionRefund($pay_type);
            return $rs;
        }
        if ($this->yb_pay == 1) {
            //微信银联退款
            $rs = $this->YbRefundQuery($pay_type);
            return $rs;
        }
        $GLOBALS['pay_type'] = $pay_type;
        //初始化值对象
        $input = new \WxPayRefundQuery();
        $input->SetOut_trade_no($this->order_number);
        // 向微信统一下单，并返回 unifiedorder，它是一个array数组1
        $refundorder = \WxPayApi::refundQuery($input);
        //下单错误
        if ($refundorder['return_code'] == "FAIL") {
            $rs['code'] = 0;
            $rs['msg'] = $refundorder['return_msg'];
            return $rs;
        }
        if ($refundorder['result_code'] == "FAIL") {
            $rs['code'] = 0;
            $rs['msg'] = $refundorder['err_code_des'];
            return $rs;
        }
        $rs['info'] = $refundorder;
        return $rs;
    }

    /**
     * 微信订单查询
     * @param string $refund_desc
     * @param $pay_type
     * @return array
     * @throws WxPayException
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function Wxquery($pay_type)
    {
        $rs = array('code' => 200, 'info' => array(), 'msg' => '');
        if (empty($this->order_info)) {
            $rs['code'] = 0;
            $rs['msg'] = '订单不存在';
            return $rs;
        }
        if ($this->union_pay == 1) {
            //微信银联退款
            $rs = $this->UnionQuery($pay_type);
            return $rs;
        }
        if ($this->yb_pay == 1) {
            //微信银联退款
            $rs = $this->YbQuery($pay_type);
            return $rs;
        }
        $GLOBALS['pay_type'] = $pay_type;
        //初始化值对象
        $input = new \WxPayOrderQuery();
        $input->SetOut_trade_no($this->order_number);
        // 向微信统一下单，并返回 unifiedorder，它是一个array数组1
        $queryorder = \WxPayApi::orderQuery($input);
        $rs['info'] = $queryorder;
        //下单错误
        if ($queryorder['return_code'] == "FAIL") {
            $rs['code'] = 0;
            $rs['msg'] = $queryorder['return_msg'];
            return $rs;
        }
        if ($queryorder['result_code'] == "FAIL") {
            $rs['code'] = 0;
            $rs['msg'] = $queryorder['err_code_des'];
            return $rs;
        }
        if ($queryorder['trade_state'] != "SUCCESS") {
            $rs['code'] = 0;
            $rs['msg'] = $queryorder['trade_state_desc'];
            return $rs;
        }
        return $rs;
    }

    /**
     * 支付宝订单查询
     * @param $pay_type
     * @return array
     * @throws Exception
     */
    public function Aliquery($pay_type)
    {
        $rs = array('code' => 200, 'info' => array(), 'msg' => '');
        if (empty($this->order_info)) {
            $rs['code'] = 0;
            $rs['msg'] = '订单不存在';
            return $rs;
        }
        $GLOBALS['pay_type'] = $pay_type;
        //支付宝
        if ($pay_type == 6) {
            $config = new \AliPayConfig();
            $aopClient = new \AopClient();
            $aopClient->appId = $config->GetAppId();
            $aopClient->rsaPrivateKey = $config->GetPrivateKey();
            $aopClient->alipayrsaPublicKey = $config->GetPublicKey();
            $aopClient->signType = $config->GetSignType();
            $request = new \AlipayTradeQueryRequest();
            $biz_content = array(
                'out_trade_no' => $this->order_number,
            );
            $request->setBizContent(json_encode($biz_content));
            $response = $aopClient->execute($request);
            $response = json_decode(json_encode($response, true), true);
            $rs['info'] = $response;
            if ($response['alipay_trade_query_response']['code'] == '10000') {
                return $rs;
            } else {
                $rs['code'] = 0;
                $rs['msg'] = json_encode($response['alipay_trade_query_response'], JSON_UNESCAPED_UNICODE);
                return $rs;
            }
        }

    }

    /**
     * 银联退款
     * @param string $refund_desc
     * @param $pay_type
     * @return array
     * @throws WxPayException
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function UnionRefund($refund_desc = '', $pay_type)
    {
        $rs = array('code' => 200, 'info' => array(), 'msg' => '');
        if (empty($this->order_info)) {
            $rs['code'] = 0;
            $rs['msg'] = '订单不存在';
            return $rs;
        }
        $GLOBALS['pay_type'] = $pay_type;
        if ($pay_type == 1) {
            $refund_desc = "微信小程序退款" . $refund_desc;
        } elseif ($pay_type == 2) {
            $refund_desc = "微信公众号退款" . $refund_desc;
        }
        //初始化值对象
        $input = new \WxPayUnionRefund();
        $input->SetOut_trade_no($this->order_number);
        $input->SetOut_refund_no($this->createOrderNo());
        $input->SetTotal_fee($this->pay_price * 100);
        $input->SetRefund_fee($this->pay_price * 100);
        // 向微信统一下单，并返回 unifiedorder，它是一个array数组1
        $unifiedorder = \WxPayApi::unionRefund($input);
        //下单错误
        if ($unifiedorder['status'] != "0") {
            $rs['code'] = 0;
            $rs['msg'] = $unifiedorder['message'];
            return $rs;
        }
        if ($unifiedorder['result_code'] != "0") {
            $rs['code'] = 0;
            $rs['msg'] = $unifiedorder['err_msg'];
            return $rs;
        }
        return $rs;
    }

    /**
     * 银联查询
     * @param string $refund_desc
     * @param $pay_type
     * @return array
     * @throws WxPayException
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function UnionQuery($pay_type)
    {
        $rs = array('code' => 200, 'info' => array(), 'msg' => '');
        if (empty($this->order_info)) {
            $rs['code'] = 0;
            $rs['msg'] = '订单不存在';
            return $rs;
        }
        $GLOBALS['pay_type'] = $pay_type;
        //初始化值对象
        $input = new \WxPayUnionOrderQuery();
        $input->SetOut_trade_no($this->order_number);
        // 向微信统一下单，并返回 unifiedorder，它是一个array数组1
        $queryorder = \WxPayApi::unionQuery($input);
        //下单错误
        if ($queryorder['status'] != "0") {
            $rs['code'] = 0;
            $rs['msg'] = $queryorder['message'];
            return $rs;
        }
        if ($queryorder['result_code'] != "0") {
            $rs['code'] = 0;
            $rs['msg'] = $queryorder['err_msg'];
            return $rs;
        }
        $rs['info'] = $queryorder;
        return $rs;
    }
    /**
     * 银盛支付
     * @param string $description
     * @param $pay_type 1/小程序支付 2/公众号 3/H5支付
     * @return array
     */
    public function YseRefund($description = '', $pay_type, $refund_fee = 0)
    {
        $rs = array('code' => 200, 'info' => array(), 'msg' => '');
        if (empty($this->order_info)) {
            $rs['code'] = 0;
            $rs['msg'] = '订单不存在';
            return $rs;
        }
        $GLOBALS['pay_type'] = $pay_type;
        $input['out_trade_no'] = $this->order_info['out_trade_no'];
        $input['total_amount'] = $refund_fee != 0 ? $refund_fee : $this->pay_price;
        $input['refund_reason'] = $description;
        $ysePay = new \YsePay();
        $unifiedorder = $ysePay->order_refund($input);
        if ($unifiedorder['code'] == 0) {
            $rs['code'] = 0;
            $rs['msg'] = $unifiedorder['msg'];
            return $rs;
        }

        $rs['info'] = $unifiedorder['data'];
        return $rs;
    }

    /**
     * 易宝支付
     * @param string $description
     * @param $pay_type 1/小程序支付 2/公众号 3/H5支付
     * @return array
     */
    public function YbRefund($description = '', $pay_type)
    {
        $rs = array('code' => 200, 'info' => array(), 'msg' => '');
        if (empty($this->order_info)) {
            $rs['code'] = 0;
            $rs['msg'] = '订单不存在';
            return $rs;
        }
        $sys_pay_notify = Db::name('sys_pay_notify')->where('order_number', $this->order_number)->find();
        if (empty($sys_pay_notify)) {
            $rs['code'] = 0;
            $rs['msg'] = '订单不存在';
            return $rs;
        }
        $notify_message = json_decode($sys_pay_notify['notify_message'], true);
        $GLOBALS['pay_type'] = $pay_type;
        $attach['mch_id'] = $this->mch_id;
        $attach['pay_type'] = $pay_type;
        $attach['platform'] = $this->platform;
        if ($pay_type == 1) {
            $description = "微信小程序易宝退款" . $description;
        } elseif ($pay_type == 2) {
            $description = "微信公众号易宝退款" . $description;
        }
        $input['orderId'] = $this->order_number;
        $input['refundRequestId'] = $this->createOrderNo();
        $input['uniqueOrderNo'] = $notify_message['uniqueOrderNo'];
        $input['refundAmount'] = $this->pay_price;
        $input['description'] = $description;
        $yopClient3 = new \YopClient3();
        $unifiedorder = $yopClient3->sendRefund($input);
        //退款错误
        if ($unifiedorder['state'] == "FAILURE") {
            $rs['code'] = 0;
            $rs['msg'] = $unifiedorder['error']['message'];
            return $rs;
        }
        if ($unifiedorder['state'] == "SUCCESS" && $unifiedorder['result']['code'] != "CAS00000") {
            $rs['code'] = 0;
            $rs['msg'] = $unifiedorder['result']['message'];
            return $rs;
        }
        $notify_message['refundRequestId'] = $input['refundRequestId'];
        $notify_message['uniqueRefundNo'] = $unifiedorder['result']['uniqueRefundNo'];
        Db::name('sys_pay_notify')->where('order_number', $this->order_number)->update(['notify_message' => json_encode($notify_message)]);
        return $rs;
    }

    /**
     * 易宝订单查询
     * @param $pay_type 1/小程序支付 2/公众号 3/H5支付
     * @return array
     */
    public function YbQuery($pay_type)
    {
        $rs = array('code' => 200, 'info' => array(), 'msg' => '');
        if (empty($this->order_info)) {
            $rs['code'] = 0;
            $rs['msg'] = '订单不存在';
            return $rs;
        }
        $sys_pay_notify = Db::name('sys_pay_notify')->where('order_number', $this->order_number)->find();
        if (empty($sys_pay_notify)) {
            $rs['code'] = 0;
            $rs['msg'] = '订单不存在';
            return $rs;
        }
        $notify_message = json_decode($sys_pay_notify['notify_message'], true);
        $GLOBALS['pay_type'] = $pay_type;
        $attach['mch_id'] = $this->mch_id;
        $attach['pay_type'] = $pay_type;
        $attach['platform'] = $this->platform;
        $input['orderId'] = $this->order_number;
        $input['uniqueOrderNo'] = $notify_message['uniqueOrderNo'];
        $yopClient3 = new \YopClient3();
        $unifiedorder = $yopClient3->sendApiOrderQuery($input);
        //下单错误
        if ($unifiedorder['state'] == "FAILURE") {
            $rs['code'] = 0;
            $rs['msg'] = $unifiedorder['error']['message'];
            return $rs;
        }
        if ($unifiedorder['state'] == "SUCCESS" && $unifiedorder['result']['code'] != "CAS00000") {
            $rs['code'] = 0;
            $rs['msg'] = $unifiedorder['result']['message'];
            return $rs;
        }
        return $rs;
    }

    /**
     * 易宝支付
     * @param $pay_type 1/小程序支付 2/公众号 3/H5支付
     * @return array
     */
    public function YbRefundQuery($pay_type)
    {
        $rs = array('code' => 200, 'info' => array(), 'msg' => '');
        if (empty($this->order_info)) {
            $rs['code'] = 0;
            $rs['msg'] = '订单不存在';
            return $rs;
        }
        $sys_pay_notify = Db::name('sys_pay_notify')->where('order_number', $this->order_number)->find();
        if (empty($sys_pay_notify)) {
            $rs['code'] = 0;
            $rs['msg'] = '订单不存在';
            return $rs;
        }
        $notify_message = json_decode($sys_pay_notify['notify_message'], true);
        $GLOBALS['pay_type'] = $pay_type;
        $attach['mch_id'] = $this->mch_id;
        $attach['pay_type'] = $pay_type;
        $attach['platform'] = $this->platform;
        $input['orderId'] = $this->order_number;
        $input['refundRequestId'] = $notify_message['refundRequestId'];
        $input['uniqueRefundNo'] = $notify_message['uniqueRefundNo'];
        $yopClient3 = new \YopClient3();
        $unifiedorder = $yopClient3->sendRefundQuery($input);
        //下单错误
        if ($unifiedorder['state'] == "FAILURE") {
            $rs['code'] = 0;
            $rs['msg'] = $unifiedorder['error']['message'];
            return $rs;
        }
        if ($unifiedorder['state'] == "SUCCESS" && $unifiedorder['result']['code'] != "CAS00000") {
            $rs['code'] = 0;
            $rs['msg'] = $unifiedorder['result']['message'];
            return $rs;
        }
        return $rs;
    }

    /**
     * 字节担保支付查询
     * @return array
     */
    public function Ttquery()
    {
        $rs = array('code' => 200, 'info' => array(), 'msg' => '');
        if (empty($this->order_info)) {
            $rs['code'] = 0;
            $rs['msg'] = '订单不存在';
            return $rs;
        }
        $ttConfig = new \TtPayConfig();
        if ($ttConfig->GetIsOpenGuaranteePay() == 1) {
            //担保支付
            $data['out_order_no'] = $this->order_number;
            $ttPayClient = new \TtPayClient();
            $response = $ttPayClient->queryOrder($data, $ttConfig);
            if ($response['err_no'] != 0) {
                $rs['code'] = 0;
                $rs['msg'] = $response['err_tips'];
                return $rs;
            }
            if ($response['payment_info']['order_status'] != 'SUCCESS') {
                $rs['code'] = 0;
                $rs['msg'] = '当前订单状态：' . $response['payment_info']['order_status'];
                return $rs;
            }
            $rs['info'] = $response;
        } else {
            $rs['code'] = 0;
            $rs['msg'] = '非担保支付';
        }
        return $rs;
    }

    /**
     * 快手担保支付查询
     * @return array
     */
    public function Ksquery()
    {
        $rs = array('code' => 200, 'info' => array(), 'msg' => '');
        if (empty($this->order_info)) {
            $rs['code'] = 0;
            $rs['msg'] = '订单不存在';
            return $rs;
        }
        //担保支付
        $data['out_order_no'] = $this->order_number;
        $ksPayClient = new \KsPayClient();
        $response = $ksPayClient->queryOrder($data);
        if ($response['result'] != 1) {
            $rs['code'] = 0;
            $rs['msg'] = $response['error_msg'];
            return $rs;
        }
        if ($response['payment_info']['pay_status'] != 'SUCCESS') {
            $rs['code'] = 0;
            $rs['msg'] = '当前订单状态：' . $response['payment_info']['order_status'];
            return $rs;
        }
        $rs['info'] = $response;
        return $rs;
    }

    /**
     * 字节担保支付退款
     * @param string $reason
     * @return array
     * @throws \think\Exception
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     * @throws \think\exception\PDOException
     */
    public function Ttrefund($reason = '')
    {
        $rs = array('code' => 200, 'info' => array(), 'msg' => '');
        if (empty($this->order_info)) {
            $rs['code'] = 0;
            $rs['msg'] = '订单不存在';
            return $rs;
        }
        $sys_pay_notify = Db::name('sys_pay_notify')->where('order_number', $this->order_number)->find();
        if (empty($sys_pay_notify)) {
            $rs['code'] = 0;
            $rs['msg'] = '订单不存在';
            return $rs;
        }
        $notify_message = json_decode($sys_pay_notify['notify_message'], true);
        $ttConfig = new \TtPayConfig();
        if ($ttConfig->GetIsOpenGuaranteePay() == 1) {
            //担保支付
            $data['out_order_no'] = $this->order_number;
            $data['out_refund_no'] = $this->createOrderNo();
            $data['reason'] = $reason;
            $data['refund_amount'] = $this->pay_price * 100;
            $cp_extra['mch_id'] = $this->mch_id;
            $data['cp_extra'] = json_encode($cp_extra, true);
            $ttPayClient = new \TtPayClient();
            $response = $ttPayClient->createRefund($data, $ttConfig);
            if ($response['err_no'] != 0) {
                $rs['code'] = 0;
                $rs['msg'] = $response['err_tips'];
                return $rs;
            }
            $notify_message['out_refund_no'] = $data['out_refund_no'];
            $notify_message['refund_no'] = $response['refund_no'];
            Db::name('sys_pay_notify')->where('order_number', $this->order_number)->update(['notify_message' => json_encode($notify_message)]);
            return $rs;
        } else {
            $rs['code'] = 0;
            $rs['msg'] = '非担保支付';
            return $rs;
        }
        return $rs;
    }

    /**
     * 快手担保支付退款
     * @param string $reason
     * @return array
     * @throws \think\Exception
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     * @throws \think\exception\PDOException
     */
    public function Ksrefund($reason = '')
    {
        $rs = array('code' => 200, 'info' => array(), 'msg' => '');
        if (empty($this->order_info)) {
            $rs['code'] = 0;
            $rs['msg'] = '订单不存在';
            return $rs;
        }
        $sys_pay_notify = Db::name('sys_pay_notify')->where('order_number', $this->order_number)->find();
        if (empty($sys_pay_notify)) {
            $rs['code'] = 0;
            $rs['msg'] = '订单不存在';
            return $rs;
        }
        $notify_message = json_decode($sys_pay_notify['notify_message'], true);
        //担保支付
        $data['out_order_no'] = $this->order_number;
        $data['out_refund_no'] = $this->createOrderNo();
        $data['reason'] = $reason;
        $data['refund_amount'] = $this->pay_price * 100;
        $attach['mch_id'] = $this->mch_id;
        $data['attach'] = json_encode($attach, true);
        $ksPayClient = new \KsPayClient();
        $response = $ksPayClient->createRefund($data);
        if ($response['result'] != 1) {
            $rs['code'] = 0;
            $rs['msg'] = $response['error_msg'];
            return $rs;
        }
        $notify_message['out_refund_no'] = $data['out_refund_no'];
        $notify_message['refund_no'] = $response['refund_no'];
        Db::name('sys_pay_notify')->where('order_number', $this->order_number)->update(['notify_message' => json_encode($notify_message)]);
        return $rs;
    }

    /**
     * 担保交易退款查询
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function TtrefundQuery()
    {
        $rs = array('code' => 200, 'info' => array(), 'msg' => '');
        if (empty($this->order_info)) {
            $rs['code'] = 0;
            $rs['msg'] = '订单不存在';
            return $rs;
        }
        $sys_pay_notify = Db::name('sys_pay_notify')->where('order_number', $this->order_number)->find();
        if (empty($sys_pay_notify)) {
            $rs['code'] = 0;
            $rs['msg'] = '订单不存在';
            return $rs;
        }
        $notify_message = json_decode($sys_pay_notify['notify_message'], true);
        $ttConfig = new \TtPayConfig();
        if ($ttConfig->GetIsOpenGuaranteePay() == 1) {
            //担保支付
            $data['out_refund_no'] = $notify_message['out_refund_no'];
            $ttPayClient = new \TtPayClient();
            $response = $ttPayClient->queryRefund($data, $ttConfig);
            if ($response['err_no'] != 0) {
                $rs['code'] = 0;
                $rs['msg'] = $response['err_tips'];
                return $rs;
            }
            if ($response['refundInfo']['refund_status'] != 'SUCCESS') {
                $rs['code'] = 0;
                $rs['msg'] = '退款失败';
                return $rs;
            }
            return $rs;
        } else {
            $rs['code'] = 0;
            $rs['msg'] = '非担保支付';
            return $rs;
        }
        return $rs;
    }

    /**
     * 快手交易退款查询
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function KsrefundQuery()
    {
        $rs = array('code' => 200, 'info' => array(), 'msg' => '');
        if (empty($this->order_info)) {
            $rs['code'] = 0;
            $rs['msg'] = '订单不存在';
            return $rs;
        }
        $sys_pay_notify = Db::name('sys_pay_notify')->where('order_number', $this->order_number)->find();
        if (empty($sys_pay_notify)) {
            $rs['code'] = 0;
            $rs['msg'] = '订单不存在';
            return $rs;
        }
        $notify_message = json_decode($sys_pay_notify['notify_message'], true);
        //担保支付
        $data['out_refund_no'] = $notify_message['out_refund_no'];
        $ksPayClient = new \KsPayClient();
        $response = $ksPayClient->queryRefund($data);
        if ($response['result'] != 1) {
            $rs['code'] = 0;
            $rs['msg'] = $response['error_msg'];
            return $rs;
        }
        if ($response['refund_info']['refund_status'] != 'REFUND_SUCCESS') {
            $rs['code'] = 0;
            $rs['msg'] = '退款失败';
            return $rs;
        }
        return $rs;
    }

    /**
     * 字节担保支付分账
     * @param string $settle_desc 结算描述，长度限制 80 个字符
     * @param string $settle_params 其他分账方信息，只需要传入卖家之外的分润方，分账分配参数数组序列化后生成的 json 格式字符串，{"merchant_uid": "分账方商户号","amount": 10 // 分账金额}
     * @return array
     */
    public function TtSplitAccount($settle_params = '', $settle_desc = '分账')
    {
        $rs = array('code' => 200, 'info' => array(), 'msg' => '');

        if (empty($this->order_info)) {
            $rs['code'] = 0;
            $rs['msg'] = '订单不存在';
            return $rs;
        }

        // 查询该订单是否已分账
        $split_info = Db::name('split_account_order')
            ->field('id,status')
            ->where(['mch_id' => $this->mch_id, 'sys_order_id' => $this->order_info['id']])
            ->find();
        if ($split_info) {
            $rs['code'] = 0;
            $rs['msg'] = '该订单已分账，请勿重复操作';
            return $rs;
        }

        if (!in_array($this->order_info['order_status'], [1, 2, 3])) {
            $rs['code'] = 0;
            $rs['msg'] = '订单状态错误';
            return $rs;
        }

        if ($this->order_info['platform'] != 3) {
            $rs['code'] = 0;
            $rs['msg'] = '仅支持使用字节跳动支付的订单';
            return $rs;
        }

        $ttConfig = new \TtPayConfig();
        if ($ttConfig->GetIsOpenGuaranteePay() == 1) {
            //担保支付
            $data['out_order_no'] = $this->order_number; // 商户分配订单号，标识进行结算的订单
            $data['out_settle_no'] = $this->createOrderNo(); // 开发者侧的结算号, 不可重复
            $data['settle_desc'] = $settle_desc; // 结算描述，长度限制 80 个字符
            $data['settle_params'] = $settle_params; // 其他分账方信息，只需要传入卖家之外的分润方，分账分配参数数组序列化后生成的 json 格式字符串，{"merchant_uid": "分账方商户号","amount": 10 // 分账金额}
            $data['cp_extra'] = json_encode(['mch_id' => $this->mch_id], true); // 开发者自定义字段，回调原样回传

            $ttPayClient = new \TtPayClient();
            $response = $ttPayClient->createSplitAccount($data, $ttConfig);
            if ($response['err_no'] != 0) {
                $rs['code'] = 0;
                $rs['msg'] = $response['err_tips'];
                return $rs;
            }

            $rs['info']['out_settle_no'] = $data['out_settle_no'];
            $rs['info']['settle_no'] = $response['settle_no'];
        } else {
            $rs['code'] = 0;
            $rs['msg'] = '非担保支付';
        }

        return $rs;
    }

    /**
     * 快手担保支付分账
     * @param string $settle_desc 结算描述，长度限制 80 个字符
     * @return array
     */
    public function KsSplitAccount($settle_desc = '分账')
    {
        $rs = array('code' => 200, 'info' => array(), 'msg' => '');

        if (empty($this->order_info)) {
            $rs['code'] = 0;
            $rs['msg'] = '订单不存在';
            return $rs;
        }

        // 查询该订单是否已分账
        $split_info = Db::name('split_account_order')
            ->field('id,status')
            ->where(['mch_id' => $this->mch_id, 'sys_order_id' => $this->order_info['id']])
            ->find();
        if ($split_info) {
            $rs['code'] = 0;
            $rs['msg'] = '该订单已分账，请勿重复操作';
            return $rs;
        }

        if (!in_array($this->order_info['order_status'], [1, 2, 3])) {
            $rs['code'] = 0;
            $rs['msg'] = '订单状态错误';
            return $rs;
        }

        if ($this->order_info['platform'] != 12) {
            $rs['code'] = 0;
            $rs['msg'] = '仅支持使用快手支付的订单';
            return $rs;
        }
        //担保支付
        $data['out_order_no'] = $this->order_number; // 商户分配订单号，标识进行结算的订单
        $data['out_settle_no'] = $this->createOrderNo(); // 开发者侧的结算号, 不可重复
        $data['reason'] = $settle_desc; // 结算描述，长度限制 80 个字符
        $data['attach'] = json_encode(['mch_id' => $this->mch_id], true); // 开发者自定义字段，回调原样回传
        $ksPayClient = new \KsPayClient();
        $response = $ksPayClient->createSplitAccount($data);
        if ($response['result'] != 1) {
            $rs['code'] = 0;
            $rs['msg'] = $response['error_msg'];
            return $rs;
        }
        $rs['info']['out_settle_no'] = $data['out_settle_no'];
        $rs['info']['settle_no'] = $response['settle_no'];
        return $rs;
    }

    /**
     * 字节担保支付查询分账
     * @return array
     */
    public function TtQuerySplitAccount()
    {
        $rs = array('code' => 200, 'info' => array(), 'msg' => '');

        if (empty($this->order_info)) {
            $rs['code'] = 0;
            $rs['msg'] = '订单不存在';
            return $rs;
        }

        // 查询该订单是否已分账
        $split_info = Db::name('split_account_order')
            ->field('id,status,out_settle_no')
            ->where(['mch_id' => $this->mch_id, 'sys_order_id' => $this->order_info['id']])
            ->find();
        if (!$split_info) {
            $rs['code'] = 0;
            $rs['msg'] = '该订单未分账';
            return $rs;
        }

        // 请求参数
        $data['out_settle_no'] = $split_info['out_settle_no']; // 开发者侧的结算号, 不可重复

        $ttConfig = new \TtPayConfig();
        $ttPayClient = new \TtPayClient();
        $response = $ttPayClient->querySplitAccount($data, $ttConfig);
        if ($response['err_no'] != 0) {
            $rs['code'] = 0;
            $rs['msg'] = $response['err_tips'];
            return $rs;
        }

        $rs['info']['settle_info'] = $response['settle_info'];
        return $rs;
    }

    /**
     * 字节担保支付查询分账
     * @return array
     */
    public function KsQuerySplitAccount()
    {
        $rs = array('code' => 200, 'info' => array(), 'msg' => '');

        if (empty($this->order_info)) {
            $rs['code'] = 0;
            $rs['msg'] = '订单不存在';
            return $rs;
        }
        // 查询该订单是否已分账
        $split_info = Db::name('split_account_order')
            ->field('id,status,out_settle_no')
            ->where(['mch_id' => $this->mch_id, 'sys_order_id' => $this->order_info['id']])
            ->find();
        if (!$split_info) {
            $rs['code'] = 0;
            $rs['msg'] = '该订单未分账';
            return $rs;
        }
        // 请求参数
        $data['out_settle_no'] = $split_info['out_settle_no']; // 开发者侧的结算号, 不可重复
        $ksPayClient = new \KsPayClient();
        $response = $ksPayClient->querySplitAccount($data);
        if ($response['result'] != 1) {
            $rs['code'] = 0;
            $rs['msg'] = $response['error_msg'];
            return $rs;
        }

        $rs['info']['settle_info'] = $response['settle_info'];
        return $rs;
    }

    /**
     * 微信企业付款到零钱
     * @param $partner_trade_no
     * @param $re_user_name
     * @param $amount
     * @param string $desc
     * @param int $user_id
     * @param int $platform
     * @return array
     */
    public function WxTransfers($partner_trade_no, $re_user_name, $amount, $desc = '', $mch_id = 0, $user_id = 0, $platform = 0, $relate_type = 1)
    {
        // 查询打款配置
        $config_info = ConfigService::getConfigValue('rule', $mch_id);
        if (empty($config_info)) {
            $config_info = ['transfer_way' => 2];
        }
        if (isset($config_info['transfer_way']) && $config_info['transfer_way'] == 2) {
            // 商家转账到零钱
            $system_service = new \iyibai\services\SystemService();
            $config_pay = $system_service->getTransferCheckSignType($mch_id, $platform);
            if (isset($config_pay['check_sign_type'])) {
                if ($config_pay['check_sign_type'] == 1 || $config_pay['check_sign_type'] == 2) {
                    // 商家转账到零钱V3，微信支付公钥验签
                    return $this->wxTransfersV3($partner_trade_no, $re_user_name, $amount, $desc, $mch_id, $user_id, $platform, $relate_type);
                }
                if ($config_pay['check_sign_type'] == 3) {
                    // 商家转账到零钱V3，商户API证书
                    return $this->wxTransfersV3New($partner_trade_no, $re_user_name, $amount, $desc, $mch_id, $user_id, $platform, $relate_type);
                }
            }
        }

        $rs = array('code' => 200, 'info' => array(), 'msg' => '');
        $user = Db::name('sys_user')->where('id', $user_id)->find();
        if (empty($user)) {
            $rs['code'] = 0;
            $rs['msg'] = '用户不存在';
            return $rs;
        }
        $pay_type = 1;
        if ($platform == 4) {
            $pay_type = 2;
        } elseif ($platform == 5) {
            $pay_type = 3;
        }
        $GLOBALS['pay_type'] = $pay_type;
        $GLOBALS['mch_id'] = $mch_id;
        $GLOBALS['platform'] = $platform;
        //初始化值对象
        $input = new \WxPayTransfers();
        $input->SetPartner_trade_no($partner_trade_no);
        $input->SetOpenid($user['openid']);
        if (!empty($re_user_name)) {
            $input->SetCheck_name('FORCE_CHECK');
            $input->SetRe_user_name($re_user_name);
        } else {
            $input->SetCheck_name('NO_CHECK');
        }
        $input->SetAmount($amount * 100);
        $input->SetDesc($desc);
        // 向微信统一下单，并返回 unifiedorder，它是一个array数组1
        $unifiedorder = \WxPayApi::transfers($input);
        //下单错误
        if ($unifiedorder['return_code'] == "FAIL") {
            $rs['code'] = 0;
            $rs['msg'] = $unifiedorder['return_msg'];
            return $rs;
        }
        if ($unifiedorder['result_code'] == "FAIL") {
            $rs['code'] = 0;
            $rs['msg'] = $unifiedorder['err_code_des'];
            return $rs;
        }
        return $rs;
    }

    /**
     * 商家转账到零钱
     * @param string $partner_trade_no
     * @param string $re_user_name
     * @param float $amount
     * @param string $desc
     * @param int $user_id
     * @param int $platform
     * @param int $relate_type 关联类型 1/分销 2/股东分红 3/区域代理 4/团队分红 5/门店佣金 6/积分提现 7/社区团购 8/代理股东 9/支付返现
     * @return array
     */
    public function wxTransfersV3($partner_trade_no, $re_user_name, $amount, $desc = '', $mch_id = 0, $user_id = 0, $platform = 0, $relate_type = 1)
    {
        $rs = array('code' => 200, 'info' => array(), 'msg' => '');

        $user = Db::name('sys_user')->where('id', $user_id)->find();
        if (empty($user['openid'])) {
            $rs['code'] = 0;
            $rs['msg'] = '用户不存在';
            return $rs;
        }
        if ($platform != 0) {
            $rs['code'] = 0;
            $rs['msg'] = '暂仅支持微信小程序';
            return $rs;
        }

        switch ($relate_type) {
            case 1: // 分销提现
                $log_info = Db::name('distribution_withdraw_log')
                    ->field('id,shop_id')
                    ->where(['out_trade_no' => $partner_trade_no, 'mch_id' => $mch_id, 'delete_time' => 0])
                    ->find();
                break;
            case 6://积分提现
                $log_info = Db::name('integral_withdrawl_log')
                    ->field('id,shop_id')
                    ->where(['out_trade_no' => $partner_trade_no, 'mch_id' => $mch_id, 'delete_time' => 0])
                    ->find();
                break;
            default:
                $log_info = [];
        }

        if (!$log_info) {
            $rs['code'] = 0;
            $rs['msg'] = '未找到提现记录数据';
            return $rs;
        }

        $relate_ids = $log_info['id'] . ',';
        // 查询转账记录是否已存在
        $transfer_log = Db::name('sys_transfer_log')
            ->field('id')
            ->where(['relate_type' => $relate_type, 'out_batch_no' => $partner_trade_no, 'mch_id' => $mch_id])
            ->where('relate_ids', 'like', "%{$relate_ids}%")
            ->find();

        if ($transfer_log) {
            $rs['code'] = 0;
            $rs['msg'] = '该提现转账记录已存在';
            return $rs;
        }

        $pay_type = 1;
        if ($platform == 4) {
            $pay_type = 2;
        } elseif ($platform == 5) {
            $pay_type = 3;
        }

        $GLOBALS['pay_type'] = $pay_type;
        $GLOBALS['mch_id'] = $mch_id;
        $GLOBALS['platform'] = $platform;

        $data['out_batch_no'] = $partner_trade_no; // 商家批次单号，商户系统内部的商家批次单号，要求此参数只能由数字、大小写字母组成，在商户系统内部唯一
        $data['batch_name'] = $desc; // 批次名称，最多允许32个字符
        $data['batch_remark'] = $desc; // 批次备注，最多允许32个字符
        $data['total_amount'] = $amount * 100; // 转账总金额，转账金额单位为“分”。转账总金额必须与批次内所有明细转账金额之和保持一致，否则无法发起转账操作
        $data['total_num'] = 1; // 一个转账批次单最多发起三千笔转账。转账总笔数必须与批次内所有明细之和保持一致，否则无法发起转账操作
        // 发起批量转账的明细列表，最多三千笔
        $data['transfer_detail_list'] = [
            [
                'out_detail_no' => $partner_trade_no, // 商家明细单号，商户系统内部区分转账批次单下不同转账明细单的唯一标识，要求此参数只能由数字、大小写字母组成
                'transfer_amount' => $amount * 100, // 转账金额，单位为分
                'transfer_remark' => $desc, // 单条转账备注（微信用户会收到该备注），UTF8编码，最多允许32个字符
                'openid' => $user['openid'], // 用户openid
                //'user_name' => $re_user_name, // 暂不传，暂不考虑>= 2,000，明细转账金额 >= 2,000，收款用户姓名必填；同一批次转账明细中，收款用户姓名字段需全部填写、或全部不填写；若传入收款用户姓名，微信支付会校验用户openID与姓名是否一致，并提供电子回单；该字段需进行加密处理(提醒：必须在HTTP头中上送Wechatpay-Serial)
            ],
        ];

        $transferApi = new \WechatpayTransferApi($mch_id);
        $res = $transferApi->transferBatches($data);
        if ($res['code'] != 200) {
            $rs['code'] = $res['code'];
            $rs['msg'] = $res['msg'];
            return $rs;
        }

        // 存储转账记录
        $transfer_data = [
            'relate_type' => $relate_type,
            'relate_ids' => $relate_ids,
            'out_batch_no' => $partner_trade_no,
            'request_message' => json_encode($data, true),
            'return_message' => json_encode($res, true),
            'create_time' => time(),
            'mch_id' => $mch_id,
            'shop_id' => $log_info['shop_id'],
        ];
        Db::name('sys_transfer_log')->insert($transfer_data);
        return $rs;
    }

    /**
     * 新版商家转账用户确认模式
     * @param string $partner_trade_no
     * @param string $re_user_name
     * @param float $amount
     * @param string $desc
     * @param int $user_id
     * @param int $platform
     * @param int $relate_type 关联类型 1/分销 2/商家提现（多商户） 3/区域代理 4/团队分红 5/门店佣金 6/积分提现 7/社区团购 8/代理股东 9/支付返现 10/股东分红
     * @return array
     */
    public function wxTransfersV3New($partner_trade_no, $re_user_name, $amount, $desc = '', $mch_id = 0, $user_id = 0, $platform = 0, $relate_type = 1)
    {
        $rs = array('code' => 200, 'info' => array(), 'msg' => '');

        $user = Db::name('sys_user')->where('id', $user_id)->find();
        if (empty($user['openid'])) {
            $rs['code'] = 0;
            $rs['msg'] = '用户不存在';
            return $rs;
        }
        if ($platform != 0 && $platform != 4) {
            $rs['code'] = 0;
            $rs['msg'] = '仅支持微信小程序和公众号';
            return $rs;
        }

        $where = ['out_trade_no' => $partner_trade_no, 'mch_id' => $mch_id, 'delete_time' => 0];
        switch ($relate_type) {
            case 1:
                // 分销商提现
                $table_name = 'distribution_withdraw_log';
                break;
            case 2:
                // 多商户商家提现
                $table_name = 'shop_withdrawal_log';
                break;
            case 3:
                // 区域代理提现
                $table_name = 'area_agent_withdrawal_log';
                break;
            case 4:
                // 团队分红提现
                $table_name = 'team_withdrawal_log';
                break;
            case 5:
                // 门店佣金提现
                $table_name = 'store_agent_withdraw_log';
                break;
            case 6:
                // 积分提现
                $table_name = 'integral_withdrawl_log';
                break;
            case 7:
                // 社区团购提现
                $table_name = 'community_withdrawal_log';
                break;
            case 8:
                // 代理股东提现
                $table_name = 'shareholder_agent_withdrawal_log';
                break;
            case 9:
                // 支付返现提现
                $table_name = 'bank_cash_log';
                $where = ['cash_no' => $partner_trade_no, 'mch_id' => $mch_id];
                break;
            case 10:
                // 股东分红提现
                $table_name = 'shareholder_withdrawal_log';
                break;
            default:
                $table_name = '';
        }

        if (!$table_name) {
            $rs['code'] = 0;
            $rs['msg'] = '未找到提现数据';
            return $rs;
        }

        $log_info = Db::name($table_name)->field('id,shop_id')->where($where)->find();
        if (!$log_info) {
            $rs['code'] = 0;
            $rs['msg'] = '未找到提现记录数据';
            return $rs;
        }

        $relate_ids = $log_info['id'] . ',';
        // 查询转账记录是否已存在
        $transfer_log = Db::name('sys_transfer_log')
            ->field('id')
            ->where(['relate_type' => $relate_type, 'out_batch_no' => $partner_trade_no, 'mch_id' => $mch_id])
            ->where('relate_ids', 'like', "%{$relate_ids}%")
            ->find();

        if ($transfer_log) {
            $rs['code'] = 0;
            $rs['msg'] = '该提现转账记录已存在';
            return $rs;
        }

        $pay_type = 1;
        if ($platform == 4) {
            $pay_type = 2;
        }

        $GLOBALS['pay_type'] = $pay_type;
        $GLOBALS['mch_id'] = $mch_id;
        $GLOBALS['platform'] = $platform;

        // 1、设置接口安全IP
        // 2、当单笔转账金额在0.3元（含）至2,000元（含）之间时，商户可以自主决定是否传入用户姓名。当单笔转账金额低于0.3元时，不支持传入用户姓名校验
        // 3、当单笔转账金额超过2,000元时，为保障商户出资金安全，必须传入用户姓名进行校验
        $total_amount = bcmul($amount, 100);
        $total_amount = intval($total_amount); // 必须是int类型
        $data = [
            'out_bill_no' => $partner_trade_no, // 【商户单号】 商户系统内部的商家单号，要求此参数只能由数字、大小写字母组成，在商户系统内部唯一
            'transfer_scene_id' => '1005', // 【转账场景ID】 该笔转账使用的转账场景，可前往“商户平台-产品中心-商家转账”中申请。系统暂固定使用1005-佣金报酬
            'transfer_amount' => $total_amount, // 转账金额，单位为分
            'transfer_remark' => $desc, // 【转账备注】 用户收款时可见该备注信息，UTF8编码，最多允许32个字符
            'openid' => $user['openid'], // 用户openid
            //'user_name' => $re_user_name, // 选填，暂不考虑>= 2,000，明细转账金额 >= 2,000，收款用户姓名必填；同一批次转账明细中，收款用户姓名字段需全部填写、或全部不填写；若传入收款用户姓名，微信支付会校验用户openID与姓名是否一致，并提供电子回单；该字段需进行加密处理(提醒：必须在HTTP头中上送Wechatpay-Serial)
            'notify_url' => '', // 选填，【通知地址】必须为HTTPS地址，且不能携带后缀参数，否则可能导致商户无法接收到微信的回调通知信息，商家转账单据到终态后（转账完成或者转账失败，对应单据状态status的值为SUCCESS、CANCELLED和FAIL），微信支付会把单据的信息发送给商户，商户需要接收处理该消息，并返回应答
            'transfer_scene_report_infos' => [
                [
                    'info_type' => '岗位类型',
                    'info_content' => '代理人'
                ],
                [
                    'info_type' => '报酬说明',
                    'info_content' => '佣金'
                ],
            ], // 【转账场景报备信息】，在不同的【转账场景】下参数可能不完全一样，具体查看文档（https://pay.weixin.qq.com/doc/v3/merchant/4013774590），在【佣金报酬】的转账场景下需固定传两条明细，每条“转账场景报备信息明细”包含info_type、info_content两个参数
        ];

        $transferNewApi = new \WechatpayTransferNewApi($mch_id);
        $res = $transferNewApi->runTransfer($data);
        if ($res['code'] != 200) {
            $rs['code'] = $res['code'];
            $rs['msg'] = $res['msg'];
            return $rs;
        }

        // 存储转账记录
        $transfer_data = [
            'relate_type' => $relate_type,
            'relate_ids' => $relate_ids,
            'out_batch_no' => $partner_trade_no,
            'request_message' => json_encode($data, true),
            'return_message' => json_encode($res, true),
            'create_time' => time(),
            'mch_id' => $mch_id,
            'shop_id' => $log_info['shop_id'],
        ];
        Db::name('sys_transfer_log')->insert($transfer_data);
        return $rs;
    }

    /**
     * 新版商家转账用户确认模式，撤销转账
     * @param int $id
     * @param int $relate_type 关联类型 1/分销 2/商家提现（多商户） 3/区域代理 4/团队分红 5/门店佣金 6/积分提现 7/社区团购 8/代理股东 9/支付返现 10/股东分红
     * @return array
     */
    public function cancelTransfer($id, $relate_type)
    {
        $rs = array('code' => 200, 'info' => array(), 'msg' => '');

        $where = ['id' => $id];
        switch ($relate_type) {
            case 1:
                // 分销商提现
                $table_name = 'distribution_withdraw_log';
                break;
            case 2:
                // 多商户商家提现
                $table_name = 'shop_withdrawal_log';
                break;
            case 3:
                // 区域代理提现
                $table_name = 'area_agent_withdrawal_log';
                break;
            case 4:
                // 团队分红提现
                $table_name = 'team_withdrawal_log';
                break;
            case 5:
                // 门店佣金提现
                $table_name = 'store_agent_withdraw_log';
                break;
            case 6:
                // 积分提现
                $table_name = 'integral_withdrawl_log';
                break;
            case 7:
                // 社区团购提现
                $table_name = 'community_withdrawal_log';
                break;
            case 8:
                // 代理股东提现
                $table_name = 'shareholder_agent_withdrawal_log';
                break;
            case 9:
                // 支付返现提现
                $table_name = 'bank_cash_log';
                break;
            case 10:
                // 股东分红提现
                $table_name = 'shareholder_withdrawal_log';
                break;
            default:
                $table_name = '';
        }

        if (!$table_name) {
            $rs['code'] = 0;
            $rs['msg'] = '未找到提现数据';
            return $rs;
        }

        if ($table_name == 'bank_cash_log') {
            $log_info = Db::name('bank_cash_log')
                ->field('id,mch_id,shop_id,cash_no as out_trade_no,platform')
                ->where($where)
                ->find();
        } else {
            $log_info = Db::name($table_name)->field('id,mch_id,shop_id,out_trade_no,platform')->where($where)->find();
        }
        if (!$log_info) {
            $rs['code'] = 0;
            $rs['msg'] = '未找到提现记录数据';
            return $rs;
        }

        if ($log_info['platform'] != 0 && $log_info['platform'] != 4) {
            $rs['code'] = 0;
            $rs['msg'] = '仅支持微信小程序和公众号';
            return $rs;
        }

        $relate_ids = $log_info['id'] . ',';
        // 查询转账记录是否存在
        $transfer_log = Db::name('sys_transfer_log')
            ->field('id')
            ->where(['relate_type' => $relate_type, 'out_batch_no' => $log_info['out_trade_no'], 'mch_id' => $log_info['mch_id']])
            ->where('relate_ids', 'like', "%{$relate_ids}%")
            ->find();
        if (!$transfer_log) {
            $rs['code'] = 0;
            $rs['msg'] = '转账记录不存在';
            return $rs;
        }

        $pay_type = 1;
        if ($log_info['platform'] == 4) {
            $pay_type = 2;
        }

        $GLOBALS['pay_type'] = $pay_type;
        $GLOBALS['mch_id'] = $log_info['mch_id'];
        $GLOBALS['platform'] = $log_info['platform'];
        $data['out_bill_no'] = $log_info['out_trade_no'];

        $transferNewApi = new \WechatpayTransferNewApi($log_info['mch_id']);
        $res = $transferNewApi->revokeTransfer($data);
        if ($res['code'] != 200) {
            $rs['code'] = $res['code'];
            $rs['msg'] = $res['msg'];
            return $rs;
        }

        return $rs;
    }

    /**
     * 商家批量转账到零钱
     * @param array $transfer_data 转账批次数据
     * @param array $detail_data 转账明细数据
     * @return array
     */
    public function wxBatchTransfersV3($transfer_data, $detail_data)
    {
        $rs = array('code' => 200, 'info' => array(), 'msg' => '');

        if (!$transfer_data) {
            $rs['code'] = 0;
            $rs['msg'] = '批次数据错误';
            return $rs;
        }

        if (!$detail_data) {
            $rs['code'] = 0;
            $rs['msg'] = '明细数据错误';
            return $rs;
        }

        $pay_type = 1;
        $GLOBALS['pay_type'] = $pay_type;
        $GLOBALS['mch_id'] = $transfer_data['mch_id'];
        $GLOBALS['platform'] = 0;

        $data['appid'] = $transfer_data['appid'];
        $data['out_batch_no'] = $transfer_data['out_batch_no']; // 商家批次单号，商户系统内部的商家批次单号，要求此参数只能由数字、大小写字母组成，在商户系统内部唯一
        $data['batch_name'] = $transfer_data['batch_name']; // 批次名称，最多允许32个字符
        $data['batch_remark'] = $transfer_data['batch_remark']; // 批次备注，最多允许32个字符
        $data['total_amount'] = $transfer_data['total_amount'] * 100; // 转账总金额，转账金额单位为“分”。转账总金额必须与批次内所有明细转账金额之和保持一致，否则无法发起转账操作
        $data['total_num'] = $transfer_data['total_num']; // 一个转账批次单最多发起三千笔转账。转账总笔数必须与批次内所有明细之和保持一致，否则无法发起转账操作

        foreach ($data as $s) {
            if (empty($s)) {
                $rs['code'] = 0;
                $rs['msg'] = '批次数据不能为空';
                return $rs;
            }
        }

        // 发起批量转账的明细列表，最多三千笔
        $detail_list = [];
        foreach ($detail_data as $v) {
            $detail = [
                'out_detail_no' => $v['out_detail_no'], // 商家明细单号，商户系统内部区分转账批次单下不同转账明细单的唯一标识，要求此参数只能由数字、大小写字母组成
                'transfer_amount' => $v['transfer_amount'] * 100, // 转账金额，单位为分
                'transfer_remark' => $v['transfer_remark'], // 单条转账备注（微信用户会收到该备注），UTF8编码，最多允许32个字符
                'openid' => $v['openid'], // 用户openid
            ];
            if ($v['user_name']) {
                // 转账金额 >= 2,000，收款用户姓名必填；同一批次转账明细中，收款用户姓名字段需全部填写、或全部不填写；若传入收款用户姓名，微信支付会校验用户openID与姓名是否一致，并提供电子回单；该字段需进行加密处理(提醒：必须在HTTP头中上送Wechatpay-Serial)
                $detail['user_name'] = $v['user_name'];
            }
            $detail_list[] = $detail;
        }
        $data['transfer_detail_list'] = $detail_list;

        $transferApi = new \WechatpayTransferApi($transfer_data['mch_id']);
        $res = $transferApi->transferBatches($data);
        Log::write('批量转账工资结果：' . json_encode($res));
        if ($res['code'] != 200) {
            $rs['code'] = $res['code'];
            $rs['msg'] = $res['msg'];
            return $rs;
        }

        $rs['info'] = $res['info'];
        return $rs;
    }

    /**
     * 转账查询
     * @param int $relate_id
     * @param int $relate_type 关联类型 1/分销 2/商家提现（多商户） 3/区域代理 4/团队分红 5/门店佣金 6/积分提现 7/社区团购 8/代理股东 9/支付返现 10/股东分红
     * @return array
     */
    public function transferQuery($relate_id, $relate_type = 1)
    {
        $rs = array('code' => 200, 'info' => array(), 'msg' => '');

        switch ($relate_type) {
            case 1:
                // 分销商提现
                $table_name = 'distribution_withdraw_log';
                break;
            case 2:
                // 多商户商家提现
                $table_name = 'shop_withdrawal_log';
                break;
            case 3:
                // 区域代理提现
                $table_name = 'area_agent_withdrawal_log';
                break;
            case 4:
                // 团队分红提现
                $table_name = 'team_withdrawal_log';
                break;
            case 5:
                // 门店佣金提现
                $table_name = 'store_agent_withdraw_log';
                break;
            case 6:
                // 积分提现
                $table_name = 'integral_withdrawl_log';
                break;
            case 7:
                // 社区团购提现
                $table_name = 'community_withdrawal_log';
                break;
            case 8:
                // 代理股东提现
                $table_name = 'shareholder_agent_withdrawal_log';
                break;
            case 9:
                // 支付返现提现
                $table_name = 'bank_cash_log';
                break;
            case 10:
                // 股东分红提现
                $table_name = 'shareholder_withdrawal_log';
                break;
            default:
                $table_name = '';
        }

        if (!$table_name) {
            $rs['code'] = 0;
            $rs['msg'] = '未找到提现数据';
            return $rs;
        }

        $log_info = Db::name($table_name)->where(['id' => $relate_id])->find();
        if (!$log_info) {
            $rs['code'] = 0;
            $rs['msg'] = '未找到提现记录';
            return $rs;
        }

        if ($relate_type == 9) {
            $log_info['out_trade_no'] = $log_info['cash_no'];
        }

        $system_service = new \iyibai\services\SystemService();
        $config_pay = $system_service->getTransferCheckSignType(0, $log_info['platform']);
        if (isset($config_pay['check_sign_type'])) {
            if ($config_pay['check_sign_type'] == 3) {
                // 商户单号查询转账单，API只支持查询最近30天内的转账单，超过30天可以通过资金账单对账确认
                $result = $this->wxTransfersV3QueryNew($log_info['out_trade_no'], 0, $log_info['platform']);
                if ($result['code'] != 200) {
                    $rs['code'] = 0;
                    $rs['msg'] = !empty($result['msg']) ? $result['msg'] : '查询失败';
                    return $rs;
                }

                // 组合数据
                $return['code'] = 200;
                $return['info']['transfer_batch'] = [
                    'batch_status' => ($result['info']['state'] == 'SUCCESS' || $result['info']['state'] == 'FAIL') ? 'FINISHED' : '',
                    'fail_num' => $result['info']['state'] == 'FAIL' ? 1 : 0,
                    'success_num' => $result['info']['state'] == 'SUCCESS' ? 1 : 0,
                    'update_time' => $result['info']['update_time']
                ];
                $result = $return;
            } else {
                $result = $this->wxTransfersV3Query($log_info['out_trade_no'], 0, $log_info['platform']);
            }
        } else {
            $result = $this->wxTransfersV3Query($log_info['out_trade_no'], 0, $log_info['platform']);
        }

        if ($result['code'] == 200) {
            $withdrawal_money = $received_money = 0;
            switch ($relate_type) {
                case 1:
                    // 分销商提现
                    $withdrawal_money = $log_info['withdrawal_money'] == 0 ? $log_info['money'] : $log_info['withdrawal_money'];
                    $update_table_name = 'distribution_user';
                    break;
                case 2:
                    // 多商户商家提现
                    $update_table_name = '';
                    break;
                case 3:
                    // 区域代理提现
                    $agent_info = Db::name('area_agent_user')->where(['id' => $log_info['agent_id']])->find();
                    if (!$agent_info) {
                        $rs['code'] = 0;
                        $rs['msg'] = '未找到代理信息';
                        return $rs;
                    }
                    // 增加已提现总金额，减少待打款金额
                    $withdrawal_money = $log_info['withdrawal_money'] == 0 ? $log_info['money'] : $log_info['withdrawal_money'];
                    $received_money = $agent_info['received_money'] + $withdrawal_money;
                    $withdrawal_money = $agent_info['withdrawal_money'] - $withdrawal_money;
                    if ($withdrawal_money < 0) {
                        $withdrawal_money = 0;
                    }
                    $update_table_name = 'area_agent_user';
                    break;
                case 4:
                    // 团队分红提现
                    $agent_info = Db::name('team_user')->where(['id' => $log_info['team_id']])->find();
                    if (!$agent_info) {
                        $rs['code'] = 0;
                        $rs['msg'] = '未找到队长信息';
                        return $rs;
                    }
                    // 增加已提现总金额，减少待打款金额
                    $withdrawal_money = $log_info['withdrawal_money'] == 0 ? $log_info['money'] : $log_info['withdrawal_money'];
                    $received_money = $agent_info['received_money'] + $withdrawal_money;
                    $withdrawal_money = $agent_info['withdrawal_money'] - $withdrawal_money;
                    if ($withdrawal_money < 0) {
                        $withdrawal_money = 0;
                    }
                    $update_table_name = 'team_user';
                    break;
                case 5:
                    // 门店佣金提现
                    $store_agent = Db::name('store_agent')->where('id', $log_info['store_id'])->find();
                    if (!$store_agent) {
                        $rs['code'] = 0;
                        $rs['msg'] = '未找到代理门店信息';
                        return $rs;
                    }
                    // 增加提现金额到门店已提现总金额中
                    $withdrawal_money = $log_info['withdrawal_money'] == 0 ? $log_info['money'] : $log_info['withdrawal_money'];
                    $received_money = $store_agent['received_money'] + $withdrawal_money;
                    $withdrawal_money = $store_agent['withdrawal_money'] - $withdrawal_money;
                    if ($withdrawal_money < 0) {
                        $withdrawal_money = 0;
                    }
                    $update_table_name = 'store_agent';
                    break;
                case 6:
                    // 积分提现
                    $update_table_name = '';
                    break;
                case 7:
                    // 社区团购提现
                    $withdrawal_money = $log_info['withdrawal_money'] == 0 ? $log_info['money'] : $log_info['withdrawal_money'];
                    $update_table_name = 'community_user';
                    break;
                case 8:
                    // 代理股东提现
                    $shareholder = Db::name('shareholder_agent_user')->where('id', $log_info['shareholder_agent_id'])->find();
                    if (!$shareholder) {
                        $rs['code'] = 0;
                        $rs['msg'] = '未找到代理股东信息';
                        return $rs;
                    }
                    // 增加提现金额到股东已提现总金额中
                    $withdrawal_money = $log_info['withdrawal_money'] == 0 ? $log_info['money'] : $log_info['withdrawal_money'];
                    $received_money = $shareholder['received_money'] + $withdrawal_money;
                    $withdrawal_money = $shareholder['withdrawal_money'] - $withdrawal_money;
                    if ($withdrawal_money < 0) {
                        $withdrawal_money = 0;
                    }
                    $update_table_name = 'shareholder_agent_user';
                    break;
                case 9:
                    // 支付返现提现
                    $update_table_name = '';
                    break;
                case 10:
                    // 股东分红提现
                    $shareholder = Db::name('shareholder_user')->where('id', $log_info['shareholder_id'])->find();
                    if (!$shareholder) {
                        $rs['code'] = 0;
                        $rs['msg'] = '未找到股东信息';
                        return $rs;
                    }
                    // 增加提现金额到股东已提现总金额中
                    $withdrawal_money = $log_info['withdrawal_money'] == 0 ? $log_info['money'] : $log_info['withdrawal_money'];
                    $received_money = $shareholder['received_money'] + $withdrawal_money;
                    $withdrawal_money = $shareholder['withdrawal_money'] - $withdrawal_money;
                    if ($withdrawal_money < 0) {
                        $withdrawal_money = 0;
                    }
                    $update_table_name = 'shareholder_user';
                    break;
                default:
                    $update_table_name = '';
            }

            Db::startTrans();
            try {
                if (!empty($result['info']['transfer_batch'])) {
                    // 更新转账状态
                    $update_data = ['update_time' => time()];
                    $transfer_batch = $result['info']['transfer_batch'];
                    if ($transfer_batch['batch_status'] === 'FINISHED') {
                        // 打款失败
                        if (!empty($transfer_batch['fail_num']) && $transfer_batch['success_num'] == 0) {
                            $update_data['status'] = 5;
                        } else {
                            $update_data['status'] = 1;
                            if (!empty($transfer_batch['update_time'])) {
                                $update_data['pay_time'] = strtotime($transfer_batch['update_time']);
                            }
                            switch ($relate_type) {
                                case 1:
                                    // 分销商提现
                                    Db::name('distribution_user')
                                        ->where('id', $log_info['distribution_id'])
                                        ->Inc('received_money', $withdrawal_money)->update();
                                    break;
                                case 2:
                                    // 多商户商家提现
                                    break;
                                case 3:
                                    // 区域代理提现
                                    Db::name('area_agent_user')
                                        ->where(['id' => $log_info['agent_id']])
                                        ->update(['received_money' => $received_money, 'withdrawal_money' => $withdrawal_money]);
                                    break;
                                case 4:
                                    // 团队分红提现
                                    Db::name('team_user')
                                        ->where(['id' => $log_info['team_id']])
                                        ->update(['received_money' => $received_money, 'withdrawal_money' => $withdrawal_money]);
                                    break;
                                case 5:
                                    // 门店佣金提现
                                    Db::name('store_agent')
                                        ->where('id', $log_info['store_id'])
                                        ->update(['received_money' => $received_money, 'withdrawal_money' => $withdrawal_money]);
                                    break;
                                case 6:
                                    // 积分提现
                                    break;
                                case 7:
                                    // 社区团购提现
                                    Db::name('community_user')
                                        ->where('id', $log_info['community_id'])
                                        ->Inc('received_money', $withdrawal_money)->update();
                                    break;
                                case 8:
                                    // 代理股东提现
                                    Db::name('shareholder_agent_user')
                                        ->where('id', $log_info['shareholder_agent_id'])
                                        ->update(['received_money' => $received_money, 'withdrawal_money' => $withdrawal_money]);
                                    break;
                                case 9:
                                    // 支付返现提现
                                    $update_data = [];
                                    $update_data['status'] = 1;
                                    break;
                                case 10:
                                    // 股东分红提现
                                    Db::name('shareholder_user')
                                        ->where('id', $log_info['shareholder_id'])
                                        ->update(['received_money' => $received_money, 'withdrawal_money' => $withdrawal_money]);
                                    break;
                                default:
                            }
                        }
                    }

                    if ($transfer_batch['batch_status'] === 'CLOSED') {
                        $update_data['status'] = 0; // 重新打款
                        $update_data['order_no'] = time() . rand(111, 999);
                        $update_data['out_trade_no'] = time() . rand(111, 999);

                        if ($relate_type == 9) {
                            $update_data = [];
                            $update_data['status'] = 0;
                            $update_data['cash_no'] = time() . rand(111, 999);
                        }
                    }
                }

                if (!empty($update_data) && isset($update_data['status'])) {
                    Db::name($table_name)->where('id', $relate_id)->update($update_data);

                    // 打款失败，返回可提现金额
                    if ($update_data['status'] == 5) {
                        switch ($relate_type) {
                            case 1:
                                // 分销商提现
                                Db::name('distribution_user')
                                    ->where('id', $log_info['distribution_id'])
                                    ->Inc('available_money', $log_info['withdrawal_money'])->update();
                                break;
                            case 2:
                                // 多商户商家提现
                                break;
                            case 3:
                                // 区域代理提现
                                $agent_info = Db::name('area_agent_user')->where(['id' => $log_info['agent_id']])->find();

                                // 增加可提现金额，减少待打款金额
                                $available_money = $agent_info['available_money'] + $log_info['withdrawal_money'];
                                $withdrawal_money = $agent_info['withdrawal_money'] - $log_info['withdrawal_money'];
                                if ($withdrawal_money < 0) {
                                    $withdrawal_money = 0;
                                }
                                Db::name('area_agent_user')
                                    ->where(['id' => $log_info['agent_id']])
                                    ->update(['available_money' => $available_money, 'withdrawal_money' => $withdrawal_money]);
                                break;
                            case 4:
                                // 团队分红提现
                                $agent_info = Db::name('team_user')->where(['id' => $log_info['team_id']])->find();

                                // 增加可提现金额，减少待打款金额
                                $available_money = $agent_info['available_money'] + $log_info['withdrawal_money'];
                                $withdrawal_money = $agent_info['withdrawal_money'] - $log_info['withdrawal_money'];
                                if ($withdrawal_money < 0) {
                                    $withdrawal_money = 0;
                                }
                                Db::name('team_user')
                                    ->where(['id' => $log_info['team_id']])
                                    ->update(['available_money' => $available_money, 'withdrawal_money' => $withdrawal_money]);
                                break;
                            case 5:
                                // 门店佣金提现
                                $store_agent = Db::name('store_agent')->where('id', $log_info['store_id'])->find();

                                // 增加可提现金额，减少待打款金额
                                $available_money = $store_agent['available_money'] + $log_info['withdrawal_money'];
                                $withdrawal_money = $store_agent['withdrawal_money'] - $log_info['withdrawal_money'];
                                if ($withdrawal_money < 0) {
                                    $withdrawal_money = 0;
                                }

                                Db::name('store_agent')
                                    ->where('id', $log_info['store_id'])
                                    ->update(['available_money' => $available_money, 'withdrawal_money' => $withdrawal_money]);
                                break;
                            case 6:
                                // 积分提现
                                break;
                            case 7:
                                // 社区团购提现
                                $community_user = Db::name('community_user')->where('id', $log_info['community_id'])->find();

                                // 增加可提现金额，减少待打款金额
                                $available_money = $community_user['available_money'] + $log_info['withdrawal_money'];
                                $withdrawal_money = $community_user['withdrawal_money'] - $log_info['withdrawal_money'];
                                if ($withdrawal_money < 0) {
                                    $withdrawal_money = 0;
                                }

                                Db::name('community_user')
                                    ->where('id', $log_info['community_id'])
                                    ->update(['available_money' => $available_money, 'withdrawal_money' => $withdrawal_money]);
                                break;
                            case 8:
                                // 代理股东提现
                                $shareholder = Db::name('shareholder_agent_user')
                                    ->where('id', $log_info['shareholder_agent_id'])
                                    ->find();

                                // 增加可提现金额，减少待打款金额
                                $available_money = $shareholder['available_money'] + $log_info['withdrawal_money'];
                                $withdrawal_money = $shareholder['withdrawal_money'] - $log_info['withdrawal_money'];
                                if ($withdrawal_money < 0) {
                                    $withdrawal_money = 0;
                                }

                                Db::name('shareholder_agent_user')
                                    ->where('id', $log_info['shareholder_agent_id'])
                                    ->update(['available_money' => $available_money, 'withdrawal_money' => $withdrawal_money]);
                                break;
                            case 9:
                                // 支付返现提现
                                break;
                            case 10:
                                // 股东分红提现
                                $shareholder = Db::name('shareholder_user')->where('id', $log_info['shareholder_id'])->find();

                                // 增加可提现金额，减少待打款金额
                                $available_money = $shareholder['available_money'] + $log_info['withdrawal_money'];
                                $withdrawal_money = $shareholder['withdrawal_money'] - $log_info['withdrawal_money'];
                                if ($withdrawal_money < 0) {
                                    $withdrawal_money = 0;
                                }

                                Db::name('shareholder_user')
                                    ->where('id', $log_info['shareholder_id'])
                                    ->update(['available_money' => $available_money, 'withdrawal_money' => $withdrawal_money]);
                                break;
                            default:
                        }
                    }
                }

                Db::commit();
            } catch (\Exception $e) {
                Db::rollback();
                $rs['code'] = 0;
                $rs['msg'] = '更新失败';
            }
        } else {
            $rs['code'] = 0;
            $rs['msg'] = !empty($result['msg']) ? $result['msg'] : '查询失败';
        }

        return $rs;
    }

    /**
     * 商家转账用户确认模式下，根据商户单号查询转账单的详细信息
     * @param string $out_batch_no 商家批次单号
     * @param int $mch_id 应用id
     * @param int $platform 平台
     * @return array
     */
    public function wxTransfersV3QueryNew($out_batch_no, $mch_id, $platform = 0)
    {
        $rs = array('code' => 200, 'info' => array(), 'msg' => '');

        $pay_type = 1;
        if ($platform == 4) {
            $pay_type = 2;
        }
        $GLOBALS['pay_type'] = $pay_type;
        $GLOBALS['mch_id'] = $mch_id;
        $GLOBALS['platform'] = $platform;

        $transferApi = new \WechatpayTransferNewApi($mch_id);
        $res = $transferApi->transferQuery($out_batch_no);
        Log::write('商家转账用户确认模式下转账查询结果：' . json_encode($res));
        if ($res['code'] != 200) {
            $rs['code'] = $res['code'];
            $rs['msg'] = $res['msg'];
            return $rs;
        }

        $rs['info'] = $res['info'];
        return $rs;
    }

    /**
     * 商家转账到零钱查询
     * @param string $out_batch_no 商家批次单号
     * @param int $mch_id 应用id
     * @param int $platform 平台
     * @return array
     */
    public function wxTransfersV3Query($out_batch_no, $mch_id, $platform = 0)
    {
        $rs = array('code' => 200, 'info' => array(), 'msg' => '');

        if (!$out_batch_no) {
            $rs['code'] = 0;
            $rs['msg'] = '参数错误';
            return $rs;
        }

        $pay_type = 1;
        if ($platform == 4) {
            $pay_type = 2;
        }
        $GLOBALS['pay_type'] = $pay_type;
        $GLOBALS['mch_id'] = $mch_id;
        $GLOBALS['platform'] = $platform;

        $transferApi = new \WechatpayTransferApi($mch_id);
        $res = $transferApi->transferQuery($out_batch_no);
        Log::write('批量转账查询结果：' . json_encode($res));
        if ($res['code'] != 200) {
            $rs['code'] = $res['code'];
            $rs['msg'] = $res['msg'];
            return $rs;
        }

        $rs['info'] = $res['info'];
        return $rs;
    }

    public function AliWebPay($subject = '', $return_url = '')
    {
        $rs = array('code' => 200, 'info' => array(), 'msg' => '');
        $GLOBALS['pay_type'] = 2;
        $body['mch_id'] = $this->mch_id;
        $body['pay_type'] = 2;
        $body['platform'] = $this->platform;
        /*支付宝支付*/
        $aliConfig = new \AliPayConfig();
        $aopClient = new \AopClient();
        $aopClient->appId = $aliConfig->GetAppId();
        $aopClient->rsaPrivateKey = $aliConfig->GetPrivateKey();
        $aopClient->alipayrsaPublicKey = $aliConfig->GetPublicKey();
        $aopClient->signType = $aliConfig->GetSignType();
        $request = new \AlipayTradePagePayRequest();
        $request->setNotifyUrl($aliConfig->GetNotifyUrl());
        $request->setReturnUrl($return_url);
        $biz_content = array(
            'subject' => empty($subject) ? '支付宝支付' : $subject,
            'out_trade_no' => $this->order_number,
            'total_amount' => $this->pay_price,
            'body' => json_encode($body),
            'product_code' => 'FAST_INSTANT_TRADE_PAY',
        );
        $biz_content['passback_params'] = urlencode('order_no=' . $this->order_info['order_no']);
        $request->setBizContent(json_encode($biz_content));
        //$response = $aopClient->pageExecute($request,'GET');
        $response = $aopClient->pageExecute($request, 'GET');
        $rs['info'] = $response;
        return $rs;
    }

    /**
     *支付宝退款退款
     * @param int $pay_type
     */
    public function Alirefund($pay_type)
    {
        $rs = array('code' => 200, 'info' => array(), 'msg' => '');
        if (empty($this->order_info)) {
            $rs['code'] = 0;
            $rs['msg'] = '订单不存在';
            return $rs;
        }
        $GLOBALS['pay_type'] = $pay_type;
        //支付宝
        if ($pay_type == 1) {
            $config = new \AliPayConfig();
            $aopClient = new \AopClient();
            $aopClient->appId = $config->GetAppId();
            $aopClient->rsaPrivateKey = $config->GetPrivateKey();
            $aopClient->alipayrsaPublicKey = $config->GetPublicKey();
            $aopClient->signType = $config->GetSignType();
            $request = new \AlipayTradeRefundRequest();
            $biz_content = array(
                'out_trade_no' => $this->order_number,
                'refund_amount' => $this->pay_price,
            );
            $request->setBizContent(json_encode($biz_content));
            $response = $aopClient->execute($request);
            $response = json_decode(json_encode($response, true), true);
            $rs['info'] = $response;

            /*{"alipay_trade_refund_response":{"msg":"Business Failed","code":"40004","sub_msg":"参数无效：退款金额不能为空 ","refund_fee":"0.00","sub_code":"ACQ.INVALID_PARAMETER","send_back_fee":"0.00"},"sign":"Lr\/Aqgn0FsLV4Ems7Up4eHZunIJGlJk4Dgxsj3FNwwsmgEodyHp4iXsb+Aq++Sti4PBm7ZTXaKsqSc\/RtSuyrVeUOCS8r0N0H8RapoaGGQ5vP\/wIzmXkdXzdH6wdl4dBt\/GCgRFrfyd7IwxZDrDrRKv0ZlJxhvhpOYFor\/zE+q+jyu4XWYrcnsHb096fPO6XQaDyvPiGv7usdQFDKWifnIUMcubR4O13JgQV98IpqdLZ2xF9zGXEycNDoEfcHoTBEk5DfgHn\/uzp7cHjr07uMz2bYjyh\/0A4wWmDrARwpbpoXxgnDhNMj6fWd7KMohr9KNTfvy3mzQrFx3qDHdLTwA=="}*/
            /*{"alipay_trade_refund_response":{"code":"10000","msg":"Success","buyer_logon_id":"zxd***@zz58.cn","buyer_user_id":"2088502589321670","fund_change":"Y","gmt_refund_pay":"2024-03-07 18:14:40","out_trade_no":"P17086805259123","refund_detail_item_list":[{"amount":"6.00","fund_channel":"PCREDIT"}],"refund_fee":"6.00","send_back_fee":"6.00","trade_no":"2024022322001421671455661000"},"sign":"X\/4X07tINQpbVRvU6oerOEi5sag5S9qO+Z08HJsKNJZp\/MbGPB34IAtLQk9jZa+5hWZBv9Ghw0Xo9gCHMNohiHeEzC3zjAT+XpfgkoxMW0QAzjhgZQ5FG6nBWyem7RihOGTDZrZ2GyH5Hx86jgC7WL\/2kztKhY6KteDmGwXIhjQ\/yAAOEjLlRCBIXlL\/i+sVdDx+kWGoAk8Twni\/5k09+v+6wU20kYdicKOEdh23Y2a0bisGrFyX7yLgTeqeAtmDjFX9Kw2HHfFDJUJfowS3XkPUz4X98FriAhiXClTYXHBJhmb2f8tTEpNxug5HCsKTcauD4twS4FuR+4UVfwA9yg=="}*/
            Log::write('支付宝退款结果' . json_encode($response, JSON_UNESCAPED_UNICODE));
            if ($response['alipay_trade_refund_response']['code'] == '10000') {
                return $rs;
            } else {
                $rs['code'] = 0;
                $rs['msg'] = $response['alipay_trade_refund_response']['sub_msg'];
                return $rs;
            }
        }
    }
}
