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

import com.alibaba.fastjson.JSONObject;
import com.tzy.common.utils.DateUtils;
import com.tzy.framework.pay.config.PayConfig;
import com.tzy.framework.pay.config.QmH5PayConfig;
import com.tzy.framework.pay.config.QmPayConfig;
import com.tzy.framework.pay.dto.*;
import com.tzy.framework.pay.service.QmH5PayService;
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.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.IOException;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Slf4j
@Service
public class QmH5PayServiceImpl implements QmH5PayService {

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


    @Override
    public ResultMap tradeCreate(PaymentRequestDto paymentRequestDto) {
        ResultMap resultMap = new ResultMap();
        try {
            QmH5PayConfig qmPayConfig = (QmH5PayConfig) payConfig.getByPayType(paymentRequestDto.getPayWay());
            if(null == qmPayConfig){
                qmPayConfig = this.qmH5PayConfig;
            }
//            String url = getBoxUrl(paymentRequestDto.getPayWay(),PayConstants.QMPAY_METHOD_TRADE_CREATE);
//            if(appversion.equals("prod")){
                String url = getUrl(paymentRequestDto.getPayWay(),PayConstants.QMPAY_METHOD_TRADE_CREATE);
//            }
            String merchantOrderId = getMerchantOrderId(qmPayConfig);
            JSONObject json = new JSONObject();
//            json.put("requestTimestamp", DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS,new Date()));    // 报文请求时间
            json.put("requestTimestamp", DateFormatUtils.format(paymentRequestDto.getExpireTime(), "yyyy-MM-dd HH:mm:ss"));    // 报文请求时间
            json.put("merOrderId", merchantOrderId); // 商户订单号
            json.put("mid", qmPayConfig.getMid_ali()); // 商户号
            json.put("tid", qmPayConfig.getTid());    // 终端号
            json.put("instMid", qmPayConfig.getInstMid()); // 业务类型
            json.put("totalAmount", paymentRequestDto.getTotalAmount().multiply(new BigDecimal(100)).intValue());
            json.put("notifyUrl", qmPayConfig.getPayNotifyUrl()); // 支付地址
            /**云闪付*/
            if(paymentRequestDto.getPayWay().equals(PayConstants.QMPAY_TYPE_UAC2H5)){
                json.put("cardNoLockFlag", true); // 卡号锁定标识
            }
            /* 分账部分 */
//        json.put("divisionFlag", true); // 分账标记
//        json.put("platformAmount", 10); // 平台商户分账金额
//        ArrayList subOrders = new ArrayList<>();
//        JSONObject jsonObject = new JSONObject();
//        jsonObject.put("mid", "子商户号");
//        jsonObject.put("totalAmount", 10);
//        subOrders.add(jsonObject);
//        json.put("subOrders", subOrders);
            log.info("请求报文:{}" + json);
            String param = getOpenBodySigForNetpay(qmPayConfig.getAppid(), qmPayConfig.getAppkey(), new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()), qmPayConfig.getPayFlag(), json.toString());
            url = url +"?"+ param;
            JSONObject data = new JSONObject();
            data.put("url",url);
            log.info(" 全民h5下单链接：{} ",data);
            return resultMap
                    .put("data",data)
                    ;
        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public PaymentInfoResponseDto queryOrder(String appid, String payWay, String orderNo) {
        PaymentInfoResponseDto paymentInfoResponseDto = new PaymentInfoResponseDto();
        String errMsg = "";
        try{
            QmH5PayConfig qmPayConfig = (QmH5PayConfig) payConfig.getByPayType(payWay);
            if(null == qmPayConfig){
                qmPayConfig = this.qmH5PayConfig;
            }
//            String url = getBoxUrl(payWay, PayConstants.QMPAY_METHOD_QUERY_ORDER);
//            if("prod".equals(appversion)){
               String 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_ali()); // 商户号
            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);
            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.setSuccess(true);
                        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")));
                        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);
    }

    @Override
    public ResultMap refund(String appid, String payWay, String orderNo, BigDecimal refundPrice, String refundMsg) {
        String errMsg = "";
        try{
            QmH5PayConfig qmPayConfig = (QmH5PayConfig) payConfig.getByPayType(payWay);
            if(null == qmPayConfig){
                qmPayConfig = this.qmH5PayConfig;
            }
            String refundOrderId = getMerchantOrderId(qmPayConfig);
//            String url = getBoxUrl(null,PayConstants.QMPAY_METHOD_REFUND);
//            if("prod".equals(appversion)){
               String 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_ali()); // 商户号
            json.put("tid", qmPayConfig.getTid());    // 终端号
            json.put("instMid", qmPayConfig.getInstMid()); // 业务类型
            json.put("refundAmount", refundPrice.multiply(new BigDecimal(100)).intValue()); // 退款金额
            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);
            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);
    }

    @Override
    public ResultMap refundQuery(String appid,String payWay,  String outRefundNo) {
        String errMsg = "";
        try{
            QmH5PayConfig qmPayConfig = (QmH5PayConfig) payConfig.getByPayType(payWay);
            if(null == qmPayConfig){
                qmPayConfig = this.qmH5PayConfig;
            }
//            String url = getBoxUrl(null,PayConstants.QMPAY_METHOD_REFUND);
//            if("prod".equals(appversion)){
               String 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", outRefundNo); // 商户订单号
            json.put("mid", qmPayConfig.getMid_ali()); // 商户号
            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);
            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);
    }

    @Override
    public ResultMap colse(String appid, String payWay, String orderNo) {
        String errMsg = "";
        try{
            QmH5PayConfig qmPayConfig = (QmH5PayConfig) payConfig.getByPayType(appid);
            if(null == qmPayConfig){
                qmPayConfig = this.qmH5PayConfig;
            }
//            String url = getBoxUrl(payWay,PayConstants.QMPAY_METHOD_CLOSE);
//            if("prod".equals(appversion)){
               String 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_ali()); // 商户号
            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);
            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);
    }
    public  String getMerchantOrderId(){
        return qmH5PayConfig.getMsgSrcId()+ DateUtils.parseDateToStr("yyyyMMddmmHHssSSS",new Date())+ RandomUtil.random(7);
    }
    public  String getMerchantOrderId(QmH5PayConfig qmPayConfig){
        return qmPayConfig.getMsgSrcId()+ DateUtils.parseDateToStr("yyyyMMddmmHHssSSS",new Date())+ RandomUtil.random(7);
    }
    private static String getOpenBodySigForNetpay(String appId, String appKey, String timestamp, String nonce, String content) throws IOException, NoSuchAlgorithmException, InvalidKeyException {
//        String bodyDigest = DigestUtils.sha256Hex(URLDecoder.decode(content, "UTF-8")); //eg:cc18f43baa87fe658146221d3f16e3b5a50d30f0c984407f74913ef6dcda8ee1
        String bodyDigest = DigestUtils.sha256Hex(new ByteArrayInputStream(content.getBytes("utf-8")));
        String str1_C = appId + timestamp + nonce + bodyDigest;
        byte[] localSignature = hmacSHA256(str1_C.getBytes(), appKey.getBytes());
        String signature = Base64.encodeBase64String(localSignature);
        System.out.println(signature);
        return ("authorization=OPEN-FORM-PARAM" + "&appId=" + appId + "&timestamp=" + timestamp + "&nonce=" + nonce + "&content=" + URLEncoder.encode(content, "UTF-8") + "&signature=" + URLEncoder.encode(signature, "UTF-8"));
//        return ( "appId=" + appId + "&timestamp=" + timestamp + "&nonce=" + nonce + "&content=" + URLEncoder.encode(content, "UTF-8") + "&signature=" + URLEncoder.encode(signature, "UTF-8"));
    }

    /**
     * @param data
     * @param key
     * @return
     * @throws NoSuchAlgorithmException
     * @throws InvalidKeyException
     * @Description
     */
    private 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);
    }

    public String getBoxUrl(String payWay,String method) throws Exception {
        return qmPayService.getBoxUrl(payWay,method);
    }

    public String getUrl(String payWay, String method) throws Exception {
        return qmPayService.getUrl(payWay,method);
    }
    public String getUrlNew(String payWay, QmPayConfig qmPayConfig, String method) throws Exception {
        return qmPayService.getUrlNew(payWay,qmPayConfig,method);
    }
    public String getOpenBodySig(String appId, String appKey, String body){
        return qmPayService.getOpenBodySig(appId, appKey, body);
    }

    public  String send(String url, String entity , String authorization) throws Exception{
        return qmPayService.send(url, entity, authorization);
    }

    /**********************新逻辑***********************/
    @Override
    public ResultMap tradeCreateNew(PaymentRequestDto paymentRequestDto) {
        ResultMap resultMap = new ResultMap();
        try {
            QmH5PayConfig qmPayConfig = (QmH5PayConfig) paymentRequestDto.getPayConfigByClass(QmH5PayConfig.class);
//            QmH5PayConfig qmPayConfig = (QmH5PayConfig) payConfig.getByPayType(paymentRequestDto.getPayWay());
//            if(null == qmPayConfig){
//                qmPayConfig = this.qmH5PayConfig;
//            }
//            String url = getBoxUrl(paymentRequestDto.getPayWay(),PayConstants.QMPAY_METHOD_TRADE_CREATE);
//            if(appversion.equals("prod")){
            String url = getUrlNew(paymentRequestDto.getPayWay(),new QmPayConfig(qmPayConfig.getAppid(),qmPayConfig.getAppkey(),qmPayConfig.getPrivateKey(),qmPayConfig.getInstMid()),PayConstants.QMPAY_METHOD_TRADE_CREATE);
//            }
            String merchantOrderId = getMerchantOrderId(qmPayConfig);
            JSONObject json = new JSONObject();
//            json.put("requestTimestamp", DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS,new Date()));    // 报文请求时间
            json.put("requestTimestamp", DateFormatUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss"));    // 报文请求时间
            json.put("merOrderId", merchantOrderId); // 商户订单号
            json.put("mid", qmPayConfig.getMid()); // 商户号
            json.put("tid", qmPayConfig.getTid());    // 终端号
            json.put("instMid", qmPayConfig.getInstMid()); // 业务类型
            json.put("totalAmount", paymentRequestDto.getTotalAmount().multiply(new BigDecimal(100)).intValue());
            json.put("notifyUrl", qmPayConfig.getPayNotifyUrl()); // 支付地址
            json.put("returnUrl", paymentRequestDto.getReturnUrl()); // 支付返回商家页面地址
            json.put("attachedData", paymentRequestDto.getPayWay()); // 备注
            json.put("expireTime", DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS,paymentRequestDto.getExpireTime()));  // 订单过期时间
            /**云闪付*/
            if(paymentRequestDto.getPayWay().contains(PayConstants.QMPAY_TYPE_UAC2H5)){
                json.put("cardNoLockFlag", true); // 卡号锁定标识
            }
            /* 分账部分 */
//        json.put("divisionFlag", true); // 分账标记
//        json.put("platformAmount", 10); // 平台商户分账金额
//        ArrayList subOrders = new ArrayList<>();
//        JSONObject jsonObject = new JSONObject();
//        jsonObject.put("mid", "子商户号");
//        jsonObject.put("totalAmount", 10);
//        subOrders.add(jsonObject);
//        json.put("subOrders", subOrders);
            log.info("请求报文:{}" + json);
            String param = getOpenBodySigForNetpay(qmPayConfig.getAppid(), qmPayConfig.getAppkey(), new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()), qmPayConfig.getPayFlag(), json.toString());
            url = url +"?"+ param;
            JSONObject data = new JSONObject();
            data.put("url",url);
            log.info(" 全民h5下单链接：{} ",data);
            return resultMap
                    .put("merOrderId",merchantOrderId)
                    .put("orderNo",paymentRequestDto.getOrderNo())
                    .put("data",data)
                    ;
        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public PaymentInfoResponseDto queryOrder(PaymentRequestDto paymentRequestDto) {
        PaymentInfoResponseDto paymentInfoResponseDto = new PaymentInfoResponseDto();
        String errMsg = "";
        try{
            String payWay = paymentRequestDto.getPayWay();
            String orderNo = paymentRequestDto.getOrderNo();
            QmH5PayConfig qmPayConfig = (QmH5PayConfig) paymentRequestDto.getPayConfigByClass(QmH5PayConfig.class);
            /*if(null == qmPayConfig){
                qmPayConfig = this.qmH5PayConfig;
            }*/
//            String url = getBoxUrl(payWay, PayConstants.QMPAY_METHOD_QUERY_ORDER);
//            if("prod".equals(appversion)){
            String url = getUrlNew(paymentRequestDto.getPayWay(),new QmPayConfig(qmPayConfig.getAppid(),qmPayConfig.getAppkey(),qmPayConfig.getPrivateKey(),qmPayConfig.getInstMid()),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);
            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_DOWN));
                        paymentInfoResponseDto.setActualPayment(new BigDecimal(retJson.getString("totalAmount")).divide(new BigDecimal(100)).setScale(2, BigDecimal.ROUND_DOWN));
                        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_DOWN));
                        }
                        paymentInfoResponseDto.setPaymentSuccessTime(DateUtils.dateTime(DateUtils.YYYY_MM_DD_HH_MM_SS, retJson.getString("payTime")));
                        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);
    }

    @Override
    public ResultMap refund(RefundRequestDto refundRequestDto) {
        String errMsg = "";
        try{
            QmH5PayConfig qmPayConfig = (QmH5PayConfig) refundRequestDto.getPayConfigByClass(QmH5PayConfig.class);
            String orderNo = refundRequestDto.getOrderNo();
            String refundMsg = refundRequestDto.getRefundMsg();
            BigDecimal refundPrice = refundRequestDto.getRefundAmount();
/*
            QmH5PayConfig qmPayConfig = (QmH5PayConfig) payConfig.getByPayType(payWay);
            if(null == qmPayConfig){
                qmPayConfig = this.qmH5PayConfig;
            }
*/
            String refundOrderId = getMerchantOrderId(qmPayConfig);
//            String url = getBoxUrl(null,PayConstants.QMPAY_METHOD_REFUND);
//            if("prod".equals(appversion)){
            String url = getUrlNew(null,new QmPayConfig(qmPayConfig.getAppid(),qmPayConfig.getAppkey(),qmPayConfig.getPrivateKey(),qmPayConfig.getInstMid()),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());    // 终端号
            json.put("instMid", qmPayConfig.getInstMid()); // 业务类型
            json.put("refundAmount", refundPrice.multiply(new BigDecimal(100)).intValue()); // 退款金额
            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);
            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("totalAmount")))));
                        }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{
            QmH5PayConfig qmPayConfig = (QmH5PayConfig) refundRequestDto.getPayConfigByClass(QmH5PayConfig.class);
            String outRefundNo = refundRequestDto.getRefundNo();
//            QmH5PayConfig qmPayConfig = (QmH5PayConfig) payConfig.getByPayType(payWay);
//            if(null == qmPayConfig){
//                qmPayConfig = this.qmH5PayConfig;
//            }
//            String url = getBoxUrl(null,PayConstants.QMPAY_METHOD_REFUND);
//            if("prod".equals(appversion)){
            String url = getUrlNew(null,new QmPayConfig(qmPayConfig.getAppid(),qmPayConfig.getAppkey(),qmPayConfig.getPrivateKey(),qmPayConfig.getInstMid()),PayConstants.QMPAY_METHOD_REFUND);
//            }
            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);
            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);
    }
}
