All Downloads are FREE. Search and download functionalities are using the official Maven repository.

cn.hnhtxx.sdk.HnhtxxOpenSdk Maven / Gradle / Ivy

The newest version!
package cn.hnhtxx.sdk;

import cn.hnhtxx.exception.BusinessException;
import cn.hnhtxx.platform.open.enums.EncryptCodeEnum;
import cn.hnhtxx.platform.open.enums.SignTypeEnum;
import cn.hnhtxx.platform.open.enums.ZipCodeEnum;
import cn.hnhtxx.platform.open.module.request.OpenApiRequestParam;
import cn.hnhtxx.sdk.pojo.query.GetTokenQuery;
import cn.hnhtxx.sdk.pojo.query.Outer;
import cn.hnhtxx.sdk.pojo.query.SdkQuery;
import cn.hnhtxx.sdk.util.*;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;

import java.util.HashMap;
import java.util.Map;

/**
 * @author huangshuo
 * @date 2023-10-18 16:01
 */
public class HnhtxxOpenSdk {

    /**
     * 默认授权类型
     */
    private String defaultGrantType = "client_credentials";

    private static final HnhtxxOpenSdk INSTANCE = new HnhtxxOpenSdk();

    public static final HnhtxxOpenSdk getInstance() {
        return INSTANCE;
    }

    private HnhtxxOpenSdk() {
    }

    /**
     * 请求云税的api接口(默认base64加密)
     *
     * @param url           接口地址
     * @param identity      identity/appId 用户的唯一标志
     * @param interfacetype 接口名/接口编码 例:kpcx、ORDER.ORDERIMPORT
     * @param token         是否需要传token请参考文档
     * @param content       接口私有入参
     * @param timeout       连接超时时间
     * @return
     */
    public String sendPostSyncRequest(String url, String identity, String interfacetype, String token,
                                      String content, int... timeout) {
        verify(url, "请求地址URL不能为空");
        verify(identity, "identity不能为空");
        verify(interfacetype, "interfacetype不能为空");
        verify(content, "content不能为空");

        SdkQuery sdkQuery = new SdkQuery();
        sdkQuery.setToken(token);
        sdkQuery.setUrl(url);
        sdkQuery.setIdentity(identity);
        sdkQuery.setInterfacetype(interfacetype);
        sdkQuery.setContent(content);

        return sendPostSyncRequest(sdkQuery, timeout);
    }

    /**
     * 请求云税的api接口(自定义加密方式)
     *
     * @param sdkQuery 入参
     * @param timeout  连接超时时间
     * @return
     */
    public String sendPostSyncRequest(SdkQuery sdkQuery, int... timeout) {
        String url = sdkQuery.getUrl();
        String identity = sdkQuery.getIdentity();
        String interfacetype = sdkQuery.getInterfacetype();
        String content = sdkQuery.getContent();

        verify(url, "请求地址URL不能为空");
        verify(identity, "identity不能为空");
        verify(interfacetype, "interfacetype不能为空");
        verify(content, "content不能为空");

        //默认base64加密
        if (StrUtil.isBlank(sdkQuery.getEncryptCode())) {
            sdkQuery.setEncryptCode(EncryptCodeEnum.BASE64.getCode());
        }

        //销项接口和开放平台接口的参数格式不一样
        boolean isOpenPlatform = false;
        if (interfacetype.indexOf(".") > -1) {
            isOpenPlatform = true;
        }

        try {
            //根据接口名,组装报文
            if (isOpenPlatform) {
                content = getOpenPlatformParam(sdkQuery);
            } else {
                content = getApiInvoiceParam(sdkQuery);
            }
        } catch (Exception e) {
            throw new BusinessException("组装参数异常", e);
        }

        Map header = buildHeader(sdkQuery);
        try {
            String result = ModuleHttp.sendSyncHttp(url, header, content, timeout);
            //解密
            result = decryptedResult(sdkQuery, isOpenPlatform, result);

            return result;
        } catch (Exception e) {
            throw new BusinessException("接口调用异常", e);
        }
    }

    /**
     * @param appId     请求者id(平台提供 AppID)
     * @param appSecret 请求者密码(密钥)
     * @return
     */
    public String getToken(String url, String appId, String appSecret, int... timeout) {
        Map header = buildHeader(null);

        GetTokenQuery getTokenQuery = new GetTokenQuery();
        getTokenQuery.setClient_id(appId);
        getTokenQuery.setClient_secret(appSecret);
        getTokenQuery.setGrant_type(defaultGrantType);
        try {
            String result = ModuleHttp.sendSyncHttp(url, header, JSONObject.toJSONString(getTokenQuery), timeout);
            return result;
        } catch (Exception e) {
            throw new BusinessException("接口调用异常", e);
        }
    }

