<?php
namespace App\Http\Controllers\Mounting\Shop;

use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use DB;
use App\Http\Models\Api\Common;
use App\Services\WeChatApplet\User\LoginUserService;

// 微信支付
class WeChatPayController extends Controller
{
    // protected $appid = 'wx41b6ce312c084edf'; //appid
    // protected $appsecret = 'da7662310b9d8f02705ea31a4f4117cd'; //小程序秘钥
    // protected $mch_id = '1622749720'; //小程序商户号
    // protected $mch_key = 'ebbe8a54fb239e80da5982dde4aec28c'; //商户号-秘钥

    protected $appid = 'wx5a4e9abd1293d052'; //appid
    protected $appsecret = '7f1b3805770021895c2212360994500d'; //小程序秘钥
    protected $mch_id = '1630337978'; //小程序商户号
    protected $mch_key = 'gzjk1111111111111111111111111111'; //商户号-秘钥

    /************************************统一下单开始*************************************************/
    /**|---------------------------------------------------------------------------------
     * @name 统一下单入口
     * @param openid 微信标识
     * @param order_num 订单单号
     * @param name 商品名称
     * @param good_id 商品id
     * @return \Illuminate\Http\JsonResponse
     * @author dou <2020/6/29 17:36>
     * |---------------------------------------------------------------------------------
     */
    public function getToPid(Request $request)
    {
        // 记录日志
        $log_record['request'] = $request->all();
        $log_record['time'] = date('Y-m-d H:i:s');
        $log_record['function'] = 'getToPid';
        logFileRecord($log_record, 'xdc/WeChatPay/getToPid', 2);

        // 查询小程序订单数据
        $find_data = DB::table('shop_order')
            ->where('shor_id', $request['shor_id'])
            ->first();
        if (empty($find_data)) {
            return response()->json(['code' => 500, 'msg' => '请选择支付订单', 'data' => '']);
        }
        // 微信支付金额不能为0
        if ($find_data->shor_order_amount == 0) {
            if ($find_data->shor_pay_state == 1) {
                return response()->json(['code' => 500, 'msg' => '该订单已支付，无需再次支付', 'data' => '']);
            }
        }

        $arr['order_num'] = $find_data->shor_number;
        $arr['goods_paid']= $find_data->shor_order_amount;//订单金额
        // $detail['goods_detail'][0]['goods_id'] = $find_orgo[0]['orgo_goo_id']; //商品名称
        // $detail['goods_detail'][0]['goods_name'] = $find_orgo[0]['orgo_goo_name']; //商品名称
        $detail['goods_detail'][0]['goods_id'] = 123456; //商品名称
        $detail['goods_detail'][0]['goods_name'] = 'shagpin'; //商品名称
        $detail['goods_detail'][0]['quantity'] = '1'; //商品数量
        $detail['goods_detail'][0]['price'] = $arr['goods_paid']; //商品金额
        $params['detail'] = json_encode($detail);
        $params['body'] = $find_data->shor_goo_name;                   //商品描述
        $params['out_trade_no'] = $arr['order_num'];   //自定义的订单号，不能重复
        // $params['opid'] = $arr['opid'];   //openid
        $params['total_fee'] = $arr['goods_paid']; //订单金额，只能为整数单位为分
        $params['trade_type'] = 'NATIVE';
        $res = $this->unifiedOrder($params);
        if ($res['return_code'] == 'SUCCESS') {
            
        } else {
            return response()->json(['code' => 500, 'msg' => $res['err_code_des'], 'data' => []]);
        }
    }

    // 微信支付
    public function unifiedOrder($params)
    {
        $nonce_str = $this->genRandomString();
        $spbill_create_ip = $_SERVER['REMOTE_ADDR'];
        $paramsw['appid'] = $this->appid; //appid
        $paramsw['mch_id'] = $this->mch_id; //mch_id
        $paramsw['nonce_str'] = $nonce_str; //nonce_str
        $paramsw['body'] = $params['body']; //body
        $paramsw['detail'] = $params['detail']; //detail
        // $paramsw['openid'] = $params['opid']; //detail
        $paramsw['out_trade_no'] = $params['out_trade_no']; //out_trade_no
        $paramsw['total_fee'] = $params['total_fee']; //total_fee
        $paramsw['spbill_create_ip'] = $spbill_create_ip; //spbill_create_ip
        $paramsw['notify_url'] = config('filesystems.server_name') . '/index.php/v1/Pay/wechatNotify'; //notify_url
        $paramsw['trade_type'] = $params['trade_type']; //trade_type
        $paramsw['sign_type'] = 'MD5';
        // 获取签名数据
        $sign = $this->MakeSign($paramsw);
        $paramsw['sign'] = $sign;
        $xml = $this->dataToXml($paramsw);
        $response = $this->postXmlCurl($xml, 'https://api.mch.weixin.qq.com/pay/unifiedorder');
        if (!$response) {
            return false;
        }
        $result = $this->xml_to_data($response);
        if (!empty($result['result_code']) && !empty($result['err_code'])) {
            $result['err_msg'] = $this->error_code($result['err_code']);
        }
        return $result;
    }


    // 微信支付回调地址
    public function wechatNotify(Request $request)
    {
        $get_input = file_get_contents("php://input");
        libxml_disable_entity_loader(true);
        $get_input = json_decode(json_encode(simplexml_load_string($get_input, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
        // 记录日志
        $log_record['get_input'] = $get_input;
        $log_record['time'] = date('Y-m-d H:i:s');
        $log_record['function'] = 'wechatNotify';
        logFileRecord($log_record, 'xdc/WeChatPay/wechatNotify', 2);
        error_reporting(0);
        try {
            $find_order = DB::table('order')
                ->leftjoin('order_client', 'orcl_ord_id', '=', 'ord_id')
                ->where('ord_number',$get_input['out_trade_no'])
                ->first();
            DB::beginTransaction();
            if ($find_order['ord_pay_state'] == 1) {
                //告诉微信，我已经处理了，否则微信那边会重复发送数据过来的哦
                $mes=array(
                    'return_code'=>'SUCCESS',
                    'return_msg'=>'OK'
                );
                $find_ord_data = true;
            } else {
                if ($find_order['ord_type'] == 1) {//服务单类型
                    $find_orgo_data = DB::table('order_goods')
                        ->leftjoin('goods', 'goo_id', '=', 'orgo_goo_id')
                        ->where('orgo_ord_id', $find_order['ord_id'])
                        ->get()->toArray();
                    $depa_center_pri = [];
                    foreach ($find_orgo_data as $key => $value) {
                        $update_goods_data['goo_num'] = $value['goo_num'] - $value['orgo_goo_num'];
                        if ($update_goods_data['goo_num'] == 0) {
                            $update_goods_data['goo_state'] = 2;//状态1上架2下架
                        }
                        $update_goods = DB::table('goods')
                            ->where('goo_id', $value['goo_id'])
                            ->update($update_goods_data);//更新商品数量
                        $new_goods_data[$value['goo_depa_id']][] = $value;
                        $depa_key = $value['goo_depa_id'];
                        $find_depa_center_pri = DB::table('department')
                            ->where('depa_id', $depa_key)
                            ->value('depa_center_pri');
                        if (!in_array($find_depa_center_pri,$depa_center_pri)) {
                            $depa_center_pri[] = $find_depa_center_pri;
                        }
                    }

                    if (in_array(1,$depa_center_pri) && in_array(5,$depa_center_pri)) {
                        $two_depa = true;
                    } else {
                        $two_depa = false;
                    }
                    $count_depa = count($new_goods_data);
                    $create_work = true;
                    if ($count_depa == 1) {
                        $find_depa_center_pri = DB::table('department')
                            ->whereIn('depa_id', $depa_center_pri)
                            ->value('depa_center_pri');
                        if ($find_depa_center_pri == 1) {
                            $create_work = false;
                            $update_data['ord_state'] = 4;
                            $data['ord_state'] = 4;
                        }
                    }

                    sort($depa_center_pri);
                    if ($depa_center_pri == [1,4,5]) {
                        $create_work = false;
                    }

                    // 使用余额支付,扣除余额
                    if ($find_order['ord_balance'] == 1) {
                        // 查询我的余额
                        $find_mybalance_details = DB::table('mybalance_details')
                            ->where('myb_user_id', $find_order['orcl_mem_id'])
                            ->where('myb_state', 1)
                            ->orderBy('myb_end_time', 'ASC')
                            ->get()->toArray();
                        if (empty($find_mybalance_details)) {
                            return ['code'=>500, 'msg'=>'余额不足', 'data'=>''];
                        }
                        $ord_payable_amount2 = $find_order['ord_use_balance'];
                        $ord_use_balance = 0;
                        // 扣除充值卡内的金额
                        foreach ($find_mybalance_details as $keymd => $valuemd) {
                            if ($valuemd['myb_remaining_amount'] >= $ord_payable_amount2) {//如果充值剩余金额足够就扣除，剩余充值金额
                                $update_myde['myb_remaining_amount'] = $valuemd['myb_remaining_amount'] - $ord_payable_amount2;
                                $update_myde['myb_update_time'] = date('Y-m-d H:i:s');
                                $update_myde_res = DB::table('mybalance_details')
                                    ->where('myb_id', $valuemd['myb_id'])
                                    ->update($update_myde);
                                $ord_use_balance += $ord_payable_amount2;
                                unset($update_myde);
                                $add_rec_log['relo_rec_money'] = $ord_payable_amount2;//使用充值金额支付的金额
                                $add_rec_log['relo_mem_id'] = $find_order['orcl_mem_id'];
                                $add_rec_log['relo_action'] = '支付订单';
                                $add_rec_log['relo_type'] = 2;
                                $add_rec_log['relo_money'] = $ord_payable_amount2;//总金额
                                $add_rec_log['relo_create_time'] = date('Y-m-d H:i:s');
                                $find_mem_banlance = DB::table('member')
                                    ->where('mem_id', $find_order['orcl_mem_id'])
                                    ->value('mem_balance');
                                $add_rec_log['relo_amount'] = $find_mem_banlance - $ord_payable_amount2;//会员余额
                                $add_rec_log['relo_ord_id'] = $find_order['ord_id'];
                                $add_rec_log['relo_myb_id'] = $valuemd['myb_id'];
                                $rec_log_res = DB::table('rechcard_log')->insertGetId($add_rec_log);
                                $ord_payable_amount2 = 0;
                                break;
                            }

                            if ($valuemd['myb_remaining_amount'] < $ord_payable_amount2) {//此充值卡余额小于支付金额
                                $add_rec_log['relo_rec_money'] = $valuemd['myb_remaining_amount'];
                                $ord_use_balance += $valuemd['myb_remaining_amount'];
                                $ord_payable_amount2 = $ord_payable_amount2 - $valuemd['myb_remaining_amount'];
                                if ($valuemd['myb_gire_amount'] > $ord_payable_amount2) {//此充值卡赠送余额大于支付金额
                                    $update_myde['myb_gire_amount'] = $valuemd['myb_gire_amount'] - $ord_payable_amount2;
                                    $ord_use_balance += $ord_payable_amount2;
                                    
                                    $add_rec_log['relo_mem_id'] = $find_order['orcl_mem_id'];
                                    $add_rec_log['relo_action'] = '支付订单';
                                    $add_rec_log['relo_type'] = 2;
                                    $add_rec_log['relo_money'] = $ord_payable_amount2;//总金额
                                    $add_rec_log['relo_create_time'] = date('Y-m-d H:i:s');
                                    $find_mem_banlance = DB::table('member')
                                        ->where('mem_id', $find_order['orcl_mem_id'])
                                        ->value('mem_balance');
                                    $add_rec_log['relo_amount'] = $find_mem_banlance - $ord_payable_amount2;//会员余额
                                    $add_rec_log['relo_gift_money'] = $ord_payable_amount2;
                                    $add_rec_log['relo_ord_id'] = $find_order['ord_id'];
                                    $rec_log_res = DB::table('rechcard_log')->insertGetId($add_rec_log);
                                    
                                    $ord_payable_amount2 = 0;
                                    $update_myde['myb_remaining_amount'] = 0;
                                    $update_myde['myb_update_time'] = date('Y-m-d H:i:s');
                                    $update_myde_res = DB::table('mybalance_details')
                                        ->where('myb_id', $valuemd['myb_id'])
                                        ->update($update_myde);
                                    unset($update_myde);
                                    break;
                                }
                                if ($valuemd['myb_gire_amount'] <= $ord_payable_amount2) {//此充值卡赠送余额小于支付金额
                                    $update_myde['myb_gire_amount'] = 0;
                                    $update_myde['myb_state'] = 5;//状态1已开启2已暂停3终止4过期5完成6转移
                                    $ord_payable_amount2 = $ord_payable_amount2 - $valuemd['myb_gire_amount'];
                                    $ord_use_balance += $valuemd['myb_gire_amount'];
                                    $add_rec_log['relo_mem_id'] = $find_order['orcl_mem_id'];
                                    $add_rec_log['relo_action'] = '支付订单';
                                    $add_rec_log['relo_type'] = 2;
                                    $add_rec_log['relo_money'] = $valuemd['myb_remaining_amount'] + $valuemd['myb_gire_amount'];//总金额
                                    $add_rec_log['relo_create_time'] = date('Y-m-d H:i:s');
                                    $find_mem_banlance = DB::table('member')
                                        ->where('mem_id', $find_order['orcl_mem_id'])
                                        ->value('mem_balance');
                                    $add_rec_log['relo_amount'] = $find_mem_banlance - $valuemd['myb_remaining_amount']-$valuemd['myb_gire_amount'];//会员余额
                                    $add_rec_log['relo_gift_money'] = $valuemd['myb_gire_amount'];
                                    $add_rec_log['relo_ord_id'] = $find_order['ord_id'];
                                    $add_rec_log['relo_myb_id'] = $valuemd['myb_id'];
                                    $rec_log_res = DB::table('rechcard_log')->insertGetId($add_rec_log);
                                    $update_myde['myb_remaining_amount'] = 0;
                                    $update_myde['myb_update_time'] = date('Y-m-d H:i:s');
                                    $update_myde_res = DB::table('mybalance_details')
                                        ->where('myb_id', $valuemd['myb_id'])
                                        ->update($update_myde);
                                    unset($update_myde);
                                    if ($ord_payable_amount2 == 0) {
                                        break;
                                    }
                                }
                            }
                        }
                        $find_mem_banlance = DB::table('member')
                            ->where('mem_id', $find_order['orcl_mem_id'])
                            ->value('mem_balance');
                        $update_mem['mem_balance'] = $find_mem_banlance - $find_order['ord_use_balance'];//会员余额
                        $update_mem['mem_update_time'] = date('Y-m-d H:i:s');
                        $up_mem_res = DB::table('member')->where('mem_id', $find_order['orcl_mem_id'])->update($update_mem);
                    } else {
                        $update_data['ord_use_balance'] = 0;
                    }

                    // 生成工单
                    if ($find_order['ord_state'] == 2 && $create_work) {//服务订单
                        foreach ($new_goods_data as $key_v => $value_n) {
                            $i = 0;
                            $wor_name = '';
                            $wor_price = 0;
                            $find_depa_center_pri = DB::table('department')
                                ->where('depa_id', $key_v)
                                ->value('depa_center_pri');
                            foreach ($value_n as $key1 => $value1) {
                                if ($find_depa_center_pri != 4 && $value1['orgo_goo_create_work'] == 1) {//服务商品生成服务工单
                                    $work_goods[$i]['wogo_goo_id'] = $value1['goo_id'];
                                    $work_goods[$i]['wogo_goo_name'] = $value1['goo_name'];
                                    $work_goods[$i]['wogo_goo_gocl_id'] = $value1['goo_gocl_id'];
                                    $work_goods[$i]['wogo_depa_id'] = $value1['goo_depa_id'];
                                    $work_goods[$i]['wogo_goo_price'] = $value1['goo_price'];
                                    $wor_name = $wor_name.$value1['goo_name'];
                                    $wor_price += $value1['goo_price'];
                                    $i++;
                                }
                            }
                            if (!empty($work_goods)) {
                                $user_info['adm_department_id'] = 1;
                                $user_info['adm_id'] = 0;
                                $wor_order_number = Common::workRule($user_info, 2);

                                $work_order['wor_number'] = $wor_order_number;
                                $work_order['wor_orcl_id'] = $find_order['ord_orcl_id'];
                                $work_order['wor_wocl_id'] = $find_order['ord_orcl_id'];
                                $work_order['wor_ord_id'] = $find_order['ord_id'];
                                $work_order['wor_name'] = $wor_name;
                                $work_order['wor_state'] = 1;
                                $work_order['wor_depa_id'] = $key_v;
                                $work_order['wor_depa_type'] = $find_depa_center_pri;
                                if ($user_info['adm_department_id'] == $key_v) {
                                    $work_order['wor_oneself'] = 1;//是否自己部门生成的工单
                                } else {
                                    $work_order['wor_oneself'] = 2;
                                }
                                $work_order['wor_create_pro_id'] = 0;
                                $work_order['wor_create_pro_name'] = '客户';
                                $work_order['wor_create_time'] = date('Y-m-d H:i:s');
                                $work_order['wor_price'] = $wor_price;
                                $wor_id = DB::table('work_order')->insertGetId($work_order);
                                foreach ($work_goods as $wgk => $wgv) {
                                    $work_goods[$wgk]['wogo_wor_id'] = $wor_id;
                                }
                                $wogo_res = DB::table('work_goods')->insert($work_goods);
                            }
                        }
                    }

                    $log_data['ord_state'] = $find_order['ord_state'];
                    $log_data['create_work'] = $create_work;
                    $log_data['new_goods_data'] = $new_goods_data;
                    $log_data['work_goods'] = $work_goods;
                    // 记录日志
                    $log_record['get_input'] = $log_data;
                    $log_record['time'] = date('Y-m-d H:i:s');
                    $log_record['function'] = 'wechatNotify';
                    logFileRecord($log_record, 'xdc/WeChatPay/wechatNotify', 2);

                    // 消费记录
                    $add_records['orre_ord_id'] = $find_order['ord_id'];
                    $add_records['orre_mem_id'] = $find_order['orcl_mem_id'];
                    $add_records['orre_ord_number'] = $find_order['ord_number'];
                    $add_records['orre_ord_type'] = $find_order['ord_type'];
                    $add_records['orre_ord_amount'] = $find_order['ord_amount'];
                    $add_records['orre_ord_payment'] = $find_order['ord_amount'];//实付金额
                    $add_records['orre_ord_payway'] = $find_order['ord_payment_way'];
                    $add_records['orre_use_banlance_money'] = $find_order['ord_use_balance'];
                    $add_records['orre_use_other_money'] = $find_order['ord_use_other_pay'];
                    $add_records['orre_use_balance'] = $find_order['ord_balance'];
                    $add_records['orre_create_time'] = date('Y-m-d H:i:s');
                    $add_records['orre_ord_source'] = 2;
                    $add_records['orre_create_adm_id'] = 0;
                    $add_records_res = DB::table('order_record')->insert($add_records);

                    $find_ord_data = DB::table('order')
                        ->where('ord_number', $get_input['out_trade_no'])
                        ->update(['ord_pay_state'=>1,'ord_pay_time'=>date('Y-m-d H:i:s')]);
                }
                if ($find_order['ord_type'] == 2) {//实物单
                    $find_orgo_data = DB::table('order_goods')
                        ->leftjoin('goods', 'goo_id', '=', 'orgo_goo_id')
                        ->where('orgo_ord_id', $find_order['ord_id'])
                        ->get()->toArray();
                    foreach ($find_orgo_data as $key => $value) {
                        $update_goods_data['goo_num'] = $value['goo_num'] - $value['orgo_goo_num'];
                        if ($update_goods_data['goo_num'] == 0) {
                            $update_goods_data['goo_state'] = 2;//状态1上架2下架
                        }
                        $update_goods = DB::table('goods')
                            ->where('goo_id', $value['goo_id'])
                            ->update($update_goods_data);//更新商品数量
                        $new_goods_data[$value['goo_depa_id']][] = $value;
                        $depa_key = $value['goo_depa_id'];
                    }
                    // 使用余额支付,扣除余额
                    if ($find_order['ord_balance'] == 1) {
                        // 查询我的余额
                        $find_mybalance_details = DB::table('mybalance_details')
                            ->where('myb_user_id', $find_order['orcl_mem_id'])
                            ->where('myb_state', 1)
                            ->orderBy('myb_end_time', 'ASC')
                            ->get()->toArray();
                        if (empty($find_mybalance_details)) {
                            return ['code'=>500, 'msg'=>'余额不足', 'data'=>''];
                        }
                        $ord_payable_amount2 = $find_order['ord_use_balance'];
                        $ord_use_balance = 0;
                        // 扣除充值卡内的金额
                        foreach ($find_mybalance_details as $keymd => $valuemd) {
                            if ($valuemd['myb_remaining_amount'] >= $ord_payable_amount2) {//如果充值剩余金额足够就扣除，剩余充值金额
                                $update_myde['myb_remaining_amount'] = $valuemd['myb_remaining_amount'] - $ord_payable_amount2;
                                $update_myde['myb_update_time'] = date('Y-m-d H:i:s');
                                $update_myde_res = DB::table('mybalance_details')
                                    ->where('myb_id', $valuemd['myb_id'])
                                    ->update($update_myde);
                                $ord_use_balance += $ord_payable_amount2;
                                $ord_payable_amount2 = 0;
                                unset($update_myde);
                                $add_rec_log['relo_rec_money'] = $ord_payable_amount2;//使用充值金额支付的金额
                                $add_rec_log['relo_mem_id'] = $find_order['orcl_mem_id'];
                                $add_rec_log['relo_action'] = '支付订单';
                                $add_rec_log['relo_type'] = 2;
                                $add_rec_log['relo_money'] = $ord_payable_amount2;//总金额
                                $add_rec_log['relo_create_time'] = date('Y-m-d H:i:s');
                                $find_mem_banlance = DB::table('member')
                                    ->where('mem_id', $find_order['orcl_mem_id'])
                                    ->value('mem_balance');
                                $add_rec_log['relo_amount'] = $find_mem_banlance - $ord_payable_amount2;//会员余额
                                $add_rec_log['relo_ord_id'] = $find_order['ord_id'];
                                $add_rec_log['relo_myb_id'] = $valuemd['myb_id'];
                                $rec_log_res = DB::table('rechcard_log')->insertGetId($add_rec_log);
                                break;
                            }

                            if ($valuemd['myb_remaining_amount'] < $ord_payable_amount2) {//此充值卡余额小于支付金额
                                $add_rec_log['relo_rec_money'] = $valuemd['myb_remaining_amount'];
                                $ord_use_balance += $valuemd['myb_remaining_amount'];
                                $ord_payable_amount2 = $ord_payable_amount2 - $valuemd['myb_remaining_amount'];
                                if ($valuemd['myb_gire_amount'] > $ord_payable_amount2) {//此充值卡赠送余额大于支付金额
                                    $update_myde['myb_gire_amount'] = $valuemd['myb_gire_amount'] - $ord_payable_amount2;
                                    $ord_use_balance += $ord_payable_amount2;
                                    
                                    $add_rec_log['relo_mem_id'] = $find_order['orcl_mem_id'];
                                    $add_rec_log['relo_action'] = '支付订单';
                                    $add_rec_log['relo_type'] = 2;
                                    $add_rec_log['relo_money'] = $ord_payable_amount2;//总金额
                                    $add_rec_log['relo_create_time'] = date('Y-m-d H:i:s');
                                    $find_mem_banlance = DB::table('member')
                                        ->where('mem_id', $find_order['orcl_mem_id'])
                                        ->value('mem_balance');
                                    $add_rec_log['relo_amount'] = $find_mem_banlance - $ord_payable_amount2;//会员余额
                                    $add_rec_log['relo_gift_money'] = $ord_payable_amount2;
                                    $add_rec_log['relo_ord_id'] = $find_order['ord_id'];
                                    $rec_log_res = DB::table('rechcard_log')->insertGetId($add_rec_log);
                                    
                                    $ord_payable_amount2 = 0;
                                    $update_myde['myb_remaining_amount'] = 0;
                                    $update_myde['myb_update_time'] = date('Y-m-d H:i:s');
                                    $update_myde_res = DB::table('mybalance_details')
                                        ->where('myb_id', $valuemd['myb_id'])
                                        ->update($update_myde);
                                    unset($update_myde);
                                    break;
                                }
                                if ($valuemd['myb_gire_amount'] <= $ord_payable_amount2) {//此充值卡赠送余额小于支付金额
                                    $update_myde['myb_gire_amount'] = 0;
                                    $update_myde['myb_state'] = 5;//状态1已开启2已暂停3终止4过期5完成6转移
                                    $ord_payable_amount2 = $ord_payable_amount2 - $valuemd['myb_gire_amount'];
                                    $ord_use_balance += $valuemd['myb_gire_amount'];
                                    $add_rec_log['relo_mem_id'] = $find_order['orcl_mem_id'];
                                    $add_rec_log['relo_action'] = '支付订单';
                                    $add_rec_log['relo_type'] = 2;
                                    $add_rec_log['relo_money'] = $valuemd['myb_remaining_amount'] + $valuemd['myb_gire_amount'];//总金额
                                    $add_rec_log['relo_create_time'] = date('Y-m-d H:i:s');
                                    $find_mem_banlance = DB::table('member')
                                        ->where('mem_id', $find_order['orcl_mem_id'])
                                        ->value('mem_balance');
                                    $add_rec_log['relo_amount'] = $find_mem_banlance - $valuemd['myb_remaining_amount']-$valuemd['myb_gire_amount'];//会员余额
                                    $add_rec_log['relo_gift_money'] = $valuemd['myb_gire_amount'];
                                    $add_rec_log['relo_ord_id'] = $find_order['ord_id'];
                                    $add_rec_log['relo_myb_id'] = $valuemd['myb_id'];
                                    $rec_log_res = DB::table('rechcard_log')->insertGetId($add_rec_log);
                                    $update_myde['myb_remaining_amount'] = 0;
                                    $update_myde['myb_update_time'] = date('Y-m-d H:i:s');
                                    $update_myde_res = DB::table('mybalance_details')
                                        ->where('myb_id', $valuemd['myb_id'])
                                        ->update($update_myde);
                                    unset($update_myde);
                                    if ($ord_payable_amount2 == 0) {
                                        break;
                                    }
                                }
                            }
                        }
                        $find_mem_banlance = DB::table('member')
                            ->where('mem_id', $find_order['orcl_mem_id'])
                            ->value('mem_balance');
                        $update_mem['mem_balance'] = $find_mem_banlance - $ord_use_balance;//会员余额
                        $update_mem['mem_update_time'] = date('Y-m-d H:i:s');
                        $up_mem_res = DB::table('member')->where('mem_id', $find_order['orcl_mem_id'])->update($update_mem);
                    } else {
                        $update_data['ord_use_balance'] = 0;
                    }

                    // 消费记录
                    $add_records['orre_ord_id'] = $find_order['ord_id'];
                    $add_records['orre_mem_id'] = $find_order['orcl_mem_id'];
                    $add_records['orre_ord_number'] = $find_order['ord_number'];
                    $add_records['orre_ord_type'] = $find_order['ord_type'];
                    $add_records['orre_ord_amount'] = $find_order['ord_amount'];
                    $add_records['orre_ord_payment'] = $find_order['ord_amount'];//实付金额
                    $add_records['orre_ord_payway'] = $find_order['ord_payment_way'];
                    $add_records['orre_use_banlance_money'] = $find_order['ord_use_balance'];
                    $add_records['orre_use_other_money'] = $find_order['ord_use_other_pay'];
                    $add_records['orre_use_balance'] = $find_order['ord_balance'];
                    $add_records['orre_create_time'] = date('Y-m-d H:i:s');
                    $add_records['orre_ord_source'] = 2;
                    $add_records['orre_create_adm_id'] = 0;
                    $add_records_res = DB::table('order_record')->insert($add_records);
                    $find_ord_data = DB::table('order')
                        ->where('ord_number', $get_input['out_trade_no'])
                        ->update(['ord_pay_state'=>1,'ord_state'=>4,'ord_pay_time'=>date('Y-m-d H:i:s')]);
                }
                if ($find_order['ord_type'] == 3) {//订单类型1服务单2实物单3充值卡4会员卡5权益单
                    $rechard_data = DB::table('order_goods')
                        ->leftjoin('rechcard', 'rec_id', '=', 'orgo_goo_id')
                        ->where('orgo_ord_id', $find_order['ord_id'])
                        ->select('rec_name', 'rec_rechargeje', 'rec_giveje', 'rec_proportion_id', 'rec_long', 'rec_id', 'orgo_goo_num', 'rec_end_time', 'orgo_goo_act_price')
                        ->get()->toArray();
                    $find_mem_banlance = DB::table('member')
                        ->where('mem_id', $find_order['orcl_mem_id'])
                        ->value('mem_balance');
                    foreach ($rechard_data as $key => $value) {
                        // 添加我的充值
                        $add_rec['myb_rec_id'] = $value['rec_id'];
                        $add_rec['myb_ord_id'] = $find_order['ord_id'];
                        $add_rec['myb_user_id'] = $find_order['orcl_mem_id'];
                        $add_rec['myb_rec_name'] = $value['rec_name'];
                        $add_rec['myb_rec_money'] = $value['rec_rechargeje'];
                        $add_rec['myb_gift_amount'] = $value['rec_giveje'];
                        $add_rec['myb_remaining_amount'] = $value['rec_rechargeje'];//充值剩余金额
                        $add_rec['myb_gire_amount'] = $value['rec_giveje'];//赠送剩余金额
                        $add_rec['myb_state'] = 1;
                        $add_rec['myb_rec_time'] = date('Y-m-d H:i:s');
                        $add_rec['myb_code'] = 'CZ'.time().rand(10000,99999);
                        $add_rec['myb_rec_long'] = $value['rec_long'];
                        $add_rec['myb_end_time'] = $value['rec_end_time'];
                        $myb_id = DB::table('mybalance_details')->insertGetId($add_rec);
                        if (!$myb_id) {
                            return ['code'=>500, 'msg'=>'充值失败', 'data'=>''];
                        }
                        // 虚拟充值卡数量减一,激活数量加一
                        $rec_data = DB::table('rechcard')
                            ->where('rec_id', $value['rec_id'])
                            ->select('rec_surplus_num', 'rec_active_num', 'rec_state')
                            ->first();
                        $update_rec['rec_surplus_num'] = $rec_data['rec_surplus_num'] - 1;
                        if ($update_rec['rec_surplus_num'] == 0) {
                            $update_rec['rec_state'] = 2;
                        }
                        $update_rec['rec_active_num'] = $rec_data['rec_active_num'] + 1;
                        $update_rec['rec_update_time'] = date('Y-m-d H:i:s');
                        $update_rec_res = DB::table('rechcard')->where('rec_id', $value['rec_id'])->update($update_rec);
                        // 操作记录
                        $add_log['myblo_myb_id'] = $myb_id;
                        $add_log['myblo_create_id'] = 0;
                        $add_log['myblo_create_name'] = '客户购买充值卡';
                        $add_log['myblo_create_phone'] = $find_order['orcl_mem_phone'];
                        $add_log['myblo_create_type'] = 2;//1pc2小程序
                        $add_log['myblo_create_time'] = date('Y-m-d H:i:s');
                        $add_log['myblo_act'] = '创建';
                        $add_log['myblo_amount'] = $value['rec_rechargeje'];
                        $add_log['myblo_gift_amount'] = $value['rec_giveje'];
                        $add_log['myblo_remark'] = '小程序购买';
                        $add_log_res = DB::table('myb_log')->insertGetId($add_log);

                        // 余额记录
                        $add_rec_log['relo_mem_id'] = $find_order['orcl_mem_id'];
                        $add_rec_log['relo_action'] = '充值';
                        $add_rec_log['relo_type'] = 1; //类型1收入2支出
                        $add_rec_log['relo_money'] = $value['rec_giveje'] + $value['rec_rechargeje'];
                        $add_rec_log['relo_create_time'] = date('Y-m-d H:i:s');
                        $add_rec_log['relo_amount'] = $find_mem_banlance + $value['rec_giveje'] + $value['rec_rechargeje'];
                        $add_rec_log['relo_gift_money'] = $value['rec_giveje'];
                        $add_rec_log['relo_rec_money'] = $value['rec_rechargeje'];
                        $add_rec_log['relo_ord_id'] = 0;
                        $add_rec_log_res = DB::table('rechcard_log')->insertGetId($add_rec_log);
                    }

                    $mem_balance = $find_mem_banlance+$value['rec_rechargeje']+$value['rec_giveje'];
                    $mem_res = DB::table('member')
                        ->where('mem_id', $find_order['orcl_mem_id'])
                        ->update(['mem_rank'=>2,'mem_balance'=>$mem_balance, 'mem_update_time'=>date('Y-m-d H:i:s')]);
                    // 消费记录
                    $add_records['orre_ord_id'] = $find_order['ord_id'];
                    $add_records['orre_mem_id'] = $find_order['orcl_mem_id'];
                    $add_records['orre_ord_number'] = $find_order['ord_number'];
                    $add_records['orre_ord_type'] = $find_order['ord_type'];
                    $add_records['orre_ord_amount'] = $find_order['ord_amount'];
                    $add_records['orre_ord_payment'] = $find_order['ord_amount'];
                    $add_records['orre_ord_payway'] = $find_order['ord_payment_way'];
                    $add_records['orre_use_balance'] = $find_order['ord_balance'];//是否使用余额1是2否
                    $add_records['orre_create_time'] = date('Y-m-d H:i:s');
                    $add_records['orre_ord_source'] = 2;
                    $add_records['orre_create_adm_id'] = 0;
                    $add_records_res = DB::table('order_record')->insert($add_records);
                    $find_ord_data = DB::table('order')
                        ->where('ord_number', $get_input['out_trade_no'])
                        ->update(['ord_pay_state'=>1,'ord_state'=>5,'ord_pay_time'=>date('Y-m-d H:i:s')]);
                }
                if ($find_order['ord_type'] == 4) {//4会员卡
                    $find_orgo = DB::table('order_goods')
                        ->leftjoin('vipcard', 'vipc_id', '=', 'orgo_goo_id')
                        ->where('orgo_ord_id', $find_order['ord_id'])
                        ->get()->toArray();
                    foreach ($find_orgo as $key => $value) {
                        for ($i=0; $i < $value['orgo_goo_num']; $i++) { 
                            // 添加我的vip卡
                            $add_vip['myvi_type'] = 1;
                            $add_vip['myvi_vica_id'] = $value['vipc_id'];
                            $add_vip['myvi_depa_id'] = $value['vipc_depa_id'];
                            $add_vip['myvi_mem_id'] = $find_order['orcl_mem_id'];
                            $add_vip['myvi_vica_name'] = $value['vipc_name'];
                            $add_vip['myvi_vica_num'] = $value['vipc_quantity'];
                            $add_vip['myvi_vipc_quantity_all'] = $value['vipc_quantity_all'];
                            $add_vip['myvi_vica_sunum'] = $value['vipc_quantity'];
                            $add_vip['myvi_vica_state'] = 1;
                            $add_vip['myvi_vica_create_time'] = date('Y-m-d H:i:s');
                            $add_vip['myvi_vica_start_time'] = date('Y-m-d H:i:s');
                            $add_vip['myvi_number'] = 'VIP'.time().rand(10000,99999);
                            $add_vip['myvi_long'] = $value['vipc_long'];
                            $add_vip['myvi_ord_id'] = $find_order['ord_id'];
                            $add_vip['myvi_effect_time'] = $value['vipc_termval'];
                            $add_vip['myvi_vica_end_time'] =date('Y-m-d H:i:s', (time() + $value['vipc_termval'] * 24 * 3600));
                            $myvi_id = DB::table('myvipcard')->insertGetId($add_vip);
                            if (!$myvi_id) {
                                return ['code'=>500, 'msg'=>'新增会员卡失败', 'data'=>''];
                            }
                            
                            // 操作记录
                            $add_log['mvop_create_id'] = 0;
                            $add_log['mvop_myvi_id'] = $myvi_id;
                            $add_log['mvop_create_name'] = $find_order['orcl_mem_name'];
                            $add_log['mvop_phone'] = $find_order['orcl_mem_phone'];
                            $add_log['mvop_detail'] = '创建';
                            $add_log['mvop_type'] = 2;
                            $add_log['mvop_create_time'] = date('Y-m-d H:i:s');
                            $add_log['mvop_remark'] = '客户购买会员卡';
                            $mvop_id = DB::table('myvip_operation')->insertGetId($add_log);
                            if (!$mvop_id) {
                                return ['code'=>500, 'msg'=>'新增会员卡失败', 'data'=>''];
                            }
                            if ($add_vip['myvi_vica_start_time']) {
                                $year = substr($add_vip['myvi_vica_start_time'], 0,4);
                                $month = substr($add_vip['myvi_vica_start_time'], 5,2);

                                $yearend = substr($add_vip['myvi_vica_end_time'], 0,4);
                                $monthend = substr($add_vip['myvi_vica_end_time'], 5,2);
                                $use_days = 0;
                                for ($y=$year; $y <= $yearend; $y++) {
                                    if ($add_vip['myvi_effect_time'] == 0) {
                                        return ['code' => 500, 'msg' => '有效期错误，请重新设置', 'data' => ''];
                                    } 
                                    $price = intval($value['orgo_goo_act_price']/$add_vip['myvi_effect_time']);
                                    $j = 0;
                                    for ($i=1; $i < 13; $i++) {
                                        $startDay=$y.'-'.$i.'-1'.' 00:00:00';
                                        $endDay=$y.'-'.$i.'-'.date('t',strtotime($startDay)).' 23:59:59';
                                        if (strtotime($add_vip['myvi_vica_start_time']) > strtotime($startDay)) {
                                            $startDay = $add_vip['myvi_vica_start_time'];
                                        }
                                        if (strtotime($add_vip['myvi_vica_end_time']) < strtotime($endDay)) {
                                            $endDay = $add_vip['myvi_vica_end_time'];
                                        }
                                        if (strtotime($add_vip['myvi_vica_start_time']) > strtotime($endDay) || strtotime($add_vip['myvi_vica_end_time']) < strtotime($startDay)) {
                                            $m[$j]['day'] = 0;
                                            $m[$j]['amount'] = 0;
                                            $use_day = 0;
                                        } else {
                                            $use_day = ceil((strtotime($endDay) - strtotime($startDay))/86400);
                                            if (($add_vip['myvi_effect_time'] - $use_days) < $use_day) {
                                                $use_day = $add_vip['myvi_effect_time'] - $use_days;
                                            }
                                            $m[$j]['day'] = $use_day;
                                            $m[$j]['amount'] = $use_day*$price;
                                        }
                                        $use_days += $use_day;//累加天数
                                        $j++;
                                    }
                                    $add_vip_price['mvap_myvi_id'] = $myvi_id;
                                    $add_vip_price['mvap_year'] = $y;
                                    $add_vip_price['mvap_m1']  =  $m[0]['amount'];
                                    $add_vip_price['mvap_m2']  =  $m[1]['amount'];
                                    $add_vip_price['mvap_m3']  =  $m[2]['amount'];
                                    $add_vip_price['mvap_m4']  =  $m[3]['amount'];
                                    $add_vip_price['mvap_m5']  =  $m[4]['amount'];
                                    $add_vip_price['mvap_m6']  =  $m[5]['amount'];
                                    $add_vip_price['mvap_m7']  =  $m[6]['amount'];
                                    $add_vip_price['mvap_m8']  =  $m[7]['amount'];
                                    $add_vip_price['mvap_m9']  =  $m[8]['amount'];
                                    $add_vip_price['mvap_m10'] =  $m[9]['amount'];
                                    $add_vip_price['mvap_m11'] = $m[10]['amount'];
                                    $add_vip_price['mvap_m12'] = $m[11]['amount'];
                                    $add_vip_price_res = DB::table('myvi_avgprice')->insertGetId($add_vip_price);
                                }
                            }
                        }
                        $find_vipc = DB::table('vipcard')
                            ->where('vipc_id', $value['vipc_id'])
                            ->update(['vipc_active_num'=>$value['vipc_active_num']+$value['orgo_goo_num'],'vipc_surplus_num'=>$value['vipc_surplus_num']-$value['orgo_goo_num'],'vipc_sale_num'=>$value['vipc_sale_num']+$value['orgo_goo_num']]);
                    }
                    // 消费记录
                    $add_records['orre_ord_id'] = $find_order['ord_id'];
                    $add_records['orre_mem_id'] = $find_order['orcl_mem_id'];
                    $add_records['orre_ord_number'] = $find_order['ord_number'];
                    $add_records['orre_ord_type'] = $find_order['ord_type'];
                    $add_records['orre_ord_amount'] = $find_order['ord_amount'];
                    $add_records['orre_ord_payment'] = $find_order['ord_amount'];//实付金额
                    $add_records['orre_ord_payway'] = $find_order['ord_payment_way'];
                    $add_records['orre_use_balance'] = $find_order['use_balance'];
                    $add_records['orre_create_time'] = date('Y-m-d H:i:s');
                    $add_records['orre_ord_source'] = 2;
                    $add_records['orre_create_adm_id'] = 0;
                    $add_records_res = DB::table('order_record')->insert($add_records);
                    $find_ord_data = DB::table('order')
                        ->where('ord_number', $get_input['out_trade_no'])
                        ->update(['ord_pay_state'=>1,'ord_pay_time'=>date('Y-m-d H:i:s'),'ord_payable_amount'=>$find_order['ord_use_other_pay']]);
                }
                if ($find_order['ord_type'] == 5) {//5权益单
                    $find_orgo = DB::table('order_goods')
                        ->leftjoin('equity', 'equ_id', '=', 'orgo_goo_id')
                        ->where('orgo_ord_id', $find_order['ord_id'])
                        ->get()->toArray();
                    foreach ($find_orgo as $key => $value) {
                        for ($i=0; $i < $value['orgo_goo_num']; $i++) { 
                            // 添加我的权益
                            $add_myequ['meeq_equ_id'] = $value['equ_id'];
                            $add_myequ['meeq_mem_id'] = $find_order['orcl_mem_id'];
                            $add_myequ['meeq_equ_depa_id'] = $value['equ_depa_id'];
                            $add_myequ['meeq_equ_name'] = $value['equ_name'];
                            $add_myequ['meeq_equ_state'] = 1;
                            $add_myequ['meeq_create_time'] = date('Y-m-d H:i:s');
                            $add_myequ['meeq_code'] = 'QY'.time().rand(10000,99999);
                            $add_myequ['meeq_long'] = $value['equ_long'];
                            $add_myequ['meeq_ord_id'] = $find_order['ord_id'];
                            $add_myequ['meeq_effect_time'] = $value['equ_effect_time'];
                            $add_myequ['meeq_end_time'] =date('Y-m-d H:i:s', (time() + $value['equ_effect_time'] * 24 * 3600));
                            $add_myequ['meeq_open_time'] = date('Y-m-d H:i:s'); //开启时间
                            $myequ_id = DB::table('member_equity')->insertGetId($add_myequ);
                            if (!$myequ_id) {
                                return ['code'=>500, 'msg'=>'权益购买失败', 'data'=>''];
                            }

                            $find_equ = DB::table('equity')
                                ->where('equ_id', $value['equ_id'])
                                ->first();
                            $update_equ['equ_vicard_active_num'] = $find_equ['equ_vicard_active_num'] + 1;
                            $update_equ['equ_vicard_surplus_num'] = $find_equ['equ_vicard_surplus_num'] - 1;
                            $update_equ['equ_update_time'] = date('Y-m-d H:i:s');
                            $update_equ_res = DB::table('equity')
                                ->where('equ_id', $value['equ_id'])
                                ->update($update_equ);

                            // 操作记录
                            $add_log['eqlo_create_id'] = 0;
                            $add_log['eqlo_create_name'] = '客户';
                            $add_log['eqlo_create_phone'] = '';
                            $add_log['eqlo_create_type'] = 1;
                            $add_log['eqlo_create_time'] = date('Y-m-d H:i:s');
                            $add_log['eqlo_remark'] = '客户购买权益';
                            $add_log['eqlo_myequ_id'] = $myequ_id;
                            $add_equ_logres = DB::table('equity_log')->insertGetId($add_log);
                            $find_equ_goods = DB::table('equity_goods')
                                ->where('eqgo_equ_id', $value['equ_id'])
                                ->get()->toArray();
                            if ($find_equ_goods) {
                                $count_price = 0;
                                foreach ($find_equ_goods as $key_n => $value_n) {
                                    $count_price += ($value_n['eqgo_goo_price']*$value_n['eqgo_goo_num']);
                                }
                                foreach ($find_equ_goods as $ekey => $eval) {
                                    // 添加我的权益商品
                                    $add_mego['mego_meeq_id'] = $myequ_id;
                                    $add_mego['mego_eqgo_id'] = $eval['eqgo_id'];
                                    $add_mego['mego_mem_id'] = $find_order['orcl_mem_id'];
                                    $add_mego['mego_eqgo_goo_id'] = $eval['eqgo_goo_id'];
                                    $add_mego['mego_eqgo_goo_name'] = $eval['eqgo_goo_name'];
                                    $add_mego['mego_eqgo_goo_depa_id'] = $eval['eqgo_goo_depa_id'];
                                    $add_mego['mego_eqgo_goo_num'] = $eval['eqgo_goo_num'];
                                    $add_mego['mego_eqgo_goo_price'] = ($eval['eqgo_goo_price']/$count_price)*$find_order['ord_payable_amount'];
                                    $add_mego['mego_eqgo_goo_sunum'] = $eval['eqgo_goo_num'];
                                    $add_mego['mego_eqgo_goo_expiry_date'] = $eval['eqgo_goo_expiry_date'];
                                    $add_mego_res = DB::table('member_equity_goods')->insertGetId($add_mego);
                                    if (!$add_mego_res) {
                                        return ['code'=>500, 'msg'=>'权益购买失败', 'data'=>''];
                                    }
                                }
                            }
                        }
                    }
                    // 消费记录
                    $add_records['orre_ord_id'] = $find_order['ord_id'];
                    $add_records['orre_mem_id'] = $find_order['orcl_mem_id'];
                    $add_records['orre_ord_number'] = $find_order['ord_number'];
                    $add_records['orre_ord_type'] = $find_order['ord_type'];
                    $add_records['orre_ord_amount'] = $find_order['ord_amount'];
                    $add_records['orre_ord_payment'] = $find_order['ord_amount'];//实付金额
                    $add_records['orre_ord_payway'] = $find_order['ord_payment_way'];
                    $add_records['orre_use_balance'] = $find_order['ord_balance'];
                    $add_records['orre_create_time'] = date('Y-m-d H:i:s');
                    $add_records['orre_ord_source'] = 2;
                    $add_records['orre_create_adm_id'] = 0;
                    $add_records_res = DB::table('order_record')->insert($add_records);
                    $find_ord_data = DB::table('order')
                        ->where('ord_number', $get_input['out_trade_no'])
                        ->update(['ord_pay_state'=>1,'ord_pay_time'=>date('Y-m-d H:i:s'),'ord_state'=>5, 'ord_payable_amount'=>$find_order['ord_use_other_pay']]);
                }
                $update_mem_res = DB::table('member')
                    ->where('mem_id', $find_order['orcl_mem_id'])
                    ->update(['mem_banlance_lock'=>2,'mem_update_time'=>date('Y-m-d H:i:s')]);
            }
            
            if ($find_ord_data) {
                DB::commit();
                //告诉微信，我已经处理了，否则微信那边会重复发送数据过来的哦
                $mes=array(
                    'return_code'=>'SUCCESS',
                    'return_msg'=>'OK'
                );
                $pay_data = 'success';
            }
        } catch (\Exception $e) {
            DB::rollBack();
            $pay_data = $e->getMessage();
            $log_record['code'] = 'error';
            $mes=array(
                'return_code'=>'Error',
                'return_msg'=>'OK'
            );
        }
        // 记录日志
        $log_record1['request'] = $request->all();
        $log_record1['data'] = $pay_data;
        $log_record1['get_input'] = $get_input;
        $log_record1['time'] = date('Y-m-d H:i:s');
        $log_record1['function'] = 'wechatNotify';
        logFileRecord($log_record1, 'xdc/WeChatPay/wechatNotify', 2);
        return $this->dataToXml($mes);
    }

    /**
     * 产生一个指定长度的随机字符串,并返回给用户
     * @param type $len 产生字符串的长度
     * @return string 随机字符串
     */
    public function genRandomString($len = 32)
    {
        $chars = array(
            "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k",
            "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v",
            "w", "x", "y", "z", "A", "B", "C", "D", "E", "F", "G",
            "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R",
            "S", "T", "U", "V", "W", "X", "Y", "Z", "0", "1", "2",
            "3", "4", "5", "6", "7", "8", "9"
        );
        $charsLen = count($chars) - 1;
        // 将数组打乱
        shuffle($chars);
        $output = "";
        for ($i = 0; $i < $len; $i++) {
            $output .= $chars[mt_rand(0, $charsLen)];
        }
        return $output;
    }

    /**
     * 生成签名
     *  @return 签名
     */
    public function MakeSign($params)
    {
        // 签名步骤一：按字典序排序数组参数
        ksort($params);
        $string = $this->toUrlParams($params);
        // 签名步骤二：在string后加入KEY(商户秘钥)
        $string = $string . "&key=".$this->mch_key;
        // 签名步骤三：MD5加密
        $string = md5($string);
        // 签名步骤四：所有字符转为大写
        $result = strtoupper($string);
        return $result;
    }

    /**
     * 将参数拼接为url: key=value&key=value
     * @param   $params
     * @return  string
     */
    public function toUrlParams($params)
    {
        $string = '';
        if (!empty($params)) {
            $array = array();
            foreach ($params as $key => $value) {
                $array[] = $key . '=' . $value;
            }
            $string = implode("&", $array);
        }
        return $string;
    }

    /**
     * 输出xml字符
     * @param   $params     参数名称
     * return   string      返回组装的xml
     **/
    public function dataToXml($params)
    {
        if (!is_array($params) || count($params) <= 0) {
            return false;
        }

        $xml = "<xml>";
        foreach ($params as $key => $val) {
            if (is_numeric($val)) {
                $xml .= "<" . $key . ">" . $val . "</" . $key . ">";
            } else {
                $xml .= "<" . $key . "><![CDATA[" . $val . "]]></" . $key . ">";
            }
        }
        $xml .= "</xml>";
        return $xml;
    }

    /**
     * 以post方式提交xml到对应的接口url
     *
     * @param string $xml  需要post的xml数据
     * @param string $url  url
     * @param bool $useCert 是否需要证书，默认不需要
     * @param int $second   url执行超时时间，默认30s
     * @throws WxPayException
     */
    public function postXmlCurl($xml, $url, $useCert = false, $second = 30)
    {
        $ch = curl_init();
        // 设置超时
        curl_setopt($ch, CURLOPT_TIMEOUT, $second);
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
        // 设置header
        curl_setopt($ch, CURLOPT_HEADER, FALSE);
        // 要求结果为字符串且输出到屏幕上
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
        // if ($useCert == true) {
        //     //设置证书
        //     //使用证书：cert 与 key 分别属于两个.pem文件
        //     curl_setopt($ch, CURLOPT_SSLCERTTYPE, 'PEM');
        //     curl_setopt($ch, CURLOPT_SSLCERT, './Wxpay/apiclient_cert.pem');
        //     curl_setopt($ch, CURLOPT_SSLKEYTYPE, 'PEM');
        //     curl_setopt($ch, CURLOPT_SSLKEY, './Wxpay/apiclient_key.pem');
        // }
        // dump(config('apisystem.server_name') . 'pay/weixin/dcps/apiclient_key.pem');die;
        if ($useCert == true) {
            // 设置证书
            // 使用证书：cert 与 key 分别属于两个.pem文件
            curl_setopt($ch, CURLOPT_SSLCERTTYPE, 'PEM');
            curl_setopt($ch, CURLOPT_SSLCERT, public_path('pay/weixin/dcps/apiclient_cert.pem'));
            curl_setopt($ch, CURLOPT_SSLKEYTYPE, 'PEM');
            curl_setopt($ch, CURLOPT_SSLKEY, public_path('pay/weixin/dcps/apiclient_key.pem'));
        }
        // post提交方式
        curl_setopt($ch, CURLOPT_POST, TRUE);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
        // 运行curl
        $data = curl_exec($ch);
        // 返回结果
        if ($data) {
            curl_close($ch);
            return $data;
        } else {
            $error = curl_errno($ch);
            curl_close($ch);
            return false;
        }
    }

    public function postXmlCurls($xml, $url)
    {
        $ch = curl_init();
        //设置超时
        curl_setopt($ch, CURLOPT_TIMEOUT, $second);
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
        //设置header
        curl_setopt($ch, CURLOPT_HEADER, FALSE);
        //要求结果为字符串且输出到屏幕上
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
        // if($useCert == true){
        //设置证书
        //使用证书：cert 与 key 分别属于两个.pem文件
        curl_setopt($ch, CURLOPT_SSLCERTTYPE, 'PEM');
        curl_setopt($ch, CURLOPT_SSLCERT, './Lib/Action/Wxpay/apiclient_cert.pem');
        curl_setopt($ch, CURLOPT_SSLKEYTYPE, 'PEM');
        curl_setopt($ch, CURLOPT_SSLKEY, './Lib/Action/Wxpay/apiclient_key.pem');

        // }
        //post提交方式
        curl_setopt($ch, CURLOPT_POST, TRUE);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
        //运行curl
        $data = curl_exec($ch);
        //返回结果
        if ($data) {
            curl_close($ch);
            return $data;
        } else {
            $error = curl_errno($ch);
            curl_close($ch);
            return false;
        }
    }

    /**
     * 错误代码
     * @param  $code       服务器输出的错误代码
     * return string
     */
    public function error_code($code)
    {
        $errList = array(
            'NOAUTH'                =>  '商户未开通此接口权限',
            'NOTENOUGH'             =>  '用户帐号余额不足',
            'ORDERNOTEXIST'         =>  '订单号不存在',
            'ORDERPAID'             =>  '商户订单已支付，无需重复操作',
            'ORDERCLOSED'           =>  '当前订单已关闭，无法支付',
            'SYSTEMERROR'           =>  '系统错误!系统超时',
            'APPID_NOT_EXIST'       =>  '参数中缺少APPID',
            'MCHID_NOT_EXIST'       =>  '参数中缺少MCHID',
            'APPID_MCHID_NOT_MATCH' =>  'appid和mch_id不匹配',
            'LACK_PARAMS'           =>  '缺少必要的请求参数',
            'OUT_TRADE_NO_USED'     =>  '同一笔交易不能多次提交',
            'SIGNERROR'             =>  '参数签名结果不正确',
            'XML_FORMAT_ERROR'      =>  'XML格式错误',
            'REQUIRE_POST_METHOD'   =>  '未使用post传递参数 ',
            'POST_DATA_EMPTY'       =>  'post数据不能为空',
            'NOT_UTF8'              =>  '未使用指定编码格式',
        );
        if (array_key_exists($code, $errList)) {
            return $errList[$code];
        }
    }

    /**
     * 将xml转为array
     * @param string $xml
     * return array
     */
    public function xml_to_data($xml)
    {
        if (!$xml) {
            return false;
        }
        //将XML转为array
        //禁止引用外部xml实体
        libxml_disable_entity_loader(true);
        $data = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
        return $data;
    }

    public function https_request($url, $data = null)
    {
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
        if (!empty($data)) {
            curl_setopt($curl, CURLOPT_POST, 1);
            curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
        }
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        $output = curl_exec($curl);
        curl_close($curl);
        return $output;
    }

    // 申请退款
    public function wechatRefund(Request $request)
    {
        // 记录日志
        $log_record['request'] = $request;
        $log_record['time'] = date('Y-m-d H:i:s');
        $log_record['function'] = 'wechatRefund';
        logFileRecord($log_record, 'xdc/WeChatPay/wechatRefund', 2);

        // 根据订单id，查询在线支付记录
        $find_weixin_record = DB::table('weixin_record')
            ->where('out_trade_no', $request['out_trade_no'])
            ->first();
        DB::beginTransaction();
        $params['appid'] = $find_weixin_record['were_appid']; //appid
        $params['mch_id'] = $find_weixin_record['were_mchid']; //微信支付分配的商户号
        $params['nonce_str'] = $this->genRandomString(); //随机字符串，不长于32位。推荐随机数生成算法
        $params['out_trade_no'] = $find_weixin_record['out_trade_no']; //订单号
        $params['out_refund_no'] = 'TK' . date('YmdHis'); //商户系统内部的退款单号，商户系统内部唯一，只能是数字、大小写字母_-|*@ ，同一退款单号多次请求只退一笔。
        $params['total_fee'] = $find_weixin_record['were_pay_total_money']; //订单总金额，单位为分，只能为整数
        $params['refund_fee'] = $find_weixin_record['were_pay_total_money']; //退款总金额，订单总金额，单位为分，只能为整数
        $request_return = $this->wxrefundapi($params);
        return response()->json($request_return);
    }

    // 退款接口
    public function wxrefundapi($paramsw)
    {
        $paramsw['notify_url'] = config('filesystems.server_name').'/index.php/u1/Pay/wechatRefundNotify'; //notify_url
        $paramsw['sign_type'] = 'MD5';
        // 获取签名数据
        $sign = $this->MakeSign($paramsw);
        $paramsw['sign'] = $sign;
        $xml = $this->dataToXml($paramsw);
        $response = $this->postXmlCurl($xml, 'https://api.mch.weixin.qq.com/secapi/pay/refund', true);
        if (!$response) {
            return false;
        }
        $result = $this->xml_to_data($response);
        if (!empty($result['result_code']) && !empty($result['err_code'])) {
            $result['err_msg'] = $this->error_code($result['err_code']);
        }
        return $result;
    }

    // 微信退款回调地址
    public function wechatRefundNotify(Request $request)
    {
        $get_input = file_get_contents("php://input");
        libxml_disable_entity_loader(true);
        $get_input = json_decode(json_encode(simplexml_load_string($get_input, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
        // 记录日志
        error_reporting(0);
        $data = $this->decipheringReqInfo($get_input['req_info']);
        $log_record['get_input'] = $get_input;
        $log_record['data'] = $data;
        $log_record['time'] = date('Y-m-d H:i:s');
        $log_record['function'] = 'wechatRefundNotify';
        logFileRecord($log_record, 'xdc/WeChatPay/wechatRefundNotify', 2);
        try {
            // 
            $find_ord_data = DB::table('order')
                ->where('ord_number', $data['out_trade_no'])
                ->update(['ord_state'=>6,'ord_update_time'=>date('Y-m-d H:i:s'),'ord_pay_state'=>3]);
            $find_ord = DB::table('order')
                ->where('ord_number', $data['out_trade_no'])
                ->value('ord_id');
            $update_work = DB::table('work_order')
                ->where('wor_ord_id',$find_ord)
                ->update(['wor_delet'=>2]);
            if ($find_ord_data) {
                //告诉微信，我已经处理了，否则微信那边会重复发送数据过来的哦
                $mes=array(
                    'return_code'=>'SUCCESS',
                    'return_msg'=>'OK'
                );
            }
        } catch (\Exception $e) {
            DB::rollBack();
            $pay_data = $e->getMessage();
            $log_record['code'] = 'error';
            $mes=array(
                'return_code'=>'Error',
                'return_msg'=>'OK'
            );
        }
        // 记录日志
        $log_record['request'] = $request->all();
        $log_record['data'] = $pay_data;
        $log_record['get_input'] = $get_input;
        $log_record['time'] = date('Y-m-d H:i:s');
        $log_record['function'] = 'wechatRefundNotify';
        logFileRecord($log_record, 'xdc/WeChatPay/wechatRefundNotify', 2);
        return $this->dataToXml($mes);
    }
    /*******************************************统一下单结束****************************************************************/

    // 取消支付
    public function wechatPayRecError(Request $request)
    {
        // 记录日志
        $log_record['request'] = $request;
        $log_record['time'] = date('Y-m-d H:i:s');
        $log_record['function'] = 'wechatPayError';
        logFileRecord($log_record, 'WeChatPay/wechatPayError', 2);

        if (!isset($request['ord_id']) || empty($request['ord_id'])) {
            return response()->json(['code' => 500, 'msg' => '参数错误', 'data' => '']);
        }
        $find_order = DB::table('order')
            ->leftjoin('order_client', 'orcl_ord_id', '=', 'ord_id')
            ->where('ord_id', $request['ord_id'])
            ->first();
        Db::beginTransaction();
        // 删除订单相关数据
        $del_orgo = DB::table('order_goods')
            ->where('orgo_ord_id', $request['ord_id'])
            ->delete();
        $del_ord = DB::table('order')
            ->where('ord_id', $request['ord_id'])
            ->delete();
        $del_orcl = DB::table('order_client')
            ->where('orcl_ord_id', $request['ord_id'])
            ->delete();
        $find_goco = DB::table('goods_commission')
            ->where('goco_ord_id', $request['ord_id'])
            ->get()->toArray();
        $update_mem['mem_banlance_lock'] = 2;
        $update_mem['mem_update_time'] = date('Y-m-d H:i:s');
        $update_mem_res = DB::table('member')
            ->where('mem_id', $find_order['orcl_mem_id'])
            ->update($update_mem);

        if (!empty($find_goco)) {
            $del_goco = DB::table('goods_commission')
                ->where('goco_ord_id', $request['ord_id'])
                ->delete();
        } else {
            $del_goco = true;
        }
        if ($del_orgo && $del_ord && $del_orcl && $del_goco) {
            DB::commit();
            return response()->json(['code'=>200, 'msg'=>'取消成功', 'data'=>'']);
        } else {
            DB::rollBack();
            return response()->json(['code'=>500, 'msg'=>'取消失败', 'data'=>'']);
        }
    }

    // 取消订单
    public function cancel(Request $request)
    {
        // 记录日志
        $log_record['request'] = $request->all();
        $log_record['time'] = date('Y-m-d H:i:s');
        $log_record['function'] = 'cancel';
        logFileRecord($log_record, 'wash/WeixinUser', 2);
        DB::beginTransaction();
        // 查询订单数据
        $find_order = DB::table('order')
            ->leftjoin('order_client', 'orcl_ord_id', '=', 'ord_id')
            ->where('ord_id', $request['ord_id'])
            ->first();

        if ($find_order['ord_state'] != 1 || $find_order['ord_state'] != 2) {
            
        } else {
            return response()->json(['code'=>500, 'msg'=>'订单不能取消', 'data'=>'']);
        }

        if ($find_order['ord_type'] == 1 || $find_order['ord_type'] == 2) {
            // 还回商品数量
            $find_orgo_data = DB::table('order_goods')
                ->where('orgo_ord_id', $request['ord_id'])
                ->get()->toArray();
            foreach ($find_orgo_data as $key => $value) {
                $find_good = DB::table('goods')
                    ->where('goo_id', $value['orgo_goo_id'])
                    ->select('goo_id', 'goo_num')
                    ->first();
                $update_goods = DB::table('goods')
                    ->where('goo_id', $value['orgo_goo_id'])
                    ->update(['goo_num'=>$value['orgo_goo_num']+$find_good['goo_num']]);
            }
            // 还回会员权益
            $find_equ = DB::table('equ_record')
                ->where('eqre_ord_id', $request['ord_id'])
                ->select('eqre_id', 'eqre_meeq_id', 'eqre_num', 'eqre_goo_id')
                ->get()->toArray();
            if (!empty($find_equ)) {
                foreach ($find_equ as $key => $value) {
                    $find_mem_equ = DB::table('member_equity_goods')
                        ->where('mego_meeq_id', $value['eqre_meeq_id'])
                        ->where('mego_eqgo_goo_id', $value['eqre_goo_id'])
                        ->select('mego_eqgo_goo_sunum', 'mego_id')
                        ->first();
                    $update_mego_res = DB::table('member_equity_goods')
                        ->where('mego_id', $find_mem_equ['mego_id'])
                        ->update(['mego_eqgo_goo_sunum'=>$value['eqre_num']+$find_mem_equ['mego_eqgo_goo_sunum']]);
                }
            }

            // 还回会员卡
            $find_mvre_data = DB::table('myvip_record')
                ->where('mvre_ord_id', $request['ord_id'])
                ->select('mvre_myvi_id')
                ->get()->toArray();
            if (!empty($find_mvre_data)) {
                foreach ($find_myvi_data as $key => $value) {
                    $find_myvip = DB::table('myvipcard')
                        ->where('myvi_id', $value['mvre_myvi_id'])
                        ->select('myvi_vica_sunum', 'myvi_vica_end_time', 'myvi_vica_state')
                        ->first();
                    if (strtotime($find_myvip['myvi_vica_end_time']) > time()) {
                        if ($find_myvip['myvi_vica_state'] == 5) {
                            $update_vip['myvi_vica_state'] = 1;
                        }
                    } else {
                        $update_vip['myvi_vica_state'] = 5;
                    }
                    $update_vip['myvi_vica_sunum'] = $find_myvip['myvi_vica_sunum'] + 1;
                    $update_myvi_res = DB::table('myvipcard')
                        ->where('myvi_id', $value['mvre_myvi_id'])
                        ->update($update_vip);
                }
            }

            // 还回充值的金额
            $find_rec_log = DB::table('rechcard_log')
                ->where('relo_ord_id', $request['ord_id'])
                ->select('relo_myb_id', 'relo_gift_money', 'relo_rec_money')
                ->get()->toArray();
            if (!empty($find_rec_log)) {
                foreach ($find_rec_log as $key => $value) {
                    $find_myb_data = DB::table('mybalance_details')
                        ->where('myb_id', $value['relo_myb_id'])
                        ->select('myb_remaining_amount', 'myb_gire_amount', 'myb_end_time', 'myb_state')
                        ->first();
                    if (time() > strtotime($find_myb_data['myb_end_time'])) {// 过期
                        $update_vip['myb_state'] = 5;
                    } else {
                        if ($find_myb_data['myb_state'] == 5) {
                            $update_myde['myb_state'] = 1;
                        }
                    }
                    $update_myde['myb_remaining_amount'] = $find_myb_data['myb_remaining_amount'] + $value['relo_rec_money'];
                    $update_myde['myb_gire_amount'] = $find_myb_data['myb_gire_amount'] + $value['relo_gift_money'];
                    $update_myde_res = DB::table('mybalance_details')
                        ->where('myb_id', $value['relo_myb_id'])
                        ->update($update_myde);
                }
            }
        } else {
            return response()->json(['code'=>500, 'msg'=>'订单不能取消', 'data'=>'']);
        }

        if ($find_order['ord_source'] == 1) {//pc端下单
            $update_order['ord_state'] = 6;//已取消
            $update_order['ord_update_time'] = date('Y-m-d H:i:s');//更新时间
            $update_order_res = DB::table('order')
                ->where('ord_id', $request['ord_id'])
                ->update($update_order);
        } elseif ($find_order['ord_source'] == 2) {//小程序
            if ($find_order['ord_pay_state'] == 1 ) {
                if ($find_order['ord_use_other_pay'] != 0) {
                    // 根据订单id，查询在线支付记录
                    $find_weixin_record = DB::table('weixin_record')
                        ->where('out_trade_no', $find_order['ord_number'])
                        ->first();
                    $params['appid'] = $find_weixin_record['were_appid']; //appid
                    $params['mch_id'] = $find_weixin_record['were_mchid']; //微信支付分配的商户号
                    $params['nonce_str'] = $this->genRandomString(); //随机字符串，不长于32位。推荐随机数生成算法
                    $params['out_trade_no'] = $find_weixin_record['out_trade_no']; //订单号
                    $params['out_refund_no'] = 'TK' . date('YmdHis'); //商户系统内部的退款单号，商户系统内部唯一，只能是数字、大小写字母_-|*@ ，同一退款单号多次请求只退一笔。
                    $params['total_fee'] = $find_weixin_record['were_pay_total_money']; //订单总金额，单位为分，只能为整数
                    $params['refund_fee'] = $find_weixin_record['were_pay_total_money']; //退款总金额，订单总金额，单位为分，只能为整数
                    $request_return = $this->wxrefundapi($params);
                    if ($request_return['result_code'] == 'SUCCESS') {
                        // 新增在线退款记录
                        $were_add_data['were_client_id'] = $find_weixin_record['were_client_id']; //客户单位id，会员id
                        $were_add_data['were_type'] = $find_weixin_record['were_type']; //订单类型1服务单2实物单3充值卡4会员卡5权益单
                        $were_add_data['out_trade_no'] = $find_weixin_record['out_trade_no']; //商户订单号
                        $were_add_data['were_appid'] = $find_weixin_record['were_appid']; //    appid
                        $were_add_data['were_mchid'] = $find_weixin_record['were_mchid']; //    mch_id
                        $were_add_data['were_description'] = $find_weixin_record['were_description']; //商品描述
                        $were_add_data['were_openid'] = $find_weixin_record['were_openid']; //用户标识,用户在直连商户appid下的唯一标识
                        $were_add_data['were_pay_total_money'] = $find_weixin_record['were_pay_total_money']; //支付总金额(单位分)
                        $were_add_data['were_pay_way'] = 1; //在线支付方式1微信小程序支付
                        $were_add_data['were_pay_type'] = 2; //在线支付类型1付款2退款
                        $were_add_data['were_transaction_id'] = $request_return['transaction_id'];
                        $were_add_data['were_pre_id'] = 0;
                        $were_add_data['out_refund_no'] = $request_return['out_refund_no'];
                        $were_add_data['refund_id'] = $request_return['refund_id'];
                        $were_add_data['were_create_time'] = date('Y-m-d H:i:s');
                        $were_add_data_res = DB::table('weixin_record')->insert($were_add_data);
                        $update_order_res = true;
                    } else {
                        $update_order_res = false;
                    }
                } else {
                   $update_order_res = true; 
                }
            } else {
                $update_order_res = true; 
            }
        }
        $update_work['wor_delet'] = 2;
        $update_work_res = DB::table('work_order')
            ->where('wor_ord_id', $request['ord_id'])
            ->update($update_work);
            
        if ($update_order_res) {
            DB::commit();
            return response()->json(['code'=>200, 'msg'=>'订单取消成功', 'data'=>'']);
        } else {
            DB::rollBack();
            return response()->json(['code'=>500, 'msg'=>'订单取消失败', 'data'=>'']);
        }
    }

    //解密退款成功时，微信回调返回的信息
    public function decipheringReqInfo($str){
        //微信商户key
        $key = $this->mch_key;
        $str = base64_decode($str);
        $xml = openssl_decrypt($str,'aes-256-ecb',md5($key),OPENSSL_RAW_DATA);
        return json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
    }
}
