Air
2024-11-04 2016903d06e308f44b9463fcd4029850ababf152
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
package com.nova.sankuai.infra.utils.huifubao.api;
 
import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.nova.sankuai.infra.utils.huifubao.common.HttpUtil;
import com.nova.sankuai.infra.utils.huifubao.common.SignEncrypt;
import com.nova.sankuai.infra.utils.huifubao.common.Utils;
import com.nova.sankuai.infra.utils.huifubao.request.BaseRequest;
import com.nova.sankuai.infra.utils.huifubao.respone.BaseResponse;
import com.nova.sankuai.infra.utils.huifubao.respone.QuerySignRespone;
import com.nova.sankuai.infra.utils.huifubao.respone.SignResponse;
import lombok.Data;
 
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.cert.X509Certificate;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;
 
@Data
public abstract class AbstractHeepayClient implements HeepayClient {
    private String serverUrl;
    private String method;
    private String version;
    private String merchantId;
    private X509Certificate cert;
    private PrivateKey privateKey;
    private PublicKey heepayPublicKey;
 
 
    public AbstractHeepayClient(String serverUrl, String privateKeystr, String publicKeystr, String method, String version, String merchantId) throws Exception {
        this.serverUrl = serverUrl;
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        byte[] privateKeyPath = org.bouncycastle.util.encoders.Base64.decode(privateKeystr.getBytes());
        byte[] publicKeyPath = org.bouncycastle.util.encoders.Base64.decode(publicKeystr.getBytes());
        privateKey = keyFactory.generatePrivate(new PKCS8EncodedKeySpec((privateKeyPath)));
        heepayPublicKey = keyFactory.generatePublic(new X509EncodedKeySpec(publicKeyPath));
        this.method = method;
        this.version = version;
        this.merchantId = merchantId;
 
    }
 
    public SignResponse submitSign(BaseRequest baseRequest) {
        BaseResponse response = doPost(baseRequest, true);
        SignResponse signResponse = new SignResponse();
        if (response.getData() != null) {
            signResponse = JSON.parseObject(response.getData(), SignResponse.class);
        }
        signResponse.setCode(response.getCode());
        signResponse.setMsg(response.getMsg());
        signResponse.setSub_code(response.getSub_code());
        signResponse.setSub_msg(response.getSub_msg());
        signResponse.setData(response.getData());
        signResponse.setSign(response.getSign());
        return signResponse;
    }
 
 
    public QuerySignRespone querySign(BaseRequest baseRequest) {
        BaseResponse response = doPost(baseRequest, false);
        QuerySignRespone querySignRespone = new QuerySignRespone();
        if (response.getData() != null) {
            querySignRespone = JSON.parseObject(response.getData(), QuerySignRespone.class);
        }
        querySignRespone.setCode(response.getCode());
        querySignRespone.setMsg(response.getMsg());
        querySignRespone.setSub_code(response.getSub_code());
        querySignRespone.setSub_msg(response.getSub_msg());
        querySignRespone.setData(response.getData());
        querySignRespone.setSign(response.getSign());
        return querySignRespone;
    }
 
 
    private BaseResponse doPost(BaseRequest baseRequest, boolean flag) {
        SignEncrypt signEncrypt = new SignEncrypt();
        HttpUtil httpUtil = new HttpUtil();
        BaseResponse baseResponse = new BaseResponse();
        try {
            baseRequest.setMerch_id(merchantId);
            baseRequest.setVersion(version);
            baseRequest.setMethod(method);
            SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            baseRequest.setTimestamp(df.format(new Date()));
            Map<String, String> map = Utils.convertBeanNoneEmpty(baseRequest);
            String bizJson = Utils.coverMap2String(map);
            //签名
            String sign = signEncrypt.sign(bizJson, privateKey);
            baseRequest.setSign(sign);
 
 
            //bizContent加密
            String content = signEncrypt.encrypt(baseRequest.getBiz_content(), heepayPublicKey);
            baseRequest.setBiz_content(content);
 
 
            System.out.println("加密后------------------------------------------------------------------------>" + content);
            System.out.println();
 
            System.out.println("待签名------------------------------------------------------------------------>" + bizJson);
            System.out.println();
 
            System.out.println("签名后------------------------------------------------------------------------>" + sign);
            System.out.println();
 
            String res = httpUtil.sendJsonHttpPost(serverUrl, JSON.toJSONString(baseRequest));
            System.out.println("resq------------------------------------------------------------------------>" + JSON.toJSONString(baseRequest));
            System.out.println();
 
            System.out.println("resp------------------------------------------------------------------------>" + res);
            System.out.println();
 
            //解析response 取到data并解密
            ObjectMapper objectMapper = new ObjectMapper();
            JsonNode jsonNode = objectMapper.readTree(res.toString());
            String data = jsonNode.get("data").asText();
            //decrypt为解密后的值
            String decrypt = signEncrypt.decrypt(data, privateKey);
            //继续解析解密后的值拿到sign_url
            JsonNode jsonNode1 = objectMapper.readTree(decrypt.toString());
            String sign_url = jsonNode1.get("sign_url").asText();
            System.out.println("sign_url------------------------------------------------------------------------>" + sign_url);
 
 
            Map<String, String> resMap = Utils.convertBeanNoneEmpty(baseResponse);
            String resJson = Utils.coverMap2String(resMap);
            if (baseResponse.getSign() != null) {
                boolean result = signEncrypt.verify(resJson, baseResponse.getSign(), heepayPublicKey);
                System.out.print(result);
                if (result) {
                    return baseResponse;
                } else {
                    baseResponse.setCode("40002");
                    baseResponse.setMsg("返回结果验签异常");
                }
            }
        } catch (Exception e) {
            baseResponse.setCode("40004");
            baseResponse.setMsg("发送请求异常");
        }
        return baseResponse;
    }
}