<?php

namespace app\api\controller;

use app\api\model\OrderInfo;
use app\api\model\OrderMoney;
use EasyWeChat\Foundation\Application;
use EasyWeChat\Payment\Order;
use app\common\controller\Api;

use think\Db;

/**
 * 微信支付,回调接口
 * @ApiInternal
 */
class Pay extends Api
{
    protected $options;
    function _initialize()
    {
        parent::_initialize();
        $this->options = [
            'app_id'  => config('app_id'),
            'secret'  => config('app_secret'),
            'payment' => [
                'merchant_id'        => config('wx_mch_id'),
                'key'                => config('wx_pay_key'),
                'cert_path'          => 'wechat/cert/apiclient_cert.pem',
                'key_path'           => 'wechat/cert/apiclient_key.pem',
            ],
        ];
    }

    /**
     * 微信支付
     */
    public function wx_pay($out_trade_no,$body,$total,$notify_url,$openid){
        $attributes = [
            'trade_type'       => 'JSAPI',
            'body'             => $body,
            'out_trade_no'     => $out_trade_no,
            'total_fee'        => $total*100, // 单位:分
            'notify_url'       => url($notify_url,'','',true), // 支付结果通知网址,如果不设置则会使用配置里的默认地址
            'openid'           => $openid, // trade_type=JSAPI,此参数必传,用户在商户appid下的唯一标识,
        ];

        $order = new Order($attributes);

        $app = new Application($this->options);
        $payment = $app->payment;
        $result = $payment->prepare($order);
        if($result['return_code'] == 'SUCCESS') {
            if ($result['result_code'] == 'SUCCESS') {
                $prepayId = $result->prepay_id;
                $config = $payment->configForJSSDKPayment($prepayId);
                $arr = array(
                    'timeStamp'=>$config['timestamp'],
                    'nonceStr'=>$config['nonceStr'],
                    'package'=>$config['package'],
                    'signType'=>'MD5',
                    'paySign'=>$config['paySign'],
                );
                return json_encode($arr);
            }else{
                return $result['err_code_des'];
            }
        }else{
            return $result['return_msg'];
        }

    }

    /**
     * 支付回调
     * @throws \EasyWeChat\Core\Exceptions\FaultException
     */
    public function notify(){
        $app = new Application($this->options);
        $response = $app->payment->handleNotify(function($notify, $successful){

            // 使用通知里的 "微信支付订单号" 或者 "商户订单号" 去自己的数据库找到订单
            $out_trade_no=$notify->out_trade_no;
//            $out_trade_no=2020042997514852;
            $orderModel = new \app\api\model\Order();
            $order = $orderModel->findData(['order_num'=>$out_trade_no]);
            if (!$order) { // 如果订单不存在
                return 'Order not exist.'; // 告诉微信,我已经处理完了,订单没找到,别再通知我了
            }
            // 如果订单存在
            // 检查订单是否已经更新过支付状态
            if ($order['status'] != 1) { // 判断是否已经支付
                return true; // 已经支付成功了就不再更新了
            }
            // 用户是否支付成功
            if ($successful) {
                $orderInfoModel = new OrderInfo();
                $goodsList = $orderInfoModel->where('order_id', $order['id'])->field('goods_id,number,ch_goods_name,type,score,depot_id')->select();
                $orderModel->notify($order['id'],$order['user_id'],$order['pay_total'],$goodsList);
            }
            return true; // 返回处理完成
        });
        $response->send();
    }

    /**
     * 充值回调
     * @throws \EasyWeChat\Core\Exceptions\FaultException
     */
    public function recharge_notify(){
        $app = new Application($this->options);
        $response = $app->payment->handleNotify(function($notify, $successful){

            // 使用通知里的 "微信支付订单号" 或者 "商户订单号" 去自己的数据库找到订单
            $out_trade_no=$notify->out_trade_no;
            $orderMoneyModel = new OrderMoney();
            $order = $orderMoneyModel->where(['order_num'=>$out_trade_no])->find();
            if (!$order) { // 如果订单不存在
                return 'Order not exist.'; // 告诉微信,我已经处理完了,订单没找到,别再通知我了
            }
            // 如果订单存在
            // 检查订单是否已经更新过支付状态
            if ($order['status'] != 1) { // 判断是否已经支付
                return true; // 已经支付成功了就不再更新了
            }
            // 用户是否支付成功
            if ($successful) {
                $userModel = new \app\api\model\User();
                $userModel->recharge($out_trade_no);
            }

            return true; // 返回处理完成
        });
        $response->send();
    }

    /**
     * 购买会员回调
     * @throws \EasyWeChat\Core\Exceptions\FaultException
     */
    public function buy_vip_notify(){
        $app = new Application($this->options);
        $response = $app->payment->handleNotify(function($notify, $successful){
            // 使用通知里的 "微信支付订单号" 或者 "商户订单号" 去自己的数据库找到订单
            $out_trade_no=$notify->out_trade_no;
            $orderMoneyModel = new OrderMoney();
            $order = $orderMoneyModel->where(['order_num'=>$out_trade_no])->find();
            if (!$order) { // 如果订单不存在
                return 'Order not exist.'; // 告诉微信,我已经处理完了,订单没找到,别再通知我了
            }
            // 如果订单存在
            // 检查订单是否已经更新过支付状态
            if ($order['status'] != 1) { // 判断是否已经支付
                return true; // 已经支付成功了就不再更新了
            }
            // 用户是否支付成功
            if ($successful) {
                $userModel = new \app\api\model\User();
                $userModel->buyVip($out_trade_no);
            }
            return true; // 返回处理完成
        });
        $response->send();
    }

