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

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.jeequan.jeepay.response.RefundOrderQueryResponse;
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.common.utils.bean.BeanUtils;
import com.tzy.framework.pay.config.PayConfig;
import com.tzy.framework.pay.config.QmPay1Config;
import com.tzy.framework.pay.config.QmPay2Config;
import com.tzy.framework.pay.config.QmPayConfig;
import com.tzy.framework.pay.dto.*;
import com.tzy.framework.pay.service.QmPayService;
import com.tzy.framework.util.RandomUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.math.BigDecimal;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * 全民付
 */
@Slf4j
@Service
public class QmPayServiceImpl implements QmPayService {

    @Autowired
    private QmPayConfig qmPayConfig ;
    @Autowired
    private QmPay1Config qmPay1Config ;
    @Autowired
    private QmPay2Config qmPay2Config ;

    @Value("${tzy.app-version:dev}")
    private String appversion;
    @Autowired
    private PayConfig payConfig;

    /**
     * 统一下单
     * @param paymentRequestDto
     * @return
     */
    @Override
    public ResultMap tradeCreate(PaymentRequestDto paymentRequestDto){
        ResultMap resultMap = new ResultMap();
        try{
            RechargeUserInfoDto rechargeUserInfoDto = paymentRequestDto.getRechargeUserInfoDto();
            String payWay = paymentRequestDto.getPayWay();
            QmPayConfig qmPayConfig = new QmPayConfig();
            boolean isSub = false;
            if(paymentRequestDto.getPayWay().contains("qm1")){
//                QmPay1Config qmPayConfig1 = (QmPay1Config) payConfig.getByPayType(paymentRequestDto.getPayWay());
                BeanUtils.copyBeanProp(qmPayConfig,this.qmPay1Config);
                payWay = payWay.substring(0,payWay.length()-1);
                isSub = true;
            }else
            if(paymentRequestDto.getPayWay().contains("qm2")){
//                QmPay2Config qmPayConfig2 = (QmPay2Config) payConfig.getByPayType(paymentRequestDto.getPayWay());
                BeanUtils.copyBeanProp(qmPayConfig,this.qmPay2Config);
                payWay = payWay.substring(0,payWay.length()-1);
                isSub = true;
            }else{
//                QmPayConfig qmPayConfig0 = (QmPayConfig) payConfig.getByPayType(paymentRequestDto.getPayWay());
                qmPayConfig = this.qmPayConfig;
            }
            if(null == qmPayConfig){
                qmPayConfig = this.qmPayConfig;
            }
            String url = getUrl(payWay,PayConstants.QMPAY_METHOD_TRADE_CREATE);
//            String url = getBoxUrl(payWay, PayConstants.QMPAY_METHOD_TRADE_CREATE);
//            if("prod".equals(appversion)){
//                url = getUrl(payWay,PayConstants.QMPAY_METHOD_TRADE_CREATE);
//            }
            String body = String.valueOf(paymentRequestDto.getBody());
            if(StringUtils.isNotEmpty(body) ){
                body = Base64Util.subStringByBytes(body,80)+"...";
            }
            String merchantOrderId = getMerchantOrderId(qmPayConfig);
            JSONObject json = new JSONObject();
            json.put("requestTimestamp", DateFormatUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss"));    // 报文请求时间
            json.put("merOrderId", merchantOrderId); // 商户订单号
//            json.put("merOrderId", paymentRequestDto.getOrderNo()); // 商户订单号
            json.put("mid", qmPayConfig.getMid()); // 商户号
            json.put("tid", qmPayConfig.getTid());    // 终端号
            JSONObject attachedData = new JSONObject();
            int totalPrice = paymentRequestDto.getTotalAmount().multiply(new BigDecimal(100)).intValue();//总金额
            //判断子商户信息
            if(isSub){
                //设置平台分账金额
                int platformAmount = 0;
//                int platformAmount = paymentRequestDto.getTotalAmount().multiply(new BigDecimal(100)).multiply(new BigDecimal(30)).divide(new BigDecimal(100)).intValue();
                //如果是 子商户模式（分账模式）则设置分账金额
                int subPrice = totalPrice - platformAmount;
                json.put("platformAmount", platformAmount);    // 平台分账金额
                json.put("divisionFlag", true);    // 分账标记 购物车模式
                JSONArray subOrders = new JSONArray();
                JSONObject suborder = new JSONObject();
                suborder.put("mid",qmPayConfig.getSub_mid());
                suborder.put("totalAmount",subPrice);
                String subMerOrderId = getMerchantOrderId(qmPayConfig);
                suborder.put("merOrderId",subMerOrderId);
                subOrders.add(suborder);
                json.put("subOrders", subOrders);    // 子商户信息
                attachedData.put("subOrders",subOrders);
            }
            json.put("attachedData",payWay); //附加数据
            json.put("instMid", "APPDEFAULT"); // 业务类型
            json.put("totalAmount", totalPrice);      // 平台支付总金额
            json.put("tradeType", "APP");  // 交易类型，微信必传
            json.put("expireTime", DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS,new Date(paymentRequestDto.getCreateOrderTime().getTime()+2800*60)));  // 订单过期时间
            json.put("orderDesc", body);  // 商品描述
            json.put("notifyUrl", qmPayConfig.getPayNotifyUrl());  // 支付结果通知地址
            json.put("showUrl", qmPayConfig.getShowUrl());  // 订单展示页面
            json.put("msgId", qmPayConfig.getPayFlag());  // 支付标记
            json.put("subAppId", qmPayConfig.getSubAppId());  // 微信子商户appId
            //是否是uac
            /*if(PayConstants.QMPAY_TYPE_UAC.equals(payWay)){//云闪付参数
                //invokeType
                json.put("invokeType", "H5");  // 云闪付参数
                json.put("supportBank", "");  // 支持的银行
            }*/
            //填写用户的实名认证信息
            if(null != rechargeUserInfoDto && rechargeUserInfoDto.isCheckUserAuth()){
                json.put("name",rechargeUserInfoDto.getUserName());//实名认证姓名
                json.put("certType","IDENTITY_CARD");//实名认证证件类型
                json.put("certNo",rechargeUserInfoDto.getCertificateNo());//实名认证证件号
                json.put("fixBuyer","T");//是否需要实名认证
            }
            String authorization = getOpenBodySig(qmPayConfig.getAppid(), qmPayConfig.getAppkey(), json.toString());
            log.info("下单地址》{}",url);
            log.info("请求参数》{}",json);
            log.info("请求头参数》{}",authorization);
            LogSyncUtil.logSync("全民银商支付 预下单,交易编号:{},请求参数:{}",paymentRequestDto.getOrderNo(),json);
            String retJson = send(url, json.toString(), authorization);
            LogSyncUtil.logSync("全民银商支付 预下单,交易编号:{},返回结果:{}",paymentRequestDto.getOrderNo(),retJson);
            JSONObject jsonObject = JSONObject.parseObject(retJson);//转换为json格式数据
            log.info("全民付统一下单，返回数据》{}",jsonObject);
            resultMap.put("merOrderId",merchantOrderId);
            resultMap.put("orderNo",paymentRequestDto.getOrderNo());
            resultMap.put("appPayRequest",jsonObject.getJSONObject("appPayRequest"));
            resultMap.put("data",jsonObject);
            return resultMap;
        }catch (Exception e){
            e.printStackTrace();
            log.error(e.getMessage());
        }
        return ResultMap.error("下单失败");
    }
    /**
     * 查询订单
     * @param payWay
     * @param orderNo
     * @return
     */
    @Override
    public PaymentInfoResponseDto queryOrder(String appid,String payWay, String  orderNo){
        PaymentInfoResponseDto paymentInfoResponseDto = new PaymentInfoResponseDto();
        String errMsg = "";
        try{
            String payWay1 = payWay;
            QmPayConfig qmPayConfig = new QmPayConfig();
            if(payWay.contains("qm1")){
//                QmPay1Config qmPayConfig1 = (QmPay1Config) payConfig.getByPayType(paymentRequestDto.getPayWay());
                BeanUtils.copyBeanProp(qmPayConfig,this.qmPay1Config);
                payWay1 = payWay.substring(0,payWay.length()-1);
            }else
            if(payWay.contains("qm2")){
//                QmPay2Config qmPayConfig2 = (QmPay2Config) payConfig.getByPayType(paymentRequestDto.getPayWay());
                BeanUtils.copyBeanProp(qmPayConfig,this.qmPay2Config);
                payWay1 = payWay.substring(0,payWay.length()-1);
            }else{
//                QmPayConfig qmPayConfig0 = (QmPayConfig) payConfig.getByPayType(paymentRequestDto.getPayWay());
                qmPayConfig = this.qmPayConfig;
            }
            if(null == qmPayConfig){
                qmPayConfig = this.qmPayConfig;
            }
            /*QmPayConfig qmPayConfig = (QmPayConfig) payConfig.getByPayType(payWay);
            if(null == qmPayConfig){
                qmPayConfig = this.qmPayConfig;
            }*/
            String url = getUrl(payWay1,PayConstants.QMPAY_METHOD_QUERY_ORDER);
//            if("prod".equals(appversion)){
//                url = getUrl(payWay1,PayConstants.QMPAY_METHOD_QUERY_ORDER);
//            }
            JSONObject json = new JSONObject();
            json.put("requestTimestamp", DateFormatUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss"));    // 报文请求时间
            json.put("merOrderId", orderNo); // 商户订单号
            json.put("mid", qmPayConfig.getMid()); // 商户号
            json.put("tid", qmPayConfig.getTid());    // 终端号
            json.put("instMid", "APPDEFAULT"); // 业务类型
            String authorization = getOpenBodySig(qmPayConfig.getAppid(), qmPayConfig.getAppkey(), json.toString());
            log.info("查询地址》{}",url);
            log.info("请求参数》{}",json);
            log.info("请求头参数》{}",authorization);
//            String retJsonStr = send(url, json.toString(), authorization);
            LogSyncUtil.logSync("全民银商支付 查询,交易编号:{},请求参数:{}",orderNo,json);
            String retJsonStr = send(url, json.toString(), authorization);
            LogSyncUtil.logSync("全民银商支付 查询,交易编号:{},返回结果:{}",orderNo,retJsonStr);
            JSONObject retJson = JSONObject.parseObject(retJsonStr);//转换为json格式数据
            log.info("全民订单查询，返回数据》{}",retJson);
            if(null != retJson && !retJson.isEmpty()) {
                //判断状态
                if(PayConstants.SUCCESS.equals(retJson.getString("errCode"))){
                    //判断交易状态
                    if(retJson.getString("status").contains(PayConstants.TRADE_SUCCESS) ||
                            retJson.getString("status").contains(PayConstants.SUCCESS)
                    ) {
                        paymentInfoResponseDto.setTradeState(retJson.getString("status"));
                        paymentInfoResponseDto.setTradeStateDesc(retJson.getString("status"));
                        paymentInfoResponseDto.setOrderNo(orderNo);
                        paymentInfoResponseDto.setPayWay(payWay);
                        paymentInfoResponseDto.setPaymentNo(retJson.getString("targetOrderId"));
                        paymentInfoResponseDto.setPaymentPrice(new BigDecimal(retJson.getString("totalAmount")).divide(new BigDecimal(100)).setScale(2, BigDecimal.ROUND_DOWN));
                        paymentInfoResponseDto.setActualPayment(new BigDecimal(retJson.getString("totalAmount")).divide(new BigDecimal(100)).setScale(2, BigDecimal.ROUND_DOWN));
                        if (PayConstants.QMPAY_TYPE_ALIPAY.equals(payWay) || PayConstants.QMPAY_TYPE_ALIPAY2APPLET.equals(payWay)) {
                            paymentInfoResponseDto.setActualPayment(new BigDecimal(retJson.getIntValue("buyerPayAmount")).divide(new BigDecimal(100)).setScale(2, BigDecimal.ROUND_DOWN));
                        }
                        paymentInfoResponseDto.setPaymentSuccessTime(DateUtils.dateTime(DateUtils.YYYY_MM_DD_HH_MM_SS, retJson.getString("payTime")));
                        paymentInfoResponseDto.setSuccess(true);
                        return paymentInfoResponseDto;
                    }else{
                        errMsg = retJson.getString("status");
                    }
                }else{
                    try{
                        errMsg = retJson.getString("errMsg");
                    }catch (Exception e){
                        errMsg = retJson.getString("errInfo");
                    }
                }
            }else{
                errMsg = "查询请求失败！";
            }
        }catch (Exception e){
            e.printStackTrace();
            log.error(e.getMessage());
            errMsg = "下单失败";
        }
        return PaymentInfoResponseDto.error(-2,errMsg);
    }
    /**
     * 退款
     * @param orderNo
     * @param refundPrice
     * @param refundMsg
     * @return
     */
    @Override
    public ResultMap refund( String appid,String payWay, String orderNo,BigDecimal refundPrice,String refundMsg){
        String errMsg = "";
        try{
            String payWay1 = payWay;
            boolean isSub = false;
            QmPayConfig qmPayConfig = new QmPayConfig();
            if(payWay.contains("qm1")){
//                QmPay1Config qmPayConfig1 = (QmPay1Config) payConfig.getByPayType(paymentRequestDto.getPayWay());
                BeanUtils.copyBeanProp(qmPayConfig,this.qmPay1Config);
                payWay1 = payWay.substring(0,payWay.length()-1);
                isSub = true;
            }else
            if(payWay.contains("qm2")){
//                QmPay2Config qmPayConfig2 = (QmPay2Config) payConfig.getByPayType(paymentRequestDto.getPayWay());
                BeanUtils.copyBeanProp(qmPayConfig,this.qmPay2Config);
                payWay1 = payWay.substring(0,payWay.length()-1);
                isSub = true;
            }else{
//                QmPayConfig qmPayConfig0 = (QmPayConfig) payConfig.getByPayType(paymentRequestDto.getPayWay());
                qmPayConfig = this.qmPayConfig;
            }
            if(null == qmPayConfig){
                qmPayConfig = this.qmPayConfig;
            }
            /*QmPayConfig qmPayConfig = (QmPayConfig) payConfig.getByPayType(payWay);
            if(null == qmPayConfig){
                qmPayConfig = this.qmPayConfig;
            }*/
            String refundOrderId = getMerchantOrderId(qmPayConfig);
            String url = getUrl(null,PayConstants.QMPAY_METHOD_REFUND);
            /*String url = getBoxUrl(null,PayConstants.QMPAY_METHOD_REFUND);
            if("prod".equals(appversion)){
                url = getUrl(null,PayConstants.QMPAY_METHOD_REFUND);
            }*/
            JSONObject json = new JSONObject();
            json.put("requestTimestamp", DateFormatUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss"));    // 报文请求时间
            json.put("merOrderId", orderNo); // 商户订单号
            json.put("mid", qmPayConfig.getMid()); // 商户号
            json.put("tid", qmPayConfig.getTid());    // 终端号
            int totalPrice = refundPrice.multiply(new BigDecimal(100)).intValue();
            //判断子商户信息
            if(isSub){
                //设置平台分账金额
//                int platformAmount = refundPrice.multiply(new BigDecimal(100)).multiply(new BigDecimal(30)).divide(new BigDecimal(100)).intValue();
                int platformAmount = 0;
                //如果是 子商户模式（分账模式）则设置分账金额
                int subPrice = totalPrice - platformAmount;
                json.put("platformAmount", platformAmount);    // 平台分账金额
                JSONArray subOrders = new JSONArray();
                JSONObject suborder = new JSONObject();
                suborder.put("mid",qmPayConfig.getSub_mid());
                suborder.put("totalAmount",subPrice);
                String subRefundOrderId = getMerchantOrderId(qmPayConfig);
                suborder.put("refundOrderId",subRefundOrderId);
                subOrders.add(suborder);
                json.put("subOrders", subOrders);    // 子商户信息
            }
            json.put("instMid", "APPDEFAULT"); // 业务类型
            json.put("refundAmount", totalPrice); // 退款金额
            json.put("refundOrderId", refundOrderId); // 退款订单号
            json.put("refundDesc", refundMsg); // 退款说明
            json.put("msgId", qmPayConfig.getRefundFlag());  // 退款标记
            String authorization = getOpenBodySig(qmPayConfig.getAppid(), qmPayConfig.getAppkey(), json.toString());
            log.info("退款地址》{}",url);
            log.info("请求参数》{}",json);
            log.info("请求头参数》{}",authorization);
//            String retJsonStr = send(url, json.toString(), authorization);
            LogSyncUtil.logSync("全民银商支付 退款,交易编号:{},请求参数:{}",orderNo,json);
            String retJsonStr = send(url, json.toString(), authorization);
            LogSyncUtil.logSync("全民银商支付 退款,交易编号:{},返回结果:{}",orderNo,retJsonStr);
            JSONObject retJson = JSONObject.parseObject(retJsonStr);//转换为json格式数据
            log.info("全民订单退款，返回数据》{}",retJson);
            if(null != retJson && !retJson.isEmpty()) {
                //判断状态
                log.info("全民订单退款，判断》{}",PayConstants.SUCCESS.equals(retJson.getString("errCode")));
                if(PayConstants.SUCCESS.equals(retJson.getString("errCode"))){
                    //判断交易状态
                    if(retJson.getString("status").contains(PayConstants.TRADE_SUCCESS)
                        || retJson.getString("status").contains(PayConstants.SUCCESS)
                    ) {
                        Map<String, String> stringStringMap = new HashMap<>();
                        stringStringMap.put("out_refund_no", refundOrderId);
                        stringStringMap.put("refund_id", String.valueOf(retJson.get("refundTargetOrderId")));
                        try{
                            stringStringMap.put("refund_fee", String.valueOf(Double.parseDouble(String.valueOf(retJson.get("refundAmount")))));
                        }catch (NumberFormatException e){
                            stringStringMap.put("refund_fee", String.valueOf(Double.parseDouble(String.valueOf(retJson.get("refundInvoiceAmount")))));
                        }
                        stringStringMap.put("fund_change", "Y");
                        return  ResultMap.ok()
                                .put("data",stringStringMap)
                                ;
                    }else{
                        errMsg = retJson.getString("status");
                    }
                }else{
                    try{
                        errMsg = retJson.getString("errMsg");
                    }catch (Exception e){
                        errMsg = retJson.getString("errInfo");
                    }
                }
            }else{
                errMsg = "退款请求失败！";
            }
        }catch (Exception e){
            e.printStackTrace();
            log.error(e.getMessage());
            errMsg = "退款请求失败";
        }
        return ResultMap.error(-2,errMsg);
    }
    /**
     * 退款 查询
     * @param outRefundNo
     * @return
     */
    @Override
    public ResultMap refundQuery( String appid,String payWay ,String outRefundNo){
        String errMsg = "";
        try{
            String payWay1 = payWay;
            QmPayConfig qmPayConfig = new QmPayConfig();
            if(payWay.contains("qm1")){
//                QmPay1Config qmPayConfig1 = (QmPay1Config) payConfig.getByPayType(paymentRequestDto.getPayWay());
                BeanUtils.copyBeanProp(qmPayConfig,this.qmPay1Config);
                payWay1 = payWay.substring(0,payWay.length()-1);
            }else
            if(payWay.contains("qm2")){
//                QmPay2Config qmPayConfig2 = (QmPay2Config) payConfig.getByPayType(paymentRequestDto.getPayWay());
                BeanUtils.copyBeanProp(qmPayConfig,this.qmPay2Config);
                payWay1 = payWay.substring(0,payWay.length()-1);
            }else{
//                QmPayConfig qmPayConfig0 = (QmPayConfig) payConfig.getByPayType(paymentRequestDto.getPayWay());
                qmPayConfig = this.qmPayConfig;
            }
            if(null == qmPayConfig){
                qmPayConfig = this.qmPayConfig;
            }
            /*QmPayConfig qmPayConfig = (QmPayConfig) payConfig.getByPayType(payWay);
            if(null == qmPayConfig){
                qmPayConfig = this.qmPayConfig;
            }*/
//            String url = getBoxUrl(null,PayConstants.QMPAY_METHOD_REFUND_QUERY);
//            if("prod".equals(appversion)){
               String url = getUrl(null,PayConstants.QMPAY_METHOD_REFUND_QUERY);
//            }
            JSONObject json = new JSONObject();
            json.put("requestTimestamp", DateFormatUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss"));    // 报文请求时间
            json.put("merOrderId", outRefundNo); // 商户订单号
            json.put("mid", qmPayConfig.getMid()); // 商户号
            json.put("tid", qmPayConfig.getTid());    // 终端号
            json.put("instMid", "APPDEFAULT"); // 业务类型
            String authorization = getOpenBodySig(qmPayConfig.getAppid(), qmPayConfig.getAppkey(), json.toString());
            log.info("退款地址》{}",url);
            log.info("请求参数》{}",json);
            log.info("请求头参数》{}",authorization);
//            String retJsonStr = send(url, json.toString(), authorization);
            LogSyncUtil.logSync("全民银商支付 退款查询,交易编号:{},请求参数:{}",outRefundNo,json);
            String retJsonStr = send(url, json.toString(), authorization);
            LogSyncUtil.logSync("全民银商支付 退款查询,交易编号:{},返回结果:{}",outRefundNo,retJsonStr);
            JSONObject retJson = JSONObject.parseObject(retJsonStr);//转换为json格式数据
            log.info("全民订单退款查询，返回数据》{}",retJson);
            if(null != retJson && !retJson.isEmpty()) {
                //判断状态
                if(PayConstants.SUCCESS.equals(retJson.getString("errCode"))){
                    //判断交易状态-退款状态
                    if(retJson.getString("refundStatus").contains(PayConstants.SUCCESS)) {
                        Map<String, String> stringStringMap = new HashMap<>();
                        stringStringMap.put("out_refund_no", String.valueOf(retJson.get("refundOrderId")));
                        stringStringMap.put("refund_id", String.valueOf(retJson.get("refundTargetOrderId")));
                        stringStringMap.put("refund_fee", String.valueOf(Double.parseDouble(String.valueOf(retJson.get("sendBackAmount")))));
                        stringStringMap.put("fund_change", "Y");
                        return  ResultMap.ok()
                                .put("data",stringStringMap)
                                ;
                    }else{
                        errMsg = retJson.getString("status");
                    }
                }else{
                    try{
                        errMsg = retJson.getString("errMsg");
                    }catch (Exception e){
                        errMsg = retJson.getString("errInfo");
                    }
                }
            }else{
                errMsg = "退款查询请求失败！";
            }
        }catch (Exception e){
            e.printStackTrace();
            log.error(e.getMessage());
            errMsg = "退款查询请求失败";
        }
        return ResultMap.error(-2,errMsg);
    }

    /**
     * 关闭订单
     * @param payWay
     * @param orderNo
     * @return
     */
    @Override
    public ResultMap colse(String appid,String payWay,String orderNo){
        String errMsg = "";
        try{
            String payWay1 = payWay;
            QmPayConfig qmPayConfig = new QmPayConfig();
            if(payWay.contains("qm1")){
//                QmPay1Config qmPayConfig1 = (QmPay1Config) payConfig.getByPayType(paymentRequestDto.getPayWay());
                BeanUtils.copyBeanProp(qmPayConfig,this.qmPay1Config);
                payWay1 = payWay.substring(0,payWay.length()-1);
            }else
            if(payWay.contains("qm2")){
//                QmPay2Config qmPayConfig2 = (QmPay2Config) payConfig.getByPayType(paymentRequestDto.getPayWay());
                BeanUtils.copyBeanProp(qmPayConfig,this.qmPay2Config);
                payWay1 = payWay.substring(0,payWay.length()-1);
            }else{
//                QmPayConfig qmPayConfig0 = (QmPayConfig) payConfig.getByPayType(paymentRequestDto.getPayWay());
                qmPayConfig = this.qmPayConfig;
            }
            if(null == qmPayConfig){
                qmPayConfig = this.qmPayConfig;
            }
            /*QmPayConfig qmPayConfig = (QmPayConfig) payConfig.getByPayType(payWay);
            if(null == qmPayConfig){
                qmPayConfig = this.qmPayConfig;
            }*/
            String url = getUrl(payWay,PayConstants.QMPAY_METHOD_CLOSE);
//            if("prod".equals(appversion)){
//                url = getUrl(payWay,PayConstants.QMPAY_METHOD_CLOSE);
//            }
            JSONObject json = new JSONObject();
            json.put("requestTimestamp", DateFormatUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss"));    // 报文请求时间
            json.put("merOrderId", orderNo); // 商户订单号
            json.put("mid", qmPayConfig.getMid()); // 商户号
            json.put("tid", qmPayConfig.getTid());    // 终端号
            json.put("instMid", "APPDEFAULT"); // 业务类型
            String authorization = getOpenBodySig(qmPayConfig.getAppid(), qmPayConfig.getAppkey(), json.toString());
            log.info("查询地址》{}",url);
            log.info("请求参数》{}",json);
            log.info("请求头参数》{}",authorization);
//            String retJsonStr = send(url, json.toString(), authorization);
            LogSyncUtil.logSync("全民银商支付 关闭订单,交易编号:{},请求参数:{}",orderNo,json);
            String retJsonStr = send(url, json.toString(), authorization);
            LogSyncUtil.logSync("全民银商支付 关闭订单,交易编号:{},返回结果:{}",orderNo,retJsonStr);
            JSONObject retJson = JSONObject.parseObject(retJsonStr);//转换为json格式数据
            log.info("全民订单-关闭订单，返回数据》{}",retJson);
            if(null != retJson && !retJson.isEmpty()) {
                //判断状态
                if(PayConstants.SUCCESS.equals(retJson.getString("errCode"))){
                    //判断交易状态
                    if(retJson.getString("status").contains(PayConstants.TRADE_SUCCESS)) {
                        return  ResultMap.ok("关闭成功！")
                                ;
                    }else{
                        errMsg = retJson.getString("status");
                    }
                } else {
                    try{
                        errMsg = retJson.getString("errMsg");
                    }catch (Exception e){
                        errMsg = retJson.getString("errInfo");
                    }
                }
            }else{
                errMsg = "关闭订单请求失败！";
            }
        }catch (Exception e){
            e.printStackTrace();
            log.error(e.getMessage());
            errMsg = "关闭订单失败";
        }
        return ResultMap.error(-2,errMsg);
    }
    /******************************新逻辑*********************************/
    /**
     * 统一下单
     * @param paymentRequestDto
     * @return
     */
    @Override
    public ResultMap tradeCreateNew(PaymentRequestDto paymentRequestDto){
        ResultMap resultMap = new ResultMap();
        try{
            RechargeUserInfoDto rechargeUserInfoDto = paymentRequestDto.getRechargeUserInfoDto();
            String payWay = paymentRequestDto.getPayWay();
            QmPayConfig qmPayConfig = (QmPayConfig) paymentRequestDto.getPayConfigByClass( QmPayConfig.class);
            boolean isSub = paymentRequestDto.getPayConfig().getBooleanValue("isSub");
            /*if(paymentRequestDto.getPayWay().contains("qm1")){
//                QmPay1Config qmPayConfig1 = (QmPay1Config) payConfig.getByPayType(paymentRequestDto.getPayWay());
                BeanUtils.copyBeanProp(qmPayConfig,this.qmPay1Config);
                payWay = payWay.substring(0,payWay.length()-1);
                isSub = true;
            }else
            if(paymentRequestDto.getPayWay().contains("qm2")){
//                QmPay2Config qmPayConfig2 = (QmPay2Config) payConfig.getByPayType(paymentRequestDto.getPayWay());
                BeanUtils.copyBeanProp(qmPayConfig,this.qmPay2Config);
                payWay = payWay.substring(0,payWay.length()-1);
                isSub = true;
            }else{
//                QmPayConfig qmPayConfig0 = (QmPayConfig) payConfig.getByPayType(paymentRequestDto.getPayWay());
                qmPayConfig = this.qmPayConfig;
            }
            if(null == qmPayConfig){
                qmPayConfig = this.qmPayConfig;
            }*/
            String url = getUrlNew(payWay,qmPayConfig,PayConstants.QMPAY_METHOD_TRADE_CREATE);
//            String url = getBoxUrl(payWay, PayConstants.QMPAY_METHOD_TRADE_CREATE);
//            if("prod".equals(appversion)){
//                url = getUrl(payWay,PayConstants.QMPAY_METHOD_TRADE_CREATE);
//            }
            String body = String.valueOf(paymentRequestDto.getBody());
            if(StringUtils.isNotEmpty(body) ){
                body = Base64Util.subStringByBytes(body,80)+"...";
            }
            String merchantOrderId = getMerchantOrderId(qmPayConfig);
            JSONObject json = new JSONObject();
            json.put("requestTimestamp", DateFormatUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss"));    // 报文请求时间
            json.put("merOrderId", merchantOrderId); // 商户订单号
//            json.put("merOrderId", paymentRequestDto.getOrderNo()); // 商户订单号
            json.put("mid", qmPayConfig.getMid()); // 商户号
            json.put("tid", qmPayConfig.getTid());    // 终端号
            JSONObject attachedData = new JSONObject();
            int totalPrice = paymentRequestDto.getTotalAmount().multiply(new BigDecimal(100)).intValue();
            //判断子商户信息
            if(isSub){
                //设置平台分账金额
                int platformAmount = 0;
//                int platformAmount = paymentRequestDto.getTotalAmount().multiply(new BigDecimal(100)).multiply(new BigDecimal(30)).divide(new BigDecimal(100)).intValue();
                //如果是 子商户模式（分账模式）则设置分账金额
                int subPrice = totalPrice - platformAmount;
                json.put("platformAmount", platformAmount);    // 平台分账金额
                json.put("divisionFlag", true);    // 分账标记 购物车模式
                JSONArray subOrders = new JSONArray();
                JSONObject suborder = new JSONObject();
                suborder.put("mid",qmPayConfig.getSub_mid());
                suborder.put("totalAmount",subPrice);
                String subMerOrderId = getMerchantOrderId(qmPayConfig);
                suborder.put("merOrderId",subMerOrderId);
                subOrders.add(suborder);
                json.put("subOrders", subOrders);    // 子商户信息
                attachedData.put("subOrders",subOrders);
            }
//            json.put("instMid", "APPDEFAULT"); // 业务类型
            json.put("instMid", qmPayConfig.getInstMid()); // 业务类型
            json.put("totalAmount", totalPrice);      // 平台支付总金额
            json.put("expireTime", DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS,paymentRequestDto.getExpireTime()));  // 订单过期时间
            json.put("orderDesc", body);  // 商品描述
            json.put("notifyUrl", qmPayConfig.getPayNotifyUrl());  // 支付结果通知地址
            json.put("showUrl", qmPayConfig.getShowUrl());  // 订单展示页面
            json.put("msgId", qmPayConfig.getPayFlag());  // 支付标记
            json.put("subAppId", qmPayConfig.getSubAppId());  // 微信子商户appId
            if("MINIDEFAULT".equals(qmPayConfig.getInstMid()) && payWay.contains("wxpay")){
                json.put("subOpenId", paymentRequestDto.getWxOpenid());  // 微信子用户openid
                json.put("tradeType", "MINI");  // 交易类型，微信必传
                json.put("srcReserve",payWay); //附加数据
            } else {
                json.put("tradeType", "APP");  // 交易类型，微信必传
                json.put("attachedData", payWay); //附加数据
            }
//            json.put("limitCreditCard", ""+qmPayConfig.isLimitCreditCard());  // 是否需要 限制信用 卡支付
            //是否是uac
            /*if(PayConstants.QMPAY_TYPE_UAC.equals(payWay)){//云闪付参数
                //invokeType
                json.put("invokeType", "H5");  // 云闪付参数
                json.put("supportBank", "");  // 支持的银行
            }*/
            //填写用户的实名认证信息
            if(null != rechargeUserInfoDto && rechargeUserInfoDto.isCheckUserAuth()){
                json.put("name",rechargeUserInfoDto.getUserName());//实名认证姓名
                json.put("certType","IDENTITY_CARD");//实名认证证件类型
                json.put("certNo",rechargeUserInfoDto.getCertificateNo());//实名认证证件号
                json.put("fixBuyer","T");//是否需要实名认证
            }
            String authorization = getOpenBodySig(qmPayConfig.getAppid(), qmPayConfig.getAppkey(), json.toString());
            log.info("下单地址》{}",url);
            log.info("请求参数》{}",json);
            log.info("请求头参数》{}",authorization);
//            String retJson = send(url, json.toString(), authorization);
            LogSyncUtil.logSync("全民银商支付 预下单,交易编号:{},请求参数:{}",paymentRequestDto.getOrderNo(),json);
            String retJson = send(url, json.toString(), authorization);
            LogSyncUtil.logSync("全民银商支付 预下单,交易编号:{},返回结果:{}",paymentRequestDto.getOrderNo(),retJson);
            log.info("全民付统一下单，返回数据》{}",retJson);
            JSONObject jsonObject = JSONObject.parseObject(retJson);//转换为json格式数据
            log.info("全民付统一下单，返回数据》{}",jsonObject);
            resultMap.put("merOrderId",merchantOrderId);
            resultMap.put("orderNo",paymentRequestDto.getOrderNo());
            resultMap.put("appPayRequest",jsonObject.getJSONObject("appPayRequest"));
            resultMap.put("data",jsonObject);
            return resultMap;
        }catch (Exception e){
            log.error("下单异常信息 {}",e);
        }
        return ResultMap.error("下单失败");
    }
    /**
     * 关闭订单
     * @param paymentRequestDto
     * @return
     */
    @Override
    public ResultMap colseNew(PaymentRequestDto paymentRequestDto){
        String errMsg = "";
        try{
            String payWay = paymentRequestDto.getPayWay();
            QmPayConfig qmPayConfig = (QmPayConfig) paymentRequestDto.getPayConfigByClass( QmPayConfig.class);
            String url = getUrlNew(payWay,qmPayConfig,PayConstants.QMPAY_METHOD_CLOSE);
//            if("prod".equals(appversion)){
//                url = getUrl(payWay,PayConstants.QMPAY_METHOD_CLOSE);
//            }
            JSONObject json = new JSONObject();
            json.put("requestTimestamp", DateFormatUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss"));    // 报文请求时间
            json.put("merOrderId", paymentRequestDto.getOrderNo()); // 商户订单号
            json.put("mid", qmPayConfig.getMid()); // 商户号
            json.put("tid", qmPayConfig.getTid());    // 终端号
            json.put("instMid", qmPayConfig.getInstMid()); // 业务类型
            String authorization = getOpenBodySig(qmPayConfig.getAppid(), qmPayConfig.getAppkey(), json.toString());
            log.info("查询地址》{}",url);
            log.info("请求参数》{}",json);
            log.info("请求头参数》{}",authorization);
//            String retJsonStr = send(url, json.toString(), authorization);
            LogSyncUtil.logSync("全民银商支付 关闭订单,交易编号:{},请求参数:{}",paymentRequestDto.getOrderNo(),json);
            String retJsonStr = send(url, json.toString(), authorization);
            LogSyncUtil.logSync("全民银商支付 关闭订单,交易编号:{},返回结果:{}",paymentRequestDto.getOrderNo(),retJsonStr);
            JSONObject retJson = JSONObject.parseObject(retJsonStr);//转换为json格式数据
            log.info("全民订单-关闭订单，返回数据》{}",retJson);
            if(null != retJson && !retJson.isEmpty()) {
                //判断状态
                if(PayConstants.SUCCESS.equals(retJson.getString("errCode"))){
                    //判断交易状态
                    if(retJson.getString("status").contains(PayConstants.TRADE_SUCCESS)) {
                        return  ResultMap.ok("关闭成功！")
                                ;
                    }else{
                        errMsg = retJson.getString("status");
                    }
                } else {
                    try{
                        errMsg = retJson.getString("errMsg");
                    }catch (Exception e){
                        errMsg = retJson.getString("errInfo");
                    }
                }
            }else{
                errMsg = "关闭订单请求失败！";
            }
        }catch (Exception e){
            e.printStackTrace();
            log.error(e.getMessage());
            errMsg = "关闭订单失败";
        }
        return ResultMap.error(-2,errMsg);
    }
    /**
     * 查询订单
     * @return
     */
    @Override
    public PaymentInfoResponseDto queryOrder(PaymentRequestDto paymentRequestDto){
        PaymentInfoResponseDto paymentInfoResponseDto = new PaymentInfoResponseDto();
        String errMsg = "";
        try{
            String payWay = paymentRequestDto.getPayWay();
            String orderNo = paymentRequestDto.getOrderNo();
            QmPayConfig qmPayConfig = (QmPayConfig) paymentRequestDto.getPayConfigByClass(QmPayConfig.class);
            /*QmPayConfig qmPayConfig = new QmPayConfig();
            if(payWay.contains("qm1")){
//                QmPay1Config qmPayConfig1 = (QmPay1Config) payConfig.getByPayType(paymentRequestDto.getPayWay());
                BeanUtils.copyBeanProp(qmPayConfig,this.qmPay1Config);
                payWay1 = payWay.substring(0,payWay.length()-1);
            }else
            if(payWay.contains("qm2")){
//                QmPay2Config qmPayConfig2 = (QmPay2Config) payConfig.getByPayType(paymentRequestDto.getPayWay());
                BeanUtils.copyBeanProp(qmPayConfig,this.qmPay2Config);
                payWay1 = payWay.substring(0,payWay.length()-1);
            }else{
//                QmPayConfig qmPayConfig0 = (QmPayConfig) payConfig.getByPayType(paymentRequestDto.getPayWay());
                qmPayConfig = this.qmPayConfig;
            }
            if(null == qmPayConfig){
                qmPayConfig = this.qmPayConfig;
            }*/
            /*QmPayConfig qmPayConfig = (QmPayConfig) payConfig.getByPayType(payWay);
            if(null == qmPayConfig){
                qmPayConfig = this.qmPayConfig;
            }*/
            String url = getUrlNew(payWay,qmPayConfig,PayConstants.QMPAY_METHOD_QUERY_ORDER);
//            String url = getBoxUrl(payWay1,PayConstants.QMPAY_METHOD_QUERY_ORDER);
//            if("prod".equals(appversion)){
//                url = getUrl(payWay,PayConstants.QMPAY_METHOD_QUERY_ORDER);
//            }
            JSONObject json = new JSONObject();
            json.put("requestTimestamp", DateFormatUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss"));    // 报文请求时间
            json.put("merOrderId", orderNo); // 商户订单号
            json.put("mid", qmPayConfig.getMid()); // 商户号
            json.put("tid", qmPayConfig.getTid());    // 终端号
            json.put("instMid", qmPayConfig.getInstMid()); // 业务类型
            String authorization = getOpenBodySig(qmPayConfig.getAppid(), qmPayConfig.getAppkey(), json.toString());
            log.info("查询地址》{}",url);
            log.info("请求参数》{}",json);
            log.info("请求头参数》{}",authorization);
//            String retJsonStr = send(url, json.toString(), authorization);
            LogSyncUtil.logSync("全民银商支付 查询订单,交易编号:{},请求参数:{}",paymentRequestDto.getOrderNo(),json);
            String retJsonStr = send(url, json.toString(), authorization);
            LogSyncUtil.logSync("全民银商支付 查询订单,交易编号:{},返回结果:{}",paymentRequestDto.getOrderNo(),retJsonStr);
            JSONObject retJson = JSONObject.parseObject(retJsonStr);//转换为json格式数据
            log.info("全民订单查询，返回数据》{}",retJson);
            if(null != retJson && !retJson.isEmpty()) {
                //判断状态
                if(PayConstants.SUCCESS.equals(retJson.getString("errCode"))){
                    //判断交易状态
                    if(retJson.getString("status").contains(PayConstants.TRADE_SUCCESS) ||
                            retJson.getString("status").contains(PayConstants.SUCCESS)
                    ) {
                        paymentInfoResponseDto.setOrderNo(orderNo);
                        paymentInfoResponseDto.setPayWay(payWay);
                        paymentInfoResponseDto.setPaymentNo(retJson.getString("targetOrderId"));
                        paymentInfoResponseDto.setPaymentPrice(new BigDecimal(retJson.getString("totalAmount")).divide(new BigDecimal(100)).setScale(2, BigDecimal.ROUND_UP));
                        paymentInfoResponseDto.setActualPayment(new BigDecimal(retJson.getString("totalAmount")).divide(new BigDecimal(100)).setScale(2, BigDecimal.ROUND_UP));
                        if (payWay.contains(PayConstants.QMPAY_TYPE_ALIPAY) || payWay.contains(PayConstants.QMPAY_TYPE_ALIPAY2APPLET)) {
                            paymentInfoResponseDto.setActualPayment(new BigDecimal(retJson.getIntValue("buyerPayAmount")).divide(new BigDecimal(100)).setScale(2, BigDecimal.ROUND_UP));
                        }
                        paymentInfoResponseDto.setPaymentSuccessTime(DateUtils.dateTime(DateUtils.YYYY_MM_DD_HH_MM_SS, retJson.getString("payTime")));
                        paymentInfoResponseDto.setSuccess(true);
                        return paymentInfoResponseDto;
                    }else{
                        errMsg = retJson.getString("status");
                    }
                }else{
                    try{
                        errMsg = retJson.getString("errMsg");
                    }catch (Exception e){
                        errMsg = retJson.getString("errInfo");
                    }
                }
            }else{
                errMsg = "查询请求失败！";
            }
        }catch (Exception e){
            e.printStackTrace();
            log.error(e.getMessage());
            errMsg = "下单失败";
        }
        return PaymentInfoResponseDto.error(-2,errMsg);
    }
    /**
     * 退款
     * @param refundRequestDto
     * @return
     */
    @Override
    public ResultMap refund( RefundRequestDto refundRequestDto){
        String errMsg = "";
        try{
            String payWay = refundRequestDto.getPayWay();
            boolean isSub = refundRequestDto.getPayConfig().getBooleanValue("isSub");
            String orderNo = refundRequestDto.getOrderNo();
            BigDecimal refundPrice = refundRequestDto.getRefundAmount();
            String refundMsg = refundRequestDto.getRefundMsg();
            QmPayConfig qmPayConfig = (QmPayConfig) refundRequestDto.getPayConfigByClass(QmPayConfig.class);
            /*if(payWay.contains("qm1")){
//                QmPay1Config qmPayConfig1 = (QmPay1Config) payConfig.getByPayType(paymentRequestDto.getPayWay());
                BeanUtils.copyBeanProp(qmPayConfig,this.qmPay1Config);
                payWay1 = payWay.substring(0,payWay.length()-1);
                isSub = true;
            }else
            if(payWay.contains("qm2")){
//                QmPay2Config qmPayConfig2 = (QmPay2Config) payConfig.getByPayType(paymentRequestDto.getPayWay());
                BeanUtils.copyBeanProp(qmPayConfig,this.qmPay2Config);
                payWay1 = payWay.substring(0,payWay.length()-1);
                isSub = true;
            }else{
//                QmPayConfig qmPayConfig0 = (QmPayConfig) payConfig.getByPayType(paymentRequestDto.getPayWay());
                qmPayConfig = this.qmPayConfig;
            }
            if(null == qmPayConfig){
                qmPayConfig = this.qmPayConfig;
            }*/
            /*QmPayConfig qmPayConfig = (QmPayConfig) payConfig.getByPayType(payWay);
            if(null == qmPayConfig){
                qmPayConfig = this.qmPayConfig;
            }*/
            String refundOrderId = getMerchantOrderId(qmPayConfig);
//            String url = getBoxUrl(null,PayConstants.QMPAY_METHOD_REFUND);
//            if("prod".equals(appversion)){
                String url = getUrlNew(null,qmPayConfig,PayConstants.QMPAY_METHOD_REFUND);
//            }
            JSONObject json = new JSONObject();
            json.put("requestTimestamp", DateFormatUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss"));    // 报文请求时间
            json.put("merOrderId", orderNo); // 商户订单号
            json.put("mid", qmPayConfig.getMid()); // 商户号
            json.put("tid", qmPayConfig.getTid());    // 终端号
            int totalPrice = refundPrice.multiply(new BigDecimal(100)).intValue();
            //判断子商户信息
            if(isSub){
                //设置平台分账金额
//                int platformAmount = refundPrice.multiply(new BigDecimal(100)).multiply(new BigDecimal(30)).divide(new BigDecimal(100)).intValue();
                int platformAmount = 0;
                //如果是 子商户模式（分账模式）则设置分账金额
                int subPrice = totalPrice - platformAmount;
                json.put("platformAmount", 0);    // 平台分账金额
                JSONArray subOrders = new JSONArray();
                JSONObject suborder = new JSONObject();
                suborder.put("mid",qmPayConfig.getSub_mid());
                suborder.put("totalAmount",subPrice);
                String subRefundOrderId = getMerchantOrderId(qmPayConfig);
                suborder.put("refundOrderId",subRefundOrderId);
                subOrders.add(suborder);
                json.put("subOrders", subOrders);    // 子商户信息
            }
            json.put("instMid", qmPayConfig.getInstMid()); // 业务类型
            json.put("refundAmount", totalPrice); // 退款金额
            json.put("refundOrderId", refundOrderId); // 退款订单号
            json.put("refundDesc", refundMsg); // 退款说明
            json.put("msgId", qmPayConfig.getRefundFlag());  // 退款标记
            String authorization = getOpenBodySig(qmPayConfig.getAppid(), qmPayConfig.getAppkey(), json.toString());
            log.info("退款地址》{}",url);
            log.info("请求参数》{}",json);
            log.info("请求头参数》{}",authorization);
//            String retJsonStr = send(url, json.toString(), authorization);
            LogSyncUtil.logSync("全民银商支付 退款,交易编号:{},请求参数:{}",orderNo,json);
            String retJsonStr = send(url, json.toString(), authorization);
            LogSyncUtil.logSync("全民银商支付 退款,交易编号:{},返回结果:{}",orderNo,retJsonStr);
            JSONObject retJson = JSONObject.parseObject(retJsonStr);//转换为json格式数据
            log.info("全民订单退款，返回数据》{}",retJson);
            if(null != retJson && !retJson.isEmpty()) {
                //判断状态
                if(PayConstants.SUCCESS.equals(retJson.getString("errCode"))){
                    //判断交易状态
                    if(retJson.getString("status").contains(PayConstants.TRADE_SUCCESS)
                            || retJson.getString("status").contains(PayConstants.SUCCESS)
                    ) {
                        Map<String, String> stringStringMap = new HashMap<>();
                        stringStringMap.put("out_refund_no", refundOrderId);
                        stringStringMap.put("refund_id", String.valueOf(retJson.get("refundTargetOrderId")));
                        try{
                            stringStringMap.put("refund_fee", String.valueOf(Double.parseDouble(String.valueOf(retJson.get("refundAmount")))));
                        }catch (NumberFormatException e){
                            stringStringMap.put("refund_fee", String.valueOf(Double.parseDouble(String.valueOf(retJson.get("refundInvoiceAmount")))));
                        }
                        stringStringMap.put("fund_change", "Y");
                        return  ResultMap.ok()
                                .put("data",stringStringMap)
                                ;
                    }else{
                        errMsg = retJson.getString("status");
                    }
                }else{
                    try{
                        errMsg = retJson.getString("errMsg");
                    }catch (Exception e){
                        errMsg = retJson.getString("errInfo");
                    }
                }
            }else{
                errMsg = "退款请求失败！";
            }
        }catch (Exception e){
            e.printStackTrace();
            log.error(e.getMessage());
            errMsg = "退款请求失败";
        }
        return ResultMap.error(-2,errMsg);
    }
    /**
     * 退款 查询
     * @param refundRequestDto
     * @return
     */
    @Override
    public ResultMap refundQuery( RefundRequestDto refundRequestDto){
        String errMsg = "";
        try{
            String payWay = refundRequestDto.getPayWay();
            QmPayConfig qmPayConfig = (QmPayConfig) refundRequestDto.getPayConfigByClass(QmPayConfig.class);
            String outRefundNo = refundRequestDto.getRefundNo();
            /*if(payWay.contains("qm1")){
//                QmPay1Config qmPayConfig1 = (QmPay1Config) payConfig.getByPayType(paymentRequestDto.getPayWay());
                BeanUtils.copyBeanProp(qmPayConfig,this.qmPay1Config);
                payWay1 = payWay.substring(0,payWay.length()-1);
            }else
            if(payWay.contains("qm2")){
//                QmPay2Config qmPayConfig2 = (QmPay2Config) payConfig.getByPayType(paymentRequestDto.getPayWay());
                BeanUtils.copyBeanProp(qmPayConfig,this.qmPay2Config);
                payWay1 = payWay.substring(0,payWay.length()-1);
            }else{
//                QmPayConfig qmPayConfig0 = (QmPayConfig) payConfig.getByPayType(paymentRequestDto.getPayWay());
                qmPayConfig = this.qmPayConfig;
            }
            if(null == qmPayConfig){
                qmPayConfig = this.qmPayConfig;
            }*/
            /*QmPayConfig qmPayConfig = (QmPayConfig) payConfig.getByPayType(payWay);
            if(null == qmPayConfig){
                qmPayConfig = this.qmPayConfig;
            }*/
//            String url = getBoxUrl(null,PayConstants.QMPAY_METHOD_REFUND_QUERY);
//            if("prod".equals(appversion)){
                String url = getUrlNew(null,qmPayConfig,PayConstants.QMPAY_METHOD_REFUND_QUERY);
//            }
            JSONObject json = new JSONObject();
            json.put("requestTimestamp", DateFormatUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss"));    // 报文请求时间
            json.put("merOrderId", outRefundNo); // 商户订单号
            json.put("mid", qmPayConfig.getMid()); // 商户号
            json.put("tid", qmPayConfig.getTid());    // 终端号
            json.put("instMid", qmPayConfig.getInstMid()); // 业务类型
            String authorization = getOpenBodySig(qmPayConfig.getAppid(), qmPayConfig.getAppkey(), json.toString());
            log.info("退款地址》{}",url);
            log.info("请求参数》{}",json);
            log.info("请求头参数》{}",authorization);
//            String retJsonStr = send(url, json.toString(), authorization);
            LogSyncUtil.logSync("全民银商支付 退款查询,交易编号:{},请求参数:{}",outRefundNo,json);
            String retJsonStr = send(url, json.toString(), authorization);
            LogSyncUtil.logSync("全民银商支付 退款查询,交易编号:{},返回结果:{}",outRefundNo,retJsonStr);
            JSONObject retJson = JSONObject.parseObject(retJsonStr);//转换为json格式数据
            log.info("全民订单退款查询，返回数据》{}",retJson);
            if(null != retJson && !retJson.isEmpty()) {
                //判断状态
                if(PayConstants.SUCCESS.equals(retJson.getString("errCode"))){
                    //判断交易状态-退款状态
                    if(retJson.getString("refundStatus").contains(PayConstants.SUCCESS)) {
                        Map<String, String> stringStringMap = new HashMap<>();
                        stringStringMap.put("out_refund_no", String.valueOf(retJson.get("refundOrderId")));
                        stringStringMap.put("refund_id", String.valueOf(retJson.get("refundTargetOrderId")));
                        stringStringMap.put("refund_fee", String.valueOf(Double.parseDouble(String.valueOf(retJson.get("sendBackAmount")))));
                        stringStringMap.put("fund_change", "Y");
                        return  ResultMap.ok()
                                .put("data",stringStringMap)
                                ;
                    }else{
                        errMsg = retJson.getString("status");
                    }
                }else{
                    try{
                        errMsg = retJson.getString("errMsg");
                    }catch (Exception e){
                        errMsg = retJson.getString("errInfo");
                    }
                }
            }else{
                errMsg = "退款查询请求失败！";
            }
        }catch (Exception e){
            e.printStackTrace();
            log.error(e.getMessage());
            errMsg = "退款查询请求失败";
        }
        return ResultMap.error(-2,errMsg);
    }
    /**
     *
     * @param url
     * @param entity
     * @param authorization
     * @return
     * @throws Exception
     */
    public String send(String url, String entity , String authorization) throws Exception {
        CloseableHttpClient httpClient = HttpClients.createDefault();
        HttpPost httpPost = new HttpPost(url);
        httpPost.addHeader("Authorization", authorization);
        StringEntity se = new StringEntity(entity, "UTF-8");
        se.setContentType("application/json");
        httpPost.setEntity(se);
        CloseableHttpResponse response = httpClient.execute(httpPost);
        HttpEntity entity1 = response.getEntity();
        String resStr = null;
        if (entity1 != null) {
            resStr = EntityUtils.toString(entity1, "UTF-8");
        }
        httpClient.close();
        response.close();
        return resStr;
    }
    /**
     * {来源编号(4位)}{时间(yyyyMMddmmHHssSSS)(17位)}{7位随机数}
     * @return
     */
    public  String getMerchantOrderId(QmPayConfig qmPayConfig){
        return qmPayConfig.getMsgSrcId()+ DateUtils.parseDateToStr("yyyyMMddmmHHssSSS",new Date())+ RandomUtil.random(7);
    }

    /**
     * open-body-sig方式获取到Authorization 的值
     * @param appId  f0ec96ad2c3848b5b810e7aadf369e2f
     * @param appKey 775481e2556e4564985f5439a5e6a277
     * @param body   json字符串 String body = "{\"merchantCode\":\"123456789900081\",\"terminalCode\":\"00810001\",\"merchantOrderId\":\"20123333644493200\",\"transactionAmount\":\"1\",\"merchantRemark\":\"测试\",\"payMode\":\"CODE_SCAN\",\"payCode\":\"285668667587422761\",\"transactionCurrencyCode\":\"156\"}";
     * @return
     * @throws Exception
     */
    public String getOpenBodySig(String appId, String appKey, String body)  {
        try{
            String timestamp = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
            String nonce = UUID.randomUUID().toString().replace("-", "");
            byte[] data = body.getBytes("UTF-8");
            InputStream is = new ByteArrayInputStream(data);
            String bodyDigest = DigestUtils.sha256Hex(is);
            String str1_C = appId + timestamp + nonce + bodyDigest;
            byte[] localSignature = hmacSHA256(str1_C.getBytes(), appKey.getBytes());
            String localSignatureStr = Base64.encodeBase64String(localSignature);   // Signature
            is.close();
            return ("OPEN-BODY-SIG AppId=" + "\"" + appId + "\"" + ", Timestamp=" + "\"" + timestamp + "\"" + ", Nonce=" + "\"" + nonce + "\"" + ", Signature=" + "\"" + localSignatureStr + "\"");
        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 加密
     * @param data
     * @param key
     * @return
     * @throws NoSuchAlgorithmException
     * @throws InvalidKeyException
     */
    public static byte[] hmacSHA256(byte[] data, byte[] key) throws NoSuchAlgorithmException, InvalidKeyException {
        String algorithm = "HmacSHA256";
        Mac mac = Mac.getInstance(algorithm);
        mac.init(new SecretKeySpec(key, algorithm));
        return mac.doFinal(data);
    }

    /**
     *
     * @param payWay
     * @param method
     * @return
     */
    public String getBoxUrl(String payWay,String method) throws Exception {
        if(StringUtils.isEmpty(method)){
            throw new Exception("操作失败["+method+"]！");
        }
        String url = "";
        switch (method){
            case PayConstants.QMPAY_METHOD_TRADE_CREATE: //统一下单
                if(StringUtils.isEmpty(payWay) ){
                    throw new Exception("请选择支付类型！");
                }
                if(payWay.contains(PayConstants.QMPAY_TYPE_WX )) {//微信支付
                    url = PayConstants.QMPAY_TRADE_URL_WX_SANDBOX;
                }else if (payWay.contains(PayConstants.QMPAY_TYPE_ALIPAY )){//支付宝
                    url = PayConstants.QMPAY_TRADE_URL_ALIPAY_SANDBOX;
                }else if (payWay.contains(PayConstants.QMPAY_TYPE_ALIPAY2APPLET )){//支付宝跳小程序
                    url = PayConstants.QMPAY_TRADE_URL_ALIPAY2APPLET_SANDBOX;
                }else if (payWay.contains(PayConstants.QMPAY_TYPE_ALIPAY2H5 )){//支付宝h5
                    url = PayConstants.QMPAY_TRADE_URL_ALIPAY2H5_SANDBOX;
                }else if (payWay.contains(PayConstants.QMPAY_TYPE_UAC2H5 )){//云闪付h5
                    url = PayConstants.QMPAY_TRADE_URL_UAC2H5_SANDBOX;
                }else if(payWay.contains(PayConstants.QMPAY_TYPE_UAC )){
                    url = PayConstants.QMPAY_TRADE_URL_UAC_SANDBOX;
                }else if(payWay.equals("CCB") || payWay.equals("CNCB") || payWay.equals("CEB") || payWay.equals(" PAB") ){
                    url = PayConstants.QMPAY_TRADE_URL_UAC_SANDBOX;
                }
                break;
            case PayConstants.QMPAY_METHOD_QUERY_ORDER: //查询订单
                url = PayConstants.QMPAY_QUERY_URL_SANDBOX;
                /*if(StringUtils.isEmpty(payWay) ){
                    throw new Exception("请选择支付类型！");
                }
                if(PayConstants.QMPAY_TYPE_WX.equals(payWay)) {//微信支付
                    url = PayConstants.QMPAY_QUERY_URL_WX_SANDBOX;
                }else if (PayConstants.QMPAY_TYPE_ALIPAY.equals(payWay)){//支付宝
                    url = PayConstants.QMPAY_QUERY_URL_SANDBOX;
                }else if (PayConstants.QMPAY_TYPE_ALIPAY2APPLET.equals(payWay)){//支付宝跳小程序
                    url = PayConstants.QMPAY_QUERY_URL_ALIPAY2APPLET_SANDBOX;
                }else if (PayConstants.QMPAY_TYPE_ALIPAY2H5.equals(payWay)){//支付宝跳小程序
                    url = PayConstants.QMPAY_TRADE_URL_ALIPAY2H5_SANDBOX;
                }*/
                break;
            case PayConstants.QMPAY_METHOD_REFUND: //退款
                    url = PayConstants.QMPAY_REFUND_URL_SANDBOX;
                break;
            case PayConstants.QMPAY_METHOD_REFUND_QUERY: //退款-查询
                    url = PayConstants.QMPAY_QUERY_REFUND_URL_SANDBOX;
                break;
            case PayConstants.QMPAY_METHOD_CLOSE: //关闭订单
                if(StringUtils.isEmpty(payWay) ){
                    throw new Exception("请选择支付类型！");
                }
                if(payWay.contains(PayConstants.QMPAY_TYPE_WX )) {//微信支付
                    url = PayConstants.QMPAY_CLOSE_URL_WX_SANDBOX;
                }else if (payWay.contains(PayConstants.QMPAY_TYPE_ALIPAY )){//支付宝
                    url = PayConstants.QMPAY_CLOSE_URL_SANDBOX;
                }else if (payWay.contains(PayConstants.QMPAY_TYPE_ALIPAY2APPLET )){//支付宝跳小程序
                    url = PayConstants.QMPAY_CLOSE_URL_ALIPAY2APPLET_SANDBOX;
                }else{
                    url = PayConstants.QMPAY_CLOSE_URL_SANDBOX;
                }
                break;
        }
        if(StringUtils.isEmpty(url)){
            throw new Exception("请选择支付类型！");
        }
        return url;
    }
    /**
     *
     * @param payWay
     * @param method
     * @return
     */
    public String getUrl(String payWay,String method) throws Exception {
        if(StringUtils.isEmpty(method)){
            throw new Exception("操作失败["+method+"]！");
        }
        String url = "";
        switch (method){
            case PayConstants.QMPAY_METHOD_TRADE_CREATE: //统一下单
                if(StringUtils.isEmpty(payWay) ){
                    throw new Exception("请选择支付类型！");
                }
                if(payWay.contains(PayConstants.QMPAY_TYPE_WX)) {//微信支付
                    url = PayConstants.QMPAY_TRADE_URL_WX;
                }else if (payWay.contains(PayConstants.QMPAY_TYPE_ALIPAY )){//支付宝
                    url = PayConstants.QMPAY_TRADE_URL_ALIPAY;
                }else if (payWay.contains(PayConstants.QMPAY_TYPE_ALIPAY2APPLET )){//支付宝跳小程序
                    url = PayConstants.QMPAY_TRADE_URL_ALIPAY2APPLET;
                }else if (payWay.contains(PayConstants.QMPAY_TYPE_ALIPAY2H5 )){//支付宝跳小程序
                    url = PayConstants.QMPAY_TRADE_URL_ALIPAY2H5;
                }else if (payWay.contains(PayConstants.QMPAY_TYPE_UAC2H5 )){//云闪付h5
                    url = PayConstants.QMPAY_TRADE_URL_UAC2H5;
                }else if(payWay.contains(PayConstants.QMPAY_TYPE_UAC )){
                    url = PayConstants.QMPAY_TRADE_URL_UAC;
                }else if(payWay.equals("CCB") || payWay.equals("CNCB") || payWay.equals("CEB") || payWay.equals(" PAB") ){
                    url = PayConstants.QMPAY_TRADE_URL_UAC;
                }
                break;
            case PayConstants.QMPAY_METHOD_QUERY_ORDER: //查询订单
                url = PayConstants.QMPAY_QUERY_URL;
               /* if(StringUtils.isEmpty(payWay) ){
                    throw new Exception("请选择支付类型！");
                }
                if(PayConstants.QMPAY_TYPE_WX.equals(payWay)) {//微信支付
                    url = PayConstants.QMPAY_QUERY_URL_WX;
                }else if (PayConstants.QMPAY_TYPE_ALIPAY.equals(payWay)){//支付宝
                    url = PayConstants.QMPAY_QUERY_URL;
                }else if (PayConstants.QMPAY_TYPE_ALIPAY2APPLET.equals(payWay)){//支付宝跳小程序
                    url = PayConstants.QMPAY_QUERY_URL_ALIPAY2APPLET;
                }*/
                break;
            case PayConstants.QMPAY_METHOD_REFUND: //退款
                url = PayConstants.QMPAY_REFUND_URL;
                break;
            case PayConstants.QMPAY_METHOD_REFUND_QUERY: //退款
                url = PayConstants.QMPAY_QUERY_REFUND_URL;
                break;
            case PayConstants.QMPAY_METHOD_CLOSE: //关闭订单
                if(StringUtils.isEmpty(payWay) ){
                    throw new Exception("请选择支付类型！");
                }
                if(payWay.contains(PayConstants.QMPAY_TYPE_WX )) {//微信支付
                    url = PayConstants.QMPAY_CLOSE_URL_WX;
                }else if (payWay.contains(PayConstants.QMPAY_TYPE_ALIPAY )){//支付宝
                    url = PayConstants.QMPAY_CLOSE_URL;
                }else if (payWay.contains(PayConstants.QMPAY_TYPE_ALIPAY2APPLET )){//支付宝跳小程序
                    url = PayConstants.QMPAY_CLOSE_URL_ALIPAY2APPLET;
                }else{
                    url = PayConstants.QMPAY_CLOSE_URL;
                }
                break;
            default :
                break;
        }
        if(StringUtils.isEmpty(url)){
            throw new Exception("请选择支付类型！");
        }
        return url;
    }
    /**
     *
     * @param payWay
     * @param method
     * @return
     */
    public String getUrlNew(String payWay,QmPayConfig qmPayConfig,String method) throws Exception {
        if(StringUtils.isEmpty(method)){
            throw new Exception("操作失败["+method+"]！");
        }
        String instMid = qmPayConfig.getInstMid();
        String url = "";
        switch (method){
            case PayConstants.QMPAY_METHOD_TRADE_CREATE: //统一下单
                if(StringUtils.isEmpty(payWay) ){
                    throw new Exception("请选择支付类型！");
                }if (payWay.contains(PayConstants.QMPAY_TYPE_ALIPAY2APPLET ) && "APPDEFAULT".equals(instMid)){//支付宝跳小程序
                    url = PayConstants.QMPAY_TRADE_URL_ALIPAY2APPLET;
                }else if (payWay.contains(PayConstants.QMPAY_TYPE_ALIPAY2APPLET ) && "MINIDEFAULT".equals(instMid)){//支付宝跳小程序-mini
                    url = PayConstants.QMPAY_TRADE_URL_ALIPAY2APPLET_MINI;
                }else if (payWay.contains(PayConstants.QMPAY_TYPE_ALIPAY2H5 ) && "APPDEFAULT".equals(instMid)){//支付宝跳小程序-app
                    url = PayConstants.QMPAY_TRADE_URL_ALIPAY2H5;
                }else if (payWay.contains(PayConstants.QMPAY_TYPE_ALIPAY2H5 ) && "H5DEFAULT".equals(instMid) ){//支付宝-h5
                    url = PayConstants.QMPAY_TRADE_URL_ALIPAY2H5_MINI;
                }else if (payWay.contains(PayConstants.QMPAY_TYPE_WX2H5 ) && "H5DEFAULT".equals(instMid) ){//微信-h5
                    url = PayConstants.QMPAY_TRADE_URL_WX2H5_MINI;
                }else if (payWay.contains(PayConstants.QMPAY_TYPE_UAC2H5 ) && "H5DEFAULT".equals(instMid) ){//云闪付h5
                    url = PayConstants.QMPAY_TRADE_URL_UAC2H5_MINI;
                }else if (payWay.contains(PayConstants.QMPAY_TYPE_UAC2H5 )){//云闪付h5
                    url = PayConstants.QMPAY_TRADE_URL_UAC2H5;
                }else if(payWay.contains(PayConstants.QMPAY_TYPE_UAC ) && "APPDEFAULT".equals(instMid)){
                    url = PayConstants.QMPAY_TRADE_URL_UAC;
                }else if (payWay.contains(PayConstants.QMPAY_TYPE_UAC ) && "MINIDEFAULT".equals(instMid)){//云闪付跳小程序-mini
                    url = PayConstants.QMPAY_TRADE_URL_UAC_MINI;
                }else if(payWay.equals("CCB") || payWay.equals("CNCB") || payWay.equals("CEB") || payWay.equals(" PAB") ){
                    url = PayConstants.QMPAY_TRADE_URL_UAC;
                }else if(payWay.contains(PayConstants.QMPAY_TYPE_WX) && "APPDEFAULT".equals(instMid)) {//微信支付
                    url = PayConstants.QMPAY_TRADE_URL_WX;
                }else if (payWay.contains(PayConstants.QMPAY_TYPE_WX ) && "MINIDEFAULT".equals(instMid)){//微信跳小程序-mini
                    url = PayConstants.QMPAY_TRADE_URL_WX_MINI;
                }else if (payWay.contains(PayConstants.QMPAY_TYPE_ALIPAY )){//支付宝
                    url = PayConstants.QMPAY_TRADE_URL_ALIPAY;
                }
                    break;
            case PayConstants.QMPAY_METHOD_QUERY_ORDER: //查询订单
                url = PayConstants.QMPAY_QUERY_URL;
                if("MINIDEFAULT".equals(instMid)||"H5DEFAULT".equals(instMid)){
                    url = PayConstants.QMPAY_QUERY_URL_MINI;
                }
               /* if(StringUtils.isEmpty(payWay) ){
                    throw new Exception("请选择支付类型！");
                }
                if(PayConstants.QMPAY_TYPE_WX.equals(payWay)) {//微信支付
                    url = PayConstants.QMPAY_QUERY_URL_WX;
                }else if (PayConstants.QMPAY_TYPE_ALIPAY.equals(payWay)){//支付宝
                    url = PayConstants.QMPAY_QUERY_URL;
                }else if (PayConstants.QMPAY_TYPE_ALIPAY2APPLET.equals(payWay)){//支付宝跳小程序
                    url = PayConstants.QMPAY_QUERY_URL_ALIPAY2APPLET;
                }*/
                break;
            case PayConstants.QMPAY_METHOD_REFUND: //退款
                url = PayConstants.QMPAY_REFUND_URL;
                if("MINIDEFAULT".equals(instMid)||"H5DEFAULT".equals(instMid)){
                    url = PayConstants.QMPAY_REFUND_URL_MINI;
                }
                break;
            case PayConstants.QMPAY_METHOD_REFUND_QUERY: //退款
                url = PayConstants.QMPAY_QUERY_REFUND_URL;
                if("MINIDEFAULT".equals(instMid)||"H5DEFAULT".equals(instMid)){
                    url = PayConstants.QMPAY_QUERY_REFUND_URL_MINI;
                }
                break;
            case PayConstants.QMPAY_METHOD_CLOSE: //关闭订单
                if(StringUtils.isEmpty(payWay) ){
                    throw new Exception("请选择支付类型！");
                }
                if(payWay.contains(PayConstants.QMPAY_TYPE_WX )) {//微信支付
                    url = PayConstants.QMPAY_CLOSE_URL_WX;
                }else if (payWay.contains(PayConstants.QMPAY_TYPE_ALIPAY )){//支付宝
                    url = PayConstants.QMPAY_CLOSE_URL;
                }else if (payWay.contains(PayConstants.QMPAY_TYPE_ALIPAY2APPLET )){//支付宝跳小程序
                    url = PayConstants.QMPAY_CLOSE_URL_ALIPAY2APPLET;
                }else{
                    url = PayConstants.QMPAY_CLOSE_URL;
                }
                break;
            default :
                break;
        }
        if(StringUtils.isEmpty(url)){
            throw new Exception("请选择支付类型！");
        }
        return url;
    }

}
