package com.tzy.framework.pay.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradeAppPayModel;
import com.alipay.api.domain.AlipayTradePrecreateModel;
import com.alipay.api.domain.ExtUserInfo;
import com.alipay.api.request.*;
import com.alipay.api.response.*;
import com.tzy.common.constant.Constants;
import com.tzy.common.core.domain.entity.SysDictData;
import com.tzy.common.utils.Base64Util;
import com.tzy.common.utils.DateUtils;
import com.tzy.common.utils.LogSyncUtil;
import com.tzy.common.utils.StringUtils;
import com.tzy.framework.pay.config.AliPayConfig;
import com.tzy.framework.pay.config.PayConfig;
import com.tzy.framework.pay.dto.*;
import com.tzy.framework.pay.service.AlipayService;
import com.tzy.framework.pay.util.AlipayConfigUtil;
import com.tzy.framework.util.RandomUtil;
import com.tzy.framework.util.RedisUtils;
import com.tzy.system.service.ISysDictDataService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;

@Slf4j
@Service
public class AlipayServiceImpl implements AlipayService {

    @Autowired
    private AliPayConfig aliPayConfig ;
    @Value("${pay.alipay.app.payNotifyUrl}")
    private String notifyUrl;
    @Value("${pay.alipay.app.refundNotifyUrl}")
    private String refundNotifyUrl;
    public static final String searchUrl="https://openapi.alipay.com/gateway.do";
    @Autowired
    private ISysDictDataService dictDataService;
    @Autowired
    private RedisUtils redisUtils;
    @Autowired
    private PayConfig payConfig;

    @Override
    public AliPayConfig initConfig(String appid,String type){
        //查询redis 生效的支付配置
        AtomicReference<AliPayConfig> aliPayConfig = null ;
        try{
            if(StringUtils.isNotEmpty(appid)) { //如果传入appid 不为空 则取缓存配置
                aliPayConfig.set((AliPayConfig) redisUtils.hget("payment_alipay", appid));
                if (null != aliPayConfig.get() && StringUtils.isNotEmpty(aliPayConfig.get().getAppId())) {
                    return aliPayConfig.get();
                }
            }
            if(StringUtils.isEmpty(appid) && !"unifiedOrder".equals(type)){
                //如果不是统一下单，则使用默认配置（配置文件）
                return this.aliPayConfig;
            }
            //如果 缓存中未查到 该配置 则启用其他配置
            Map<Object, Object> paymentAlipayMap = redisUtils.hmget("payment_alipay");
            if(null != paymentAlipayMap && !paymentAlipayMap.isEmpty()){
                aliPayConfig.set((AliPayConfig) paymentAlipayMap.values().stream().findFirst().get());
                return aliPayConfig.get();
            }
        } catch (Exception e) {
            log.error(" 获取缓存支付配置失败，从数据库获取支付配置 ");
        }
        //查询字典配置生效的选项
        List<SysDictData> paymentAlipays = dictDataService.getByTypeAndStatus("payment_alipay", "1");
        if(null != paymentAlipays && !paymentAlipays.isEmpty()){
            paymentAlipays.forEach(sysDictData -> {
                AliPayConfig aliPayConfig1 = new AliPayConfig();
                //根据字典表配置的 商户号，加载 配置的密钥等参数
                AlipayData alipayData = AlipayConfigUtil.initConfig(sysDictData.getDictValue());
                if(null != alipayData && StringUtils.isNotEmpty(alipayData.getAppid()) ){
                    aliPayConfig1.setAppId(alipayData.getAppid());
                    aliPayConfig1.setAlipayPublicKey(alipayData.getPublicKey());
                    aliPayConfig1.setPrivateKey(alipayData.getPrivateKey());
                }
                if(appid.equals(sysDictData.getDictValue())){
                    //如果有配置的选项则设置为配置选项
                    aliPayConfig.set(aliPayConfig1);
                }
                redisUtils.hset("appPayConfig",sysDictData.getDictValue(),aliPayConfig1);
            });
            //判断是否有配置选项，如果没有则使用 其他配置
            if(null == aliPayConfig || null == aliPayConfig.get() || StringUtils.isEmpty(aliPayConfig.get().getAppId())){
                Map<Object, Object> paymentAlipayMap = redisUtils.hmget("payment_alipay");
                if(null != paymentAlipayMap && !paymentAlipayMap.isEmpty()){
                    aliPayConfig.set((AliPayConfig) paymentAlipayMap.values().stream().findFirst().get());
                }else{
                    //如果数据库中没有查到则使用配置文件中配置
                    redisUtils.hset("appPayConfig",this.aliPayConfig.getAppId(),this.aliPayConfig);
                    return this.aliPayConfig;
                }
            }
        }else{
            //如果数据库中没有查到则使用配置文件中配置
            redisUtils.hset("appPayConfig",this.aliPayConfig.getAppId(),this.aliPayConfig);
            return this.aliPayConfig;
        }
        return aliPayConfig.get();
    }

    public AliPayConfig initConfig2(String appid){
        return (AliPayConfig) payConfig.get(appid);
    }