    private void verify(String v, String msg) {
        if (v == null || v.trim().length() == 0 || v.toLowerCase().trim().equals("null")) {
            throw new BusinessException(msg);
        }
    }

    private Map buildHeader(SdkQuery sdkQuery) {
        Map header = new HashMap<>(1);
        header.put("Content-Type", "application/json");
        if (sdkQuery != null && StrUtil.isNotBlank(sdkQuery.getToken())) {
            header.put("Authorization", sdkQuery.getToken());
        }
        return header;
    }

    /**
     * 生成api接口的入参
     *
     * @param sdkQuery
     * @return
     */
    private String getApiInvoiceParam(SdkQuery sdkQuery) throws Exception {
        Outer outer = new Outer();
        Outer.Order order = new Outer.Order();
        outer.setOrder(order);

        BeanUtil.copyProperties(sdkQuery, order);

        //入参加密
        order.setContent(encryptedData(sdkQuery));

        //生成签名
        if (SignTypeEnum.HMAC_SHA256.getCode().equals(sdkQuery.getSignType())) {
            sdkQuery.setContent(order.getContent());
            order.setSignature(SignatureUtils.getSignature(sdkQuery));
        }

        return JSONObject.toJSONString(outer);
    }

    /**
     * 生成开放平台接口的入参
     *
     * @param sdkQuery
     * @return
     */
    private String getOpenPlatformParam(SdkQuery sdkQuery) throws Exception {
        verify(sdkQuery.getToken(), "token不能为空");

        OpenApiRequestParam openApiRequestParam = new OpenApiRequestParam();
        openApiRequestParam.setAppId(sdkQuery.getIdentity());
        openApiRequestParam.setInterfaceCode(sdkQuery.getInterfacetype());
        openApiRequestParam.setEncryptCode(sdkQuery.getEncryptCode());
        openApiRequestParam.setZipCode(sdkQuery.getZipCode());
        openApiRequestParam.setSignType(sdkQuery.getSignType());
        openApiRequestParam.setSignature(sdkQuery.getSignature());

        //入参加密
        openApiRequestParam.setData(encryptedData(sdkQuery));

        //生成签名
        if (SignTypeEnum.HMAC_SHA256.getCode().equals(sdkQuery.getSignType())) {
            sdkQuery.setContent(openApiRequestParam.getData());
            openApiRequestParam.setSignature(SignatureUtils.getSignature(sdkQuery));
        }

        return JSONObject.toJSONString(openApiRequestParam);
    }

    /**
     * 数据加密
     *
     * @param sdkQuery
     * @throws Exception
     */
    private String encryptedData(SdkQuery sdkQuery) throws Exception {
        String data = sdkQuery.getContent();

        //AES解密,对称密钥算法
        if (EncryptCodeEnum.AES.getCode().equals(sdkQuery.getEncryptCode())) {
            verify(sdkQuery.getSecretKey(), "使用AES加密时,密钥(平台提供)不能为空");
            data = AESUtil.encrypt(data, sdkQuery.getSecretKey());
        }

        //Gzip解压缩
        if (ZipCodeEnum.GZIP.getCode().equals(sdkQuery.getZipCode())) {
            data = GZIPUtils.compress(data);
        }

        //base64解码
        data = Base64Utils.encodeUtf8(data);

        return data;
    }

    /**
     * 数据解密
     *
     * @param sdkQuery
     * @return
     * @throws Exception
     */
    public String decryptedData(SdkQuery sdkQuery) throws Exception {
        String data = sdkQuery.getContent();

        //base64解码
        data = Base64Utils.decodeUtf8(data);

        //Gzip解压缩
        if (ZipCodeEnum.GZIP.getCode().equals(sdkQuery.getZipCode())) {
            data = GZIPUtils.uncompress(data);
        }

        //AES解密,对称密钥算法
        if (EncryptCodeEnum.AES.getCode().equals(sdkQuery.getEncryptCode())) {
            data = AESUtil.decrypt(data, sdkQuery.getSecretKey());
        }

        return data;
    }

    private String decryptedResult(SdkQuery sdkQuery, Boolean isOpenPlatform, String result) throws Exception {
        if (isOpenPlatform) {
            return result;
        }

        sdkQuery.setContent(result);
        return decryptedData(sdkQuery);
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy