package com.jeequan.jeepay.thirdparty.channel.lklspay;

import cn.com.sand.hmpay.util.StringUtil;
import cn.hutool.core.codec.Base64;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.img.ImgUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.crypto.PemUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.asymmetric.KeyType;
import cn.hutool.crypto.asymmetric.RSA;
import cn.hutool.crypto.asymmetric.Sign;
import cn.hutool.crypto.asymmetric.SignAlgorithm;
import cn.hutool.http.ContentType;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.jeequan.jeepay.core.entity.MchApplyment;
import com.jeequan.jeepay.core.exception.BizException;
import com.jeequan.jeepay.core.model.context.MchAppConfigContext;
import com.jeequan.jeepay.core.model.params.lklspay.LklspayIsvParams;
import com.jeequan.jeepay.core.model.params.lklspay.LklspayIsvsubMchParams;
import com.jeequan.jeepay.core.utils.SpringBeansUtil;
import com.jeequan.jeepay.thirdparty.channel.lklpay.utils.LklpayConst;
import com.jeequan.jeepay.thirdparty.channel.lklspay.model.*;
import com.jeequan.jeepay.thirdparty.channel.lklspay.util.LklspayConst;
import com.jeequan.jeepay.thirdparty.service.ConfigContextQueryService;
import com.jeequan.jeepay.thirdparty.util.ChannelCertConfigKitBean;
import lombok.AccessLevel;
import lombok.Cleanup;
import lombok.NoArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
import org.springframework.web.client.HttpStatusCodeException;

import javax.xml.bind.DatatypeConverter;
import java.awt.*;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.security.cert.Certificate;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

import static org.springframework.http.HttpStatus.BAD_REQUEST;
import static org.springframework.http.HttpStatus.PRECONDITION_FAILED;

/**
 * TODO
 *
 * @author crystal
 * @date 2023/11/22 15:49
 */
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class LklspayKit {

    public static final Logger log = LoggerFactory.getLogger(LklspayKit.class);

    public static final String RESP_APPID_HEADER = "Lklapi-Appid";

    public static final String RESP_SERIAL_HEADER = "Lklapi-Serial";

    public static final String RESP_TIMESTAMP_HEADER = "Lklapi-Timestamp";

    public static final String RESP_NONCE_HEADER = "Lklapi-Nonce";

    public static final String RESP_SIGNATURE_HEADER = "Lklapi-Signature";

    public static final String SCHEMA = "LKLAPI-SHA256withRSA";

    public static final String SUCCESS_CODE = "000000";

    public static final String EXT_SUCCESS_CODE = "BBS00000";

    public static final String PAYING_SUCCESS_CODE = "BBS10000";

    private static JSONObject token;

    private static JSONObject editToken;

    public static JSONObject uploadRequest(LklspayIsvParams isvParams, String fileUrl, String imgType) {
        reqAuditToken(isvParams);

        log.info("拉卡拉上传图片, 上传图片类型为{}, 上传图片链接为{}", imgType, fileUrl);
        HttpRequest httpRequest = HttpRequest.post(LklTkReqMethod.UPLOAD.getUrl())
                .contentType(ContentType.MULTIPART.name())
                .header("Authorization", "bearer " + token.getString("access_token"));

        byte[] byteArray = HttpUtil.downloadBytes(fileUrl);
        Image read = ImgUtil.toImage(byteArray);

        while (byteArray.length > 1024 * 1024) {
            read = ImgUtil.scale(read, 0.9f);
            byteArray = ImgUtil.toBytes(read, "jpg");
        }
//        ByteArrayResource file = new ByteArrayResource(byteArray) {
//            @Override
//            public String getFilename() {
//                return "test.jpg";
//            }
//        };

        httpRequest.form("file", byteArray, "test.jpg");
        httpRequest.form("imgType", imgType);
        httpRequest.form("sourcechnl", "0");
        httpRequest.form("isOcr", false);

        HttpResponse execute = null;
        try {
            execute = httpRequest.execute();
            if (execute.isOk()) {
                return JSON.parseObject(execute.body());
            } else {
                log.info("拉卡拉上传图片异常, 上传图片类型为{}, 上传图片链接为{}", imgType, fileUrl);
                throw new BizException("拉卡拉上传图片异常");
            }

        } catch (HttpStatusCodeException e) {
            token = null;
            throw e;
        } finally {
            if (execute != null) {
                execute.close();
            }
        }
    }

    public static JSONObject uploadRequest(LklspayIsvParams isvParams, File file, String imgType) {
        reqAuditToken(isvParams);

        HttpRequest httpRequest = HttpRequest.post(LklTkReqMethod.UPLOAD.getUrl())
                .contentType(ContentType.MULTIPART.name())
                .header("Authorization", "bearer " + token.getString("access_token"));

        httpRequest.form("file", file);
        httpRequest.form("imgType", imgType);
        httpRequest.form("sourcechnl", "0");
        httpRequest.form("isOcr", false);

        HttpResponse execute = null;
        try {
            execute = httpRequest.execute();
            if (execute.isOk()) {
                return JSON.parseObject(execute.body());
            } else {
                log.info("拉卡拉上传图片异常, 上传图片类型为｛｝", imgType);
                throw new BizException("拉卡拉上传图片异常");
            }

        } catch (HttpStatusCodeException e) {
            token = null;
            throw e;
        } finally {
            if (execute != null) {
                execute.close();
            }
        }
    }

    private static void reqAuditToken(LklspayIsvParams isvParams) {
        token = getToken(isvParams);
    }

    /**
     * 获取入网token
     *
     * @return
     */
    private static JSONObject getToken(LklspayIsvParams isvParams) {
        String clientInfo = isvParams.getClientId() + ":" + isvParams.getClientSecret();
        String encodeClientInfo = Base64.encode(clientInfo);

        try {
            @Cleanup HttpResponse execute = HttpRequest.post(LklTkReqMethod.TOKEN_AUDIT.getUrl())
                    .header("Authorization", "Basic " + encodeClientInfo)
                    .form("grant_type", "client_credentials")
                    .form("client_id", isvParams.getClientId())
                    .form("client_secret", isvParams.getClientSecret())
                    .execute();
            log.info("请求结果: {}", execute.body());
            JSONObject token = JSON.parseObject(execute.body());
            if (!execute.isOk()) {
                throw new BizException(execute.body());
            }
            token.put("expire_in", token.getIntValue("expire_in") + System.currentTimeMillis() / 1000L);
            return token;
        } catch (Exception e) {
            log.info("token获取失败", e);
            throw new BizException("token获取失败");
        }
    }

    private static void reqAuditEditToken(LklspayIsvParams isvParams) {
        editToken = getEditToken(isvParams);
    }

    private static JSONObject getEditToken(LklspayIsvParams isvParams) {
        String clientInfo = isvParams.getClientId() + ":" + isvParams.getClientSecret();
        String encodeClientInfo = Base64.encode(clientInfo);

        try {
            @Cleanup HttpResponse execute = HttpRequest.post(LklTkReqMethod.TOKEN_EDIT.getUrl())
                    .header("Authorization", "Basic " + encodeClientInfo)
                    .form("grant_type", "password")
                    .form("username", isvParams.getAppUserName())
                    .form("password", isvParams.getAppPassword())
                    .form("scope", "all")
                    .execute();
            log.info("请求结果: {}", execute.body());
            JSONObject token = JSON.parseObject(execute.body());
            if (!execute.isOk()) {
                throw new BizException(execute.body());
            }
            token.put("expire_in", token.getIntValue("expire_in") + System.currentTimeMillis() / 1000L);
            return token;
        } catch (Exception e) {
            log.info("token获取失败", e);
            throw new BizException("token获取失败");
        }
    }

    public static JSONObject applymentRequest(ILklTkReqMethod reqMethod, LklspayIsvParams isvParams, JSONObject param) {
        ConfigContextQueryService configContextQueryService = SpringBeansUtil.getBean(ConfigContextQueryService.class);
        Assert.notNull(configContextQueryService, "无法获取拉卡拉配置信息");

        log.info("LklspayIsvParams：{}", JSONUtil.toJsonStr(isvParams));

        if (reqMethod.getUrlFlag().equals(LklspayConst.AUDIT)) {
            reqAuditToken(isvParams);
        } else {
            reqAuditEditToken(isvParams);
        }

        String url = reqMethod.getUrl();
        String templateWord = reqMethod.getTemplateWord();
        if (!ObjectUtils.isEmpty(templateWord)) {
            String paramWord = param.getString(templateWord.replaceAll("[{}]", ""));
            url = url.replace(templateWord, paramWord);
        }

        log.info("拉卡拉请求链接: {}", url);
        log.info("拉卡拉请求参数: {}", param);

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(reqMethod.getContentType());
        if (reqMethod.getUrlFlag().equals(LklspayConst.AUDIT)) {
            headers.add("Authorization", "bearer " + token.getString("access_token"));
        } else {
            headers.add("Authorization", "bearer " + editToken.getString("access_token"));
        }
        log.info("拉卡拉请求头：{}", JSON.toJSONString(headers));

        if (reqMethod.getContentType().equals(MediaType.APPLICATION_FORM_URLENCODED)) {

            HttpResponse execute = null;
            if (reqMethod.getMethod().equals(LklpayConst.POST)) {
                try {
                    HttpRequest httpRequest = HttpRequest.post(url);
                    if (reqMethod.getUrlFlag().equals(LklspayConst.AUDIT)) {
                        httpRequest.header("Authorization", "bearer " + token.getString("access_token"));
                    } else {
                        httpRequest.header("Authorization", "bearer " + editToken.getString("access_token"));
                    }

                    for (Map.Entry<String, Object> entry : param.entrySet()) {
                        httpRequest.form(entry.getKey(), entry.getValue());
                    }

                    execute = httpRequest.execute();
                    String body = execute.body();
                    if (execute.isOk()) {
                        log.info("拉卡拉请求返回结果：{}", body);
                        return JSON.parseObject(body);
                    } else {
                        log.info("拉卡拉请求返回结果：{}", body);
                        throw new BizException(body);
                    }

                } catch (HttpStatusCodeException e) {
                    token = null;
                    handleHttpStatusCodeException(e);
                } catch (Exception e) {
                    log.info("拉卡拉请求异常", e);
                    throw new BizException("拉卡拉请求异常");
                } finally {
                    if (execute != null) {
                        execute.close();
                    }
                }
            }

            if (reqMethod.getMethod().equals(LklspayConst.GET)) {
                try {
                    url += "?";

                    HttpRequest httpRequest = HttpRequest.get(url);

                    if (reqMethod.getUrlFlag().equals(LklspayConst.AUDIT)) {
                        httpRequest.header("Authorization", "bearer " + token.getString("access_token"));
                    } else {
                        httpRequest.header("Authorization", "bearer " + editToken.getString("access_token"));
                    }

                    for (Map.Entry<String, Object> entry : param.entrySet()) {
                        httpRequest.form(entry.getKey(), entry.getValue());
                    }
                    execute = httpRequest.execute();
                    String body = execute.body();
                    if (execute.isOk()) {
                        log.info("拉卡拉请求返回结果：{}", body);
                        return JSON.parseObject(body);
                    } else {
                        log.info("拉卡拉请求返回结果：{}", body);
                        throw new BizException(body);
                    }
                } catch (HttpStatusCodeException e) {
                    token = null;
                    handleHttpStatusCodeException(e);
                } catch (Exception e) {
                    log.info("拉卡拉请求异常", e);
                    throw new BizException("拉卡拉请求异常");
                } finally {
                    if (execute != null) {
                        execute.close();
                    }
                }
            }
        }

        if (MediaType.APPLICATION_JSON.equals(reqMethod.getContentType())) {
            RSA rsa = null;
            HttpRequest post = HttpRequest.post(url).header(headers);
            if (reqMethod.isEncrypt()) {
                rsa = SecureUtil.rsa(LklTkReqMethod.PRI_KEY, LklTkReqMethod.PUB_KEY);
                String encryptBase64 = rsa.encryptBase64(param.toJSONString(), KeyType.PrivateKey);
                JSONObject reqParam = new JSONObject();
                reqParam.put("data", encryptBase64);
                post.body(reqParam.toJSONString());
            } else {
                post.body(param.toJSONString());
            }

            try {
                @Cleanup HttpResponse execute = post.execute();
                String body = execute.body();
                if (execute.isOk()) {
                    log.info("拉卡拉请求返回结果：{}", body);

                    JSONObject respData = JSON.parseObject(body);
                    String encryptData = respData.getString("data");
                    if (reqMethod.isEncrypt()) {
                        String encryptRespData = rsa.decryptStr(encryptData, KeyType.PublicKey);
                        log.info("拉卡拉请求返回结果解密：{}", encryptRespData);

                        return JSON.parseObject(encryptRespData);
                    }

                    return JSON.parseObject(body);
                } else {
                    log.info("拉卡拉请求返回结果：{}", body);

                    if (execute.getStatus() == 400 || execute.getStatus() == 412 || execute.getStatus() == 500) {
                        throw new BizException(JSON.parseObject(body).getString("message"));
                    }

                    throw new BizException(body);
                }

            } catch (Exception e) {
                log.info("拉卡拉请求异常", e);
                if (e instanceof BizException) {
                    throw e;
                }
                throw new BizException("拉卡拉请求异常, " + e.getMessage());
            }
        }

        throw new BizException("拉卡拉请求异常");
    }

    public static JSONObject openRequest(ILklTkReqMethod method, LklspayIsvParams isvParams, JSONObject params) {
        JSONObject reqParam = new JSONObject();
        reqParam.put("ver", "v1.0.0");
        reqParam.put("timestamp", String.valueOf(System.currentTimeMillis()));
        reqParam.put("rnd", UUID.randomUUID().toString().replace("-", ""));
        reqParam.put("reqId", UUID.randomUUID().toString().replace("-", ""));
        reqParam.put("reqData", params);

        Map<String, String> headers = getAuthorization(isvParams, reqParam.toString());
        try {
            HttpResponse response = HttpRequest.post(method.getUrl()).addHeaders(headers).body(reqParam.toString()).execute();
            log.info("拉卡拉返回参数：{}", response.body());
            checkSign(isvParams, response);
            return JSON.parseObject(response.body()).getJSONObject("respData");
        } catch (HttpStatusCodeException e) {
            handleHttpClientErrorException(e);
            return new JSONObject();
        }
    }

    public static Map<String, String> getAuthorization(LklspayIsvParams isvParams, String body) {
        ConfigContextQueryService configContextQueryService = SpringBeansUtil.getBean(ConfigContextQueryService.class);
        Assert.notNull(configContextQueryService, "无法获取拉卡拉入网配置信息");
        ChannelCertConfigKitBean channelCertConfigKitBean = SpringBeansUtil.getBean(ChannelCertConfigKitBean.class);
        String certFilePath = channelCertConfigKitBean.getCertFilePath(isvParams.getPrivateCert());
        InputStream inputStream = FileUtil.getInputStream(certFilePath);
        String nonceStr = RandomUtil.randomString(16);
        Map<String, String> headers = new HashMap<>(1);
        long timestamp = System.currentTimeMillis() / 1000;
        String data = isvParams.getAppId() + "\n" + isvParams.getSerialNo() + "\n" + timestamp + "\n" + nonceStr + "\n" + body + "\n";
        byte[] privateKey = PemUtil.readPem(inputStream);
        Sign sign = SecureUtil.sign(SignAlgorithm.SHA256withRSA, privateKey, null);
        sign.sign(data);
        String signature = Base64.encode(sign.sign(data));
        try {
            String authorization = "appid=\"" + isvParams.getAppId() + "\"," + "serial_no=\"" + isvParams.getSerialNo() + "\"," + "timestamp=\""
                    + timestamp + "\"," + "nonce_str=\"" + nonceStr + "\"," + "signature=\"" + signature + "\"";
            headers.put("Authorization", SCHEMA + " " + authorization);
            log.info("【拉卡拉】接口请求参数：{}",body);
            return headers;
        } catch (Exception e) {
            throw new BizException("拉卡拉接口授权参数异常");
        } finally {
            try {
                inputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public static boolean checkSign(LklspayIsvParams isvParams, HttpResponse response) {
        String respAppid = response.header(RESP_APPID_HEADER);
        String respSerial = response.header(RESP_SERIAL_HEADER);
        String respTimestamp = response.header(RESP_TIMESTAMP_HEADER);
        String respNonce = response.header(RESP_NONCE_HEADER);
        String repsSignature = response.header(RESP_SIGNATURE_HEADER);
        String source = respAppid + "\n" + respSerial + "\n" + respTimestamp + "\n" + respNonce + "\n" + response.body() + "\n";
        ConfigContextQueryService configContextQueryService = SpringBeansUtil.getBean(ConfigContextQueryService.class);
        Assert.notNull(configContextQueryService, "无法获取拉卡拉入网配置信息");
        ChannelCertConfigKitBean channelCertConfigKitBean = SpringBeansUtil.getBean(ChannelCertConfigKitBean.class);
        String certFilePath = channelCertConfigKitBean.getCertFilePath(isvParams.getPublicCert());
        InputStream inputStream = FileUtil.getInputStream(certFilePath);
        try {
            Certificate certificate = SecureUtil.readX509Certificate(inputStream);
            Sign sign = SecureUtil.sign(SignAlgorithm.SHA256withRSA).setCertificate(certificate);
            return sign.verify(source.getBytes(StandardCharsets.UTF_8), DatatypeConverter.parseBase64Binary(repsSignature));
        } catch (Exception e) {
            return false;
        } finally {
            try {
                inputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 设置通道参数
     *
     * @param mchAppConfigContext
     * @param bizContent
     */
    public static void setPayParams(MchAppConfigContext mchAppConfigContext, JSONObject bizContent, String ip) {
        LklspayIsvsubMchParams mchParams = JSON.parseObject(mchAppConfigContext.getMchApplyment().getSuccResParameter(), LklspayIsvsubMchParams.class);
        bizContent.put("merchant_no", mchParams.getExternalCustomerNo());
        bizContent.put("term_no", mchParams.getTermNo());
        if (StringUtil.isNotEmpty(ip)) {
            JSONObject location_info = new JSONObject(1);
            location_info.put("request_ip", ip);
            bizContent.put("location_info", location_info);
        }
    }

    /**
     * 请求
     *
     * @return
     */
    public static JSONObject payRequest(LklPayMethod.Api method, MchApplyment mchApplyment, JSONObject params) {
        ConfigContextQueryService configContextQueryService = SpringBeansUtil.getBean(ConfigContextQueryService.class);
        LklspayIsvParams isvParams = ((LklspayIsvParams) configContextQueryService.queryIsvParams(mchApplyment));
        JSONObject reqParam = new JSONObject();
        reqParam.put("version", "3.0");
        reqParam.put("req_time", DateUtil.format(new DateTime(), DatePattern.PURE_DATETIME_FORMAT));
        reqParam.put("req_data", params);
        Map<String, String> headers = getAuthorization(isvParams, reqParam.toString());
        try {
            HttpResponse response = HttpRequest.post(method.getUrl()).addHeaders(headers).body(reqParam.toString()).execute();
            log.info("拉卡拉返回参数：{}", response.body());
            JSONObject responseBody = JSON.parseObject(response.body());
            if(!EXT_SUCCESS_CODE.equals(responseBody.getString("code")) && !PAYING_SUCCESS_CODE.equals(responseBody.getString("code"))){
                throw new BizException(responseBody.getString("msg"));
            }
            checkSign(isvParams, response);
            return responseBody.getJSONObject("resp_data");
        } catch (HttpStatusCodeException e) {
            handleHttpClientErrorException(e);
            return new JSONObject();
        }
    }

    public static void handleHttpClientErrorException(HttpStatusCodeException e) {
        log.info("http code exception", e);
        byte[] responseBodyAsByteArray = e.getResponseBodyAsByteArray();
        String resp = new String(responseBodyAsByteArray, StandardCharsets.UTF_8);
        log.info("拉卡拉请求返回结果：{}", resp);
        JSONObject error = JSON.parseObject(resp);
        String errorMsg;
        String msg;
        HttpStatus statusCode = e.getStatusCode();
        if (statusCode.equals(BAD_REQUEST) || statusCode.equals(PRECONDITION_FAILED)) {
            errorMsg = error.getString("message");
            msg = String.format("接口请求异常,请求code:%s, 异常信息:%s", e.getStatusCode(), errorMsg);
            throw new BizException(msg);
        } else {
            errorMsg = StringUtil.isNotEmpty(error.getString("retMsg")) ? error.getString("retMsg") : error.getString("msg");
            msg = String.format("接口请求异常,请求code:%s, 异常信息:%s", e.getStatusCode(), errorMsg);
            throw new BizException(msg);
        }
    }

    public static void handleHttpStatusCodeException(HttpStatusCodeException e) {
        log.info("拉卡拉请求异常返回码", e);
        byte[] responseBodyAsByteArray = e.getResponseBodyAsByteArray();
        String resp = new String(responseBodyAsByteArray, StandardCharsets.UTF_8);
        log.info("拉卡拉请求返回结果：{}", resp);

        JSONObject error = JSON.parseObject(resp);
        String errorMsg;
        String msg;
        switch (e.getStatusCode()) {
            case BAD_REQUEST:
            case PRECONDITION_FAILED:
                // 汇拓客的接口
                errorMsg = error.getString("message");
                msg = String.format("接口请求异常,请求code:%s, 异常信息:%s", e.getStatusCode(), errorMsg);
                throw new BizException(errorMsg);
            default:
                errorMsg = StringUtil.isNotEmpty(error.getString("retMsg")) ? error.getString("retMsg") : error.getString("msg");
                msg = String.format("接口请求异常,请求code:%s, 异常信息:%s", e.getStatusCode(), errorMsg);
                break;
        }

        throw e;
    }

    public static JSONObject ok() {
        JSONObject result = new JSONObject(2);
        result.put("code", "SUCCESS");
        result.put("message", "处理成功");
        return result;
    }

    /**
     * 商户相关参数请求
     *
     * @param method
     * @param bizContent
     * @return
     */
    public static JSONObject reqMch(LklPayMethod.Api method, LklspayIsvParams isvParams, JSONObject bizContent) {
        if (method == LklPayMethod.Api.WECHAT_PARAMS_CONFIG_URL) {
            bizContent.put("channlId", isvParams.getWxChannelId());
        }
        LklMchReq req = new LklMchReq(bizContent);
        return reqApi(method, isvParams, JSON.toJSONString(req));
    }

    public static JSONObject reqApi(LklPayMethod.Api method, LklspayIsvParams isvParams, String reqBody) {
        log.info("【拉卡拉】接口请求地址：{}",method.getUrl());
        Map<String, String> headers = getAuthorization(isvParams, reqBody);
        try {
            HttpResponse response = HttpRequest.post(method.getUrl()).addHeaders(headers).body(reqBody).execute();
            log.info("拉卡拉返回参数：{}", response.body());
            return initResult(isvParams, response);
        } catch (HttpStatusCodeException e) {
            handleHttpClientErrorException(e);
            throw new BizException("接口异常");
        } catch (Exception e) {
            throw new BizException(e.getMessage());
        }
    }

    /**
     * 发起结算信息请求
     *
     * @param method
     * @param bizData
     * @param isvParams
     * @return
     */
    public static JSONObject reqSettle(LklPayMethod.Api method, JSONObject bizData, LklspayIsvParams isvParams) {
        LklSettleReq reqData = new LklSettleReq(bizData);
        return reqApi(method, isvParams, JSON.toJSONString(reqData));
    }

    private static JSONObject initResult(LklspayIsvParams isvParams, HttpResponse response) {
        boolean verify = checkSign(isvParams, response);
        if (!verify) {
            throw new BizException("签名校验异常");
        }
        JSONObject responseBody = JSON.parseObject(response.body());
        String retCode = responseBody.getString("retCode");
        if (!SUCCESS_CODE.equals(retCode)) {
            throw new BizException(responseBody.getString("retMsg"));
        }
        Object respData  = responseBody.get("respData");
        if(respData instanceof JSONObject){
            return (JSONObject) respData;
        }
        return responseBody;
    }
}