    @Override
    public ResultMap unifiedOrder(String orderNo, BigDecimal amount, String body) {
        return unifiedOrder(orderNo,amount,body,new Date());
    }

    /**
     * 支付宝统一下单
     * @param orderNo
     * @param amount
     * @param body
     * @return
     */
    @Override
    public ResultMap unifiedOrder(String orderNo, BigDecimal amount, String body,Date expireTime){
        if(StringUtils.isNotEmpty(body) ){
            body = Base64Util.subStringByBytes(body,120)+"...";
        }
        String serverUrl = aliPayConfig.getServerUrl();
        String appId = aliPayConfig.getAppId();
        String privateKey = aliPayConfig.getPrivateKey();
        String format = aliPayConfig.getFormat();
        String charset = aliPayConfig.getCharset();
        String alipayPublicKey = aliPayConfig.getAlipayPublicKey();
        String signType = aliPayConfig.getSignType();
        //实例化客户端
//        AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do", APP_ID, APP_PRIVATE_KEY, "json", CHARSET, ALIPAY_PUBLIC_KEY, "RSA2");
        AlipayClient alipayClient = new DefaultAlipayClient(serverUrl, appId, privateKey, format, charset, alipayPublicKey, signType);
        //实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称：alipay.trade.app.pay
        AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
        //SDK已经封装掉了公共参数，这里只需要传入业务参数。以下方法为sdk的model入参方式(model和biz_content同时存在的情况下取biz_content)。
        AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
        model.setBody("");
        model.setSubject(body);
        model.setOutTradeNo(orderNo);
        //model.setTimeExpire(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS,new Date(System.currentTimeMillis()+2800*60)));
        model.setTimeExpire(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS,new Date(expireTime.getTime()+2900*60)));
        //model.setTimeoutExpress("3m");
//        model.setTotalAmount("0.01");
        model.setTotalAmount(String.valueOf(amount));
        model.setProductCode("QUICK_MSECURITY_PAY");
        request.setBizModel(model);
        request.setNotifyUrl(notifyUrl);
        try {
            LogSyncUtil.logSync("支付宝直连统一下单,交易编号:{},请求参数:{}",orderNo,request);
            //这里和普通的接口调用不同，使用的是sdkExecute
            AlipayTradeAppPayResponse response = alipayClient.sdkExecute(request);
            if (response.isSuccess()) {
                LogSyncUtil.logSync("支付宝直连统一下单,交易编号:{},返回结果:{}",orderNo,response.getBody());
                return ResultMap.ok().put("data",response.getBody());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return ResultMap.error(-1,"调用失败");
    }

    /**
     * 统一下单-新
     * @param paymentRequestDto
     * @return
     */
    @Override
    public ResultMap unifiedOrder(PaymentRequestDto paymentRequestDto){
        LogSyncUtil.logSync("支付宝直连统一下单,交易编号:{},请求参数:{}",paymentRequestDto.getOrderNo(),paymentRequestDto);
        if(StringUtils.isNotEmpty(paymentRequestDto.getBody()) ){
            paymentRequestDto.setBody(Base64Util.subStringByBytes(paymentRequestDto.getBody(),120)+"...");
        }
        AliPayConfig aliPayConfig = (AliPayConfig) payConfig.get(paymentRequestDto.getAppid());
        if(null == aliPayConfig){
            aliPayConfig = this.aliPayConfig;
        }
        String serverUrl = aliPayConfig.getServerUrl();
        String appId = aliPayConfig.getAppId();
        String privateKey = aliPayConfig.getPrivateKey();
        String format = aliPayConfig.getFormat();
        String charset = aliPayConfig.getCharset();
        String alipayPublicKey = aliPayConfig.getAlipayPublicKey();
        String signType = aliPayConfig.getSignType();
        //实例化客户端
//        AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do", APP_ID, APP_PRIVATE_KEY, "json", CHARSET, ALIPAY_PUBLIC_KEY, "RSA2");
        AlipayClient alipayClient = new DefaultAlipayClient(serverUrl, appId, privateKey, format, charset, alipayPublicKey, signType);
        //实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称：alipay.trade.app.pay
        AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
        //SDK已经封装掉了公共参数，这里只需要传入业务参数。以下方法为sdk的model入参方式(model和biz_content同时存在的情况下取biz_content)。
        AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
        model.setBody("");
        model.setSubject(paymentRequestDto.getBody());
        model.setOutTradeNo(paymentRequestDto.getOrderNo());
        model.setTimeExpire(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS,new Date(paymentRequestDto.getCreateOrderTime().getTime()+2800*60)));
        //model.setTimeoutExpress("3m");
//        model.setTotalAmount("0.01");
        model.setTotalAmount(String.valueOf(paymentRequestDto.getTotalAmount().setScale(2,BigDecimal.ROUND_DOWN)));
        model.setProductCode("QUICK_MSECURITY_PAY");
        request.setBizModel(model);
        request.setNotifyUrl(aliPayConfig.getPayNotifyUrl());
        try {
            //这里和普通的接口调用不同，使用的是sdkExecute
            AlipayTradeAppPayResponse response = alipayClient.sdkExecute(request);
            LogSyncUtil.logSync("支付宝直连统一下单,交易编号:{},返回结果:{}",paymentRequestDto.getOrderNo(),response);
            if (response.isSuccess()) {
                return ResultMap.ok()
                        .put("data",response.getBody())
                        .put("paySubType",aliPayConfig.getName())
                        ;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return ResultMap.error(-1,"调用失败");
    }
    /**
     * 支付宝退款
     * @param orderNo
     * @param amount
     * @param body
     * @return
     */
    @Override
    public ResultMap aliRefundNotify(String appid,String orderNo, BigDecimal amount, String body){
        AliPayConfig aliPayConfig = (AliPayConfig) payConfig.get(appid);
        if(null == aliPayConfig){
            aliPayConfig = this.aliPayConfig;
        }
        String serverUrl = aliPayConfig.getServerUrl();
        String appId = aliPayConfig.getAppId();
        String privateKey = aliPayConfig.getPrivateKey();
        String format = aliPayConfig.getFormat();
        String charset = aliPayConfig.getCharset();
        String alipayPublicKey = aliPayConfig.getAlipayPublicKey();
        String signType = aliPayConfig.getSignType();
        AlipayClient alipayClient = new DefaultAlipayClient(serverUrl,appId,privateKey,format,charset,alipayPublicKey,signType);
        AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
        JSONObject bizContent = new JSONObject();
        bizContent.put("out_trade_no", orderNo);
        bizContent.put("refund_amount", amount);
        String out_request_no = RandomUtil.getRandom(RandomUtil.REFUND_NO);
        bizContent.put("out_request_no", out_request_no);
        bizContent.put("refund_reason", body);
        //// 返回参数选项，按需传入
        JSONArray queryOptions = new JSONArray();
        queryOptions.add("refund_detail_item_list");
        bizContent.put("query_options", queryOptions);
        request.setBizContent(bizContent.toString());
        try {
            LogSyncUtil.logSync("支付宝直连 退款,交易编号:{},请求参数:{}",orderNo,request);
            AlipayTradeRefundResponse response = alipayClient.execute(request);
            String responseBody = response.getBody();
            JSONObject jsonObject = JSONObject.parseObject(responseBody);
            LogSyncUtil.logSync("支付宝直连 退款,交易编号:{},返回结果:{}",orderNo,jsonObject);
            log.debug("返回数据》》》{}",jsonObject);
            JSONObject alipay_trade_refund_response = jsonObject.getJSONObject("alipay_trade_refund_response");
            if(response.isSuccess()){
                System.out.println("调用成功");
                if("10000".equals(alipay_trade_refund_response.getString("code"))){//网关返回状态 10000 代表成功
                    alipay_trade_refund_response.put("out_refund_no",out_request_no);
                    alipay_trade_refund_response.put("refund_id",out_request_no);
                    String refund_fee = alipay_trade_refund_response.get("refund_fee").toString();
                    alipay_trade_refund_response.put("refund_fee", (StringUtils.isEmpty(refund_fee) ? 0 : Double.valueOf(refund_fee)) * 100);
                    String send_back_fee = alipay_trade_refund_response.get("send_back_fee").toString();
                    alipay_trade_refund_response.put("send_back_fee", (StringUtils.isEmpty(send_back_fee) ? 0 : Double.valueOf(send_back_fee)) * 100);
                    return ResultMap.ok()
                            .put("data",alipay_trade_refund_response)
                            ;
                } else {
                    return ResultMap.error(Integer.parseInt(alipay_trade_refund_response.getString("code")),alipay_trade_refund_response.getString("sub_msg"));
                }
            } else {
                System.out.println("调用失败");
//                return ResultMap.error(-1,"调用失败");
                return ResultMap.error(Integer.parseInt(alipay_trade_refund_response.getString("code")),alipay_trade_refund_response.getString("sub_msg"));
            }
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        return ResultMap.error(-1,"调用失败");
    }

    /**
     * 查询订单
     * @param orderNo
     * @return
     */
    @Override
    public AlipayTradeQueryResponse searchOrder(String orderNo){
        String appId = aliPayConfig.getAppId();
        String privateKey = aliPayConfig.getPrivateKey();
        String format = aliPayConfig.getFormat();
        String charset = aliPayConfig.getCharset();
        String signType = aliPayConfig.getSignType();
        String alipayPublicKey = aliPayConfig.getAlipayPublicKey();
        AlipayClient alipayClient = new DefaultAlipayClient(searchUrl, appId,privateKey,format, charset,alipayPublicKey,signType);
        AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
        JSONObject bizContent = new JSONObject();
        bizContent.put("out_trade_no", orderNo);
        request.setBizContent(bizContent.toString());
        try{
            return alipayClient.execute(request);
        }catch (Exception e){}
        return null;
    }

    /**
     * 查询订单
     * @param orderNo
     * @return
     */
    @Override
    public PaymentInfoResponseDto queryOrder(String appid,String orderNo){
        AliPayConfig aliPayConfig = (AliPayConfig) payConfig.get(appid);
        if(null == aliPayConfig){
            aliPayConfig = this.aliPayConfig;
        }
        String appId = aliPayConfig.getAppId();
        String privateKey = aliPayConfig.getPrivateKey();
        String format = aliPayConfig.getFormat();
        String charset = aliPayConfig.getCharset();
        String signType = aliPayConfig.getSignType();
        String alipayPublicKey = aliPayConfig.getAlipayPublicKey();
        AlipayClient alipayClient = new DefaultAlipayClient(searchUrl, appId,privateKey,format, charset,alipayPublicKey,signType);
        AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
        JSONObject bizContent = new JSONObject();
        bizContent.put("out_trade_no", orderNo);
        request.setBizContent(bizContent.toString());
        try{
            LogSyncUtil.logSync("支付宝直连 查询,交易编号:{},请求参数:{}",orderNo,request);
            AlipayTradeQueryResponse response = alipayClient.execute(request);
            LogSyncUtil.logSync("支付宝直连 查询,交易编号:{},返回结果:{}",orderNo,response);
            PaymentInfoResponseDto paymentInfoResponseDto = new PaymentInfoResponseDto();
            if(response!=null &&response.isSuccess()&& Constants.ALIPAY_TRADE_SUCCESS.equals(response.getTradeStatus())){
                paymentInfoResponseDto.setOrderNo(orderNo);
                paymentInfoResponseDto.setPayWay("alipay");
                paymentInfoResponseDto.setAppid(appId);
                paymentInfoResponseDto.setPaymentNo(response.getTradeNo());
                paymentInfoResponseDto.setPaymentPrice(new BigDecimal(response.getTotalAmount()));
                paymentInfoResponseDto.setActualPayment(new BigDecimal(response.getBuyerPayAmount()));
                paymentInfoResponseDto.setPaymentSuccessTime(response.getSendPayDate());
                paymentInfoResponseDto.setTradeState(response.getTradeStatus());
                paymentInfoResponseDto.setTradeStateDesc(response.getTradeStatus());
                paymentInfoResponseDto.setSuccess(true);
                return paymentInfoResponseDto;
            }else{
                return PaymentInfoResponseDto.error(-1,response.getMsg());
            }
        }catch (Exception e){}
        return PaymentInfoResponseDto.error(-1,"查询支付宝支付订单失败");
    }

    /**
     * 关闭订单
     * @param orderNo
     * @return
     */
    @Override
    public boolean closeTradeOrder(String orderNo){
        String appId = aliPayConfig.getAppId();
        String privateKey = aliPayConfig.getPrivateKey();
        String format = aliPayConfig.getFormat();
        String charset = aliPayConfig.getCharset();
        String signType = aliPayConfig.getSignType();
        String alipayPublicKey = aliPayConfig.getAlipayPublicKey();
        AlipayClient alipayClient = new DefaultAlipayClient(searchUrl, appId,privateKey,format, charset,alipayPublicKey,signType);
        AlipayTradeCloseRequest request = new AlipayTradeCloseRequest();
        JSONObject bizContent = new JSONObject();
        bizContent.put("out_trade_no", orderNo);
        request.setBizContent(bizContent.toString());
        try{
            AlipayTradeCloseResponse response = alipayClient.execute(request);
            if(response.isSuccess()){
                return true;
            }
        }catch (Exception e){}
        return false;
    }
    /**
     * 关闭订单-新
     * @param orderNo
     * @return
     */
    @Override
    public ResultMap closeTradeOrderNew(String appid,String orderNo){
        AliPayConfig aliPayConfig = (AliPayConfig) payConfig.get(appid);
        if(null == aliPayConfig){
            aliPayConfig = this.aliPayConfig;
        }
        String errMsg = "";
        String appId = aliPayConfig.getAppId();
        String privateKey = aliPayConfig.getPrivateKey();
        String format = aliPayConfig.getFormat();
        String charset = aliPayConfig.getCharset();
        String signType = aliPayConfig.getSignType();
        String alipayPublicKey = aliPayConfig.getAlipayPublicKey();
        AlipayClient alipayClient = new DefaultAlipayClient(searchUrl, appId,privateKey,format, charset,alipayPublicKey,signType);
        AlipayTradeCloseRequest request = new AlipayTradeCloseRequest();
        JSONObject bizContent = new JSONObject();
        bizContent.put("out_trade_no", orderNo);
        request.setBizContent(bizContent.toString());
        try{
            AlipayTradeCloseResponse response = alipayClient.execute(request);
            if(response.isSuccess()){
                return ResultMap.ok();
            }else{
                errMsg = response.getMsg();
            }
        }catch (Exception e){
            log.error("支付宝关闭订单【"+orderNo+"】错误{}",e.getMessage());
            errMsg = "支付宝关闭订单【"+orderNo+"】错误:"+e.getMessage();
        }
        return ResultMap.error(-1,errMsg);
    }

/*****************************新逻辑**********************/
    /**
     * 统一下单-新
     * @param paymentRequestDto
     * @return
     */
    /*@Override
    public ResultMap unifiedOrderNew(PaymentRequestDto paymentRequestDto){
        if(StringUtils.isNotEmpty(paymentRequestDto.getBody()) && paymentRequestDto.getBody().getBytes().length >128){
            paymentRequestDto.setBody(Base64Util.subStringByBytes(paymentRequestDto.getBody(),120)+"...");
        }
        AliPayConfig aliPayConfig = (AliPayConfig) paymentRequestDto.getPayConfigByClass(AliPayConfig.class);
        *//*AliPayConfig aliPayConfig = (AliPayConfig) payConfig.get(paymentRequestDto.getAppid());
        if(null == aliPayConfig){
            aliPayConfig = this.aliPayConfig;
        }*//*
        String serverUrl = aliPayConfig.getServerUrl();
        String appId = aliPayConfig.getAppId();
        String privateKey = aliPayConfig.getPrivateKey();
        String format = aliPayConfig.getFormat();
        String charset = aliPayConfig.getCharset();
        String alipayPublicKey = aliPayConfig.getAlipayPublicKey();
        String signType = aliPayConfig.getSignType();
        //实例化客户端
//        AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do", APP_ID, APP_PRIVATE_KEY, "json", CHARSET, ALIPAY_PUBLIC_KEY, "RSA2");
        AlipayClient alipayClient = new DefaultAlipayClient(serverUrl, appId, privateKey, format, charset, alipayPublicKey, signType);
        //实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称：alipay.trade.app.pay
        AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
        //SDK已经封装掉了公共参数，这里只需要传入业务参数。以下方法为sdk的model入参方式(model和biz_content同时存在的情况下取biz_content)。
        AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
        model.setBody("");
        model.setSubject(paymentRequestDto.getBody());
        model.setOutTradeNo(paymentRequestDto.getOrderNo());
        String expireTime = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS,paymentRequestDto.getExpireTime());
        model.setTimeExpire(expireTime);
        //model.setTimeoutExpress("3m");
//        model.setTotalAmount("0.01");
        model.setTotalAmount(String.valueOf(paymentRequestDto.getTotalAmount().setScale(2,BigDecimal.ROUND_DOWN)));
        model.setProductCode("QUICK_MSECURITY_PAY");
        model.setPassbackParams(paymentRequestDto.getPayWay());
        request.setBizModel(model);
        request.setNotifyUrl(aliPayConfig.getPayNotifyUrl());
        try {
            //这里和普通的接口调用不同，使用的是sdkExecute
            AlipayTradeAppPayResponse response = alipayClient.sdkExecute(request);
            if (response.isSuccess()) {
                return ResultMap.ok()
                        .put("data",response.getBody())
                        .put("paySubType",aliPayConfig.getName())
                        ;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return ResultMap.error(-1,"调用失败");
    }*/
    /**
     * 统一下单-新
     * @param paymentRequestDto
     * @return
     */
    @Override
    public ResultMap unifiedOrderNew(PaymentRequestDto paymentRequestDto){
        if(StringUtils.isNotEmpty(paymentRequestDto.getBody()) ){
            paymentRequestDto.setBody(Base64Util.subStringByBytes(paymentRequestDto.getBody(),120)+"...");
        }
        if(paymentRequestDto.getPayWay().contains("web")){
            return mainPay(paymentRequestDto);
        }
        return appPay(paymentRequestDto);
    }

    /**
     * app支付
     * @param paymentRequestDto
     * @return
     */
    public ResultMap appPay(PaymentRequestDto paymentRequestDto){
        RechargeUserInfoDto rechargeUserInfoDto = paymentRequestDto.getRechargeUserInfoDto();
        AliPayConfig aliPayConfig = (AliPayConfig) paymentRequestDto.getPayConfigByClass(AliPayConfig.class);
        /*AliPayConfig aliPayConfig = (AliPayConfig) payConfig.get(paymentRequestDto.getAppid());
        if(null == aliPayConfig){
            aliPayConfig = this.aliPayConfig;
        }*/
        String serverUrl = aliPayConfig.getServerUrl();
        String appId = aliPayConfig.getAppId();
        String privateKey = aliPayConfig.getPrivateKey();
        String format = aliPayConfig.getFormat();
        String charset = aliPayConfig.getCharset();
        String alipayPublicKey = aliPayConfig.getAlipayPublicKey();
        String signType = aliPayConfig.getSignType();
        //实例化客户端
//        AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do", APP_ID, APP_PRIVATE_KEY, "json", CHARSET, ALIPAY_PUBLIC_KEY, "RSA2");
        AlipayClient alipayClient = new DefaultAlipayClient(serverUrl, appId, privateKey, format, charset, alipayPublicKey, signType);
        //实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称：alipay.trade.app.pay
        AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
        //SDK已经封装掉了公共参数，这里只需要传入业务参数。以下方法为sdk的model入参方式(model和biz_content同时存在的情况下取biz_content)。
        AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
        model.setBody("");
        model.setSubject(paymentRequestDto.getBody());
        model.setOutTradeNo(paymentRequestDto.getOrderNo());
        model.setTimeExpire(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS,paymentRequestDto.getExpireTime()));
        //model.setTimeoutExpress("3m");
//        model.setTotalAmount("0.01");
        model.setTotalAmount(String.valueOf(paymentRequestDto.getTotalAmount().setScale(2,BigDecimal.ROUND_DOWN)));
        model.setProductCode("QUICK_MSECURITY_PAY");
        model.setPassbackParams(paymentRequestDto.getPayWay());
        //设置支付用户信息
        if(null != rechargeUserInfoDto && rechargeUserInfoDto.isCheckUserAuth()){
            ExtUserInfo userInfo = new ExtUserInfo();
            userInfo.setName(rechargeUserInfoDto.getUserName());//实名认证姓名
            userInfo.setCertType("IDENTITY_CARD");//实名认证证件类型
            userInfo.setCertNo(rechargeUserInfoDto.getCertificateNo());//实名认证证件号
            userInfo.setNeedCheckInfo("T");//是否需要实名认证
            model.setExtUserInfo(userInfo);
        }
        request.setBizModel(model);
        request.setNotifyUrl(aliPayConfig.getPayNotifyUrl());

        try {
            LogSyncUtil.logSync("支付宝直连 下单,交易编号:{},请求参数:{}",paymentRequestDto.getOrderNo(),request);
            //这里和普通的接口调用不同，使用的是sdkExecute
            AlipayTradeAppPayResponse response = alipayClient.sdkExecute(request);
            LogSyncUtil.logSync("支付宝直连 下单,交易编号:{},返回结果:{}",paymentRequestDto.getOrderNo(),response);
            if (response.isSuccess()) {
                return ResultMap.ok()
                        .put("data",response.getBody())
                        .put("paySubType",aliPayConfig.getName())
                        ;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return ResultMap.error(-1,"调用失败");
    }

    /**
     * 主扫
     * @param paymentRequestDto
     * @return
     */
    public ResultMap mainPay(PaymentRequestDto paymentRequestDto){
        RechargeUserInfoDto rechargeUserInfoDto = paymentRequestDto.getRechargeUserInfoDto();
        AliPayConfig aliPayConfig = (AliPayConfig) paymentRequestDto.getPayConfigByClass(AliPayConfig.class);
        /*AliPayConfig aliPayConfig = (AliPayConfig) payConfig.get(paymentRequestDto.getAppid());
        if(null == aliPayConfig){
            aliPayConfig = this.aliPayConfig;
        }*/
        String serverUrl = aliPayConfig.getServerUrl();
        String appId = aliPayConfig.getAppId();
        String privateKey = aliPayConfig.getPrivateKey();
        String format = aliPayConfig.getFormat();
        String charset = aliPayConfig.getCharset();
        String alipayPublicKey = aliPayConfig.getAlipayPublicKey();
        String signType = aliPayConfig.getSignType();
        //实例化客户端
//        AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do", APP_ID, APP_PRIVATE_KEY, "json", CHARSET, ALIPAY_PUBLIC_KEY, "RSA2");
        AlipayClient alipayClient = new DefaultAlipayClient(serverUrl, appId, privateKey, format, charset, alipayPublicKey, signType);
        //实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称：alipay.trade.app.pay
        AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest();
        //SDK已经封装掉了公共参数，这里只需要传入业务参数。以下方法为sdk的model入参方式(model和biz_content同时存在的情况下取biz_content)。
        AlipayTradePrecreateModel model = new AlipayTradePrecreateModel();
        model.setBody("");
        model.setSubject(paymentRequestDto.getBody());
        model.setOutTradeNo(paymentRequestDto.getOrderNo());
//        model.setTimeExpire(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS,paymentRequestDto.getExpireTime()));
        //model.setTimeoutExpress("3m");
//        model.setTotalAmount("0.01");
        model.setTotalAmount(String.valueOf(paymentRequestDto.getTotalAmount().setScale(2,BigDecimal.ROUND_DOWN)));
        model.setPassbackParams(paymentRequestDto.getPayWay());
        //设置支付用户信息
        if(null != rechargeUserInfoDto && rechargeUserInfoDto.isCheckUserAuth()){
            ExtUserInfo userInfo = new ExtUserInfo();
            userInfo.setName(rechargeUserInfoDto.getUserName());//实名认证姓名
            userInfo.setCertType("IDENTITY_CARD");//实名认证证件类型
            userInfo.setCertNo(rechargeUserInfoDto.getCertificateNo());//实名认证证件号
            userInfo.setNeedCheckInfo("T");//是否需要实名认证
            model.setExtUserInfo(userInfo);
        }
        request.setBizModel(model);
        request.setNotifyUrl(aliPayConfig.getPayNotifyUrl());
        try {
            LogSyncUtil.logSync("支付宝直连 主扫下单,交易编号:{},请求参数:{}",paymentRequestDto.getOrderNo(),request);
            //这里和普通的接口调用不同，使用的是sdkExecute
            AlipayTradePrecreateResponse response = alipayClient.execute(request);
            LogSyncUtil.logSync("支付宝直连 主扫下单,交易编号:{},返回结果:{}",paymentRequestDto.getOrderNo(),response);
            if (response.isSuccess()) {
                String url = response.getQrCode();
                Map<String, String> data = new HashMap<>();
                data.put("url", "alipays://platformapi/startapp?appId=20000067&url="+url);
                return ResultMap.ok()
                        .put("data",data)
                        .put("paySubType",aliPayConfig.getName())
                        ;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return ResultMap.error(-1,"调用失败");
    }


    /**
     * 支付宝退款
     * @param refundRequestDto
     * @return
     */
    @Override
    public ResultMap aliRefundNotify(RefundRequestDto refundRequestDto){
        AliPayConfig aliPayConfig = (AliPayConfig) refundRequestDto.getPayConfigByClass(AliPayConfig.class);
        String orderNo = refundRequestDto.getOrderNo();
        BigDecimal amount = refundRequestDto.getRefundAmount();
        String body = refundRequestDto.getRefundMsg();
//        AliPayConfig aliPayConfig = (AliPayConfig) payConfig.get(appid);
//        if(null == aliPayConfig){
//            aliPayConfig = this.aliPayConfig;
//        }
        String serverUrl = aliPayConfig.getServerUrl();
        String appId = aliPayConfig.getAppId();
        String privateKey = aliPayConfig.getPrivateKey();
        String format = aliPayConfig.getFormat();
        String charset = aliPayConfig.getCharset();
        String alipayPublicKey = aliPayConfig.getAlipayPublicKey();
        String signType = aliPayConfig.getSignType();
        AlipayClient alipayClient = new DefaultAlipayClient(serverUrl,appId,privateKey,format,charset,alipayPublicKey,signType);
        AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
        JSONObject bizContent = new JSONObject();
        bizContent.put("out_trade_no", orderNo);
        bizContent.put("refund_amount", amount);
        String out_request_no = RandomUtil.getRandom(RandomUtil.REFUND_NO);
        bizContent.put("out_request_no", out_request_no);
        bizContent.put("refund_reason", body);
        //// 返回参数选项，按需传入
        JSONArray queryOptions = new JSONArray();
        queryOptions.add("refund_detail_item_list");
        bizContent.put("query_options", queryOptions);
        request.setBizContent(bizContent.toString());
        try {
            LogSyncUtil.logSync("支付宝直连 退款,交易编号:{},请求参数:{}",refundRequestDto.getRefundNo(),request);
            AlipayTradeRefundResponse response = alipayClient.execute(request);
            String responseBody = response.getBody();
            JSONObject jsonObject = JSONObject.parseObject(responseBody);
            log.debug("返回数据》》》{}",jsonObject);
            JSONObject alipay_trade_refund_response = jsonObject.getJSONObject("alipay_trade_refund_response");
            LogSyncUtil.logSync("支付宝直连 退款,交易编号:{},返回结果:{}",refundRequestDto.getRefundNo(),response);
            if(response.isSuccess()){
                System.out.println("调用成功");
                if("10000".equals(alipay_trade_refund_response.getString("code"))){//网关返回状态 10000 代表成功
                    alipay_trade_refund_response.put("out_refund_no",out_request_no);
                    alipay_trade_refund_response.put("refund_id",out_request_no);
                    String refund_fee = alipay_trade_refund_response.get("refund_fee").toString();
                    alipay_trade_refund_response.put("refund_fee", (StringUtils.isEmpty(refund_fee) ? 0 : Double.valueOf(refund_fee)) * 100);
                    String send_back_fee = alipay_trade_refund_response.get("send_back_fee").toString();
                    alipay_trade_refund_response.put("send_back_fee", (StringUtils.isEmpty(send_back_fee) ? 0 : Double.valueOf(send_back_fee)) * 100);
                    alipay_trade_refund_response.put("fund_change","Y");
                    return ResultMap.ok()
                            .put("data",alipay_trade_refund_response)
                            ;
                } else {
                    return ResultMap.error(Integer.parseInt(alipay_trade_refund_response.getString("code")),alipay_trade_refund_response.getString("sub_msg"));
                }
            } else {
                System.out.println("调用失败");
//                return ResultMap.error(-1,"调用失败");
                return ResultMap.error(Integer.parseInt(alipay_trade_refund_response.getString("code")),alipay_trade_refund_response.getString("sub_msg"));
            }
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        return ResultMap.error(-1,"调用失败");
    }

    /**
     * 查询订单
     * @param paymentRequestDto
     * @return
     */
    @Override
    public PaymentInfoResponseDto queryOrder(PaymentRequestDto paymentRequestDto){
        AliPayConfig aliPayConfig = (AliPayConfig) paymentRequestDto.getPayConfigByClass(AliPayConfig.class);
        String orderNo = paymentRequestDto.getOrderNo();
//        AliPayConfig aliPayConfig = (AliPayConfig) payConfig.get(appid);
//        if(null == aliPayConfig){
//            aliPayConfig = this.aliPayConfig;
//        }
        String appId = aliPayConfig.getAppId();
        String privateKey = aliPayConfig.getPrivateKey();
        String format = aliPayConfig.getFormat();
        String charset = aliPayConfig.getCharset();
        String signType = aliPayConfig.getSignType();
        String alipayPublicKey = aliPayConfig.getAlipayPublicKey();
        AlipayClient alipayClient = new DefaultAlipayClient(searchUrl, appId,privateKey,format, charset,alipayPublicKey,signType);
        AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
        JSONObject bizContent = new JSONObject();
        bizContent.put("out_trade_no", orderNo);
        request.setBizContent(bizContent.toString());
        try{
            LogSyncUtil.logSync("支付宝直连 查询,交易编号:{},请求参数:{}",paymentRequestDto.getOrderNo(),request);
            AlipayTradeQueryResponse response = alipayClient.execute(request);
            PaymentInfoResponseDto paymentInfoResponseDto = new PaymentInfoResponseDto();
            log.info(" 支付宝查询结果：{} ",paymentInfoResponseDto);
            LogSyncUtil.logSync("支付宝直连 查询,交易编号:{},返回结果:{}",paymentRequestDto.getOrderNo(),paymentInfoResponseDto);
            if(response!=null &&response.isSuccess()&& Constants.ALIPAY_TRADE_SUCCESS.equals(response.getTradeStatus())){
                paymentInfoResponseDto.setOrderNo(orderNo);
                paymentInfoResponseDto.setPayWay("alipay");
                paymentInfoResponseDto.setAppid(appId);
                paymentInfoResponseDto.setPaymentNo(response.getTradeNo());
                paymentInfoResponseDto.setPaymentPrice(new BigDecimal(response.getTotalAmount()));
                paymentInfoResponseDto.setActualPayment(new BigDecimal(response.getBuyerPayAmount()));
                paymentInfoResponseDto.setPaymentSuccessTime(response.getSendPayDate());
                paymentInfoResponseDto.setSuccess(true);
                return paymentInfoResponseDto;
            }else{
                return PaymentInfoResponseDto.error(-1,response.getMsg());
            }
        }catch (Exception e){}
        return PaymentInfoResponseDto.error(-1,"查询支付宝支付订单失败");
    }
    /**
     * 查询退款订单
     * @param refundRequestDto
     * @return
     */
    @Override
    public ResultMap queryRefundOrder(RefundRequestDto refundRequestDto){
        AliPayConfig aliPayConfig = (AliPayConfig) refundRequestDto.getPayConfigByClass(AliPayConfig.class);
        String orderNo = refundRequestDto.getMerOrderId();
        String refundNo = StringUtils.isEmpty(refundRequestDto.getRefundNo()) ? orderNo : refundRequestDto.getRefundNo();
//        AliPayConfig aliPayConfig = (AliPayConfig) payConfig.get(appid);
//        if(null == aliPayConfig){
//            aliPayConfig = this.aliPayConfig;
//        }
        String appId = aliPayConfig.getAppId();
        String privateKey = aliPayConfig.getPrivateKey();
        String format = aliPayConfig.getFormat();
        String charset = aliPayConfig.getCharset();
        String signType = aliPayConfig.getSignType();
        String alipayPublicKey = aliPayConfig.getAlipayPublicKey();
        AlipayClient alipayClient = new DefaultAlipayClient(searchUrl, appId,privateKey,format, charset,alipayPublicKey,signType);
        AlipayTradeFastpayRefundQueryRequest  request = new AlipayTradeFastpayRefundQueryRequest ();
        JSONObject bizContent = new JSONObject();
        bizContent.put("out_trade_no", orderNo);
        bizContent.put("out_request_no", refundNo);
        bizContent.put("query_options", new String[]{"gmt_refund_pay"});
        request.setBizContent(bizContent.toString());
        try{
            LogSyncUtil.logSync("支付宝直连 退款查询,交易编号:{},请求参数:{}",refundRequestDto.getOrderNo(),request);
            AlipayTradeFastpayRefundQueryResponse response = alipayClient.execute(request);
            PaymentInfoResponseDto paymentInfoResponseDto = new PaymentInfoResponseDto();
            JSONObject alipay_trade_refund_response = (JSONObject) JSONObject.toJSON(paymentInfoResponseDto);
            LogSyncUtil.logSync("支付宝直连 退款查询,交易编号:{},返回结果:{}",refundRequestDto.getOrderNo(),paymentInfoResponseDto);
            if(response!=null &&response.isSuccess() && Constants.ALIPAY_REFUND_SUCCESS.equals(response.getRefundStatus())){
                alipay_trade_refund_response.put("out_refund_no",refundNo);
                alipay_trade_refund_response.put("refund_id",response.getTradeNo());
                String refund_fee = response.getRefundAmount();
                alipay_trade_refund_response.put("refund_fee", (StringUtils.isEmpty(refund_fee) ? 0 : Double.valueOf(refund_fee)) * 100);
                String send_back_fee = response.getSendBackFee();
                alipay_trade_refund_response.put("send_back_fee", (StringUtils.isEmpty(send_back_fee) ? 0 : Double.valueOf(send_back_fee)) * 100);
                alipay_trade_refund_response.put("fund_change","Y");
                Date gmt_refund_pay = response.getGmtRefundPay();
                alipay_trade_refund_response.put("refund_time",gmt_refund_pay);
                return ResultMap.ok()
                        .put("data",alipay_trade_refund_response)
                        ;
            }else{
                return ResultMap.error(-1,response.getMsg());
            }
        }catch (Exception e){}
        return ResultMap.error(-1,"查询支付宝退款订单失败");
    }
}