    /**
     * 续费会员回调
     * @throws \EasyWeChat\Core\Exceptions\FaultException
     */
    public function renew_vip_notify(){
        $app = new Application($this->options);
//        $response = $app->payment->handleNotify(function($notify, $successful){

            // 使用通知里的 "微信支付订单号" 或者 "商户订单号" 去自己的数据库找到订单
//            $out_trade_no=$notify->out_trade_no;
            $out_trade_no=20200511515410295;
            $orderMoneyModel = new OrderMoney();
            $order = $orderMoneyModel->where(['order_num'=>$out_trade_no])->find();
            if (!$order) { // 如果订单不存在
                return 'Order not exist.'; // 告诉微信,我已经处理完了,订单没找到,别再通知我了
            }
            // 如果订单存在
            // 检查订单是否已经更新过支付状态
            if ($order['status'] != 1) { // 判断是否已经支付
                return true; // 已经支付成功了就不再更新了
            }
            // 用户是否支付成功
//            if ($successful) {
                $userModel = new \app\api\model\User();
                $userModel->renewVip($out_trade_no);
//            }
            return true; // 返回处理完成
//        });
//        $response->send();
    }

    /**
     * 查询订单
     */
    public function checkOrder(){
        $app = new Application($this->options);
        $payment = $app->payment;
        $orderNo = "20200509101541001";//商户系统内部的订单号(out_trade_no)
        $result=$payment->query($orderNo);
        var_dump($result);
    }

    /**
     * 退款
     */
    public function refund($orderNo,$total,$refund_note=null,$refundFee=null){

        $app = new Application($this->options);
        $payment = $app->payment;
        //使用商户订单号退款  PS.其他形式参考文档
//        $orderNo = "2020060610056519";//商户系统内部的订单号(out_trade_no)
        $refundNo = get_order_num().'3';//退款单号
        if ($refundFee){
            $result = json_decode($payment->refund($orderNo, $refundNo, $total*100,$refundFee*100),true); // 总金额 100, 退款 80,refundFee可选(为空时全额退款)
        }else {
            $result = json_decode($payment->refund($orderNo, $refundNo, $total*100),true); // 总金额 100, 退款 80,refundFee可选(为空时全额退款)
        }

        if ($result['return_code'] == 'SUCCESS' && $result['result_code'] == 'SUCCESS'){
            $orderModel = new \app\api\model\Order();
            $res = $orderModel->orderRefund($orderNo,$refundNo,$refund_note,$refundFee);
            if ($res) return true;
            else return false;
        }
    }

    /**
     * 退款单商品
     */
    public function refundGoods($orderNo,$total,$order_info_id,$refund_note=null,$refundFee=null){

        $app = new Application($this->options);
        $payment = $app->payment;
        //使用商户订单号退款  PS.其他形式参考文档
//        $orderNo = "2020060610056519";//商户系统内部的订单号(out_trade_no)
        $refundNo = get_order_num().'3';//退款单号
        if ($refundFee){
            $result = json_decode($payment->refund($orderNo, $refundNo, $total*100,$refundFee*100),true); // 总金额 100, 退款 80,refundFee可选(为空时全额退款)
        }else {
            $result = json_decode($payment->refund($orderNo, $refundNo, $total*100),true); // 总金额 100, 退款 80,refundFee可选(为空时全额退款)
        }

        if ($result['return_code'] == 'SUCCESS' && $result['result_code'] == 'SUCCESS'){
            $orderModel = new \app\api\model\Order();
            $res = $orderModel->orderRefundGoods($orderNo,$refundNo,$refund_note,$order_info_id,$refundFee);
            if ($res) return true;
            else return false;
        }
    }

    /**
     * 查询退款
     */
    public function checkRefund(){
        $app = new Application($this->options);
        $payment = $app->payment;
        $outTradeNo="2018080210097519";//商户系统内部的订单号(out_trade_no)
        $result = $payment->queryRefund($outTradeNo);
        var_dump($result);
    }

    /**
     * 退款结果回调
     */
    public function refundNotify() {
        cache('test',123123);
        $app = new Application($this->options);
        $response = $app->payment->handleRefundNotify(function ($message, $reqInfo) {
            cache('message',$message);
            cache('reqInfo',$reqInfo);
            // 其中 $message['req_info'] 获取到的是加密信息
            // $reqInfo 为 message['req_info'] 解密后的信息
            // 你的业务逻辑...
            return true; // 返回 true 告诉微信“我已处理完成”
            // 或返回错误原因 $fail('参数格式校验错误');
        });

        $response->send();
    }
    /**
     * 提现
     */
    public function merchantPay($openid,$user_name,$price,$desc){
        $app = new Application($this->options);
        $merchantPay = $app->merchant_pay;
        $merchantPayData = [
            'partner_trade_no' => get_order_num().'2', //随机字符串作为订单号
            'openid' => $openid, //收款人的openid
            'check_name' => 'NO_CHECK',  //文档中有三种校验实名的方法 NO_CHECK OPTION_CHECK FORCE_CHECK
            're_user_name'=>$user_name,     //OPTION_CHECK FORCE_CHECK 校验实名的时候必须提交
            'amount' => $price*100,  //单位为分
            'desc' => $desc,
            'spbill_create_ip' => $this->request->ip(0,true),  //发起交易的IP地址
        ];
        $result = $merchantPay->send($merchantPayData);
        return $result;
    }
}