mitao
2025-02-21 31573d6180d15ef65ed0df9c2732495f40b12663
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
package com.panzhihua.applets.unionpay;
 
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.digest.DigestUtils;
 
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
 
/**
 * @author kkqiao
 * 全民付移动支付小程序支付担保撤销接口
 * 说明:
 * 对于担保交易(下单接口请求参数中上送了担保交易标识并置true),用户支付成功后,商户可调用此
 * 接口来进行担保撤销操作。
 *  测试环境:http://58.247.0.18:29015/v1/netpay/secure-cancel
 *  生产环境:https://api-mop.chinaums.com/v1/netpay/secure-cancel
 */
public class SecureCancel {
 
    static String url = "https://test-api-open.chinaums.com/v1/netpay/secure-cancel";
 
    public static void main(String[] args) throws Exception{
        //1. 组建请求报文
        SecureCancelBody reqBody = new SecureCancelBody();
        reqBody.requestTimestamp = "2019-08-09 17:12:55";
        reqBody.mid = "898460107420248";
        reqBody.tid = "00000001";
        reqBody.instMid = "MINIDEFAULT";
        reqBody.merOrderId = "101771305dc89764b477474";
        System.out.println("request body:\n"+reqBody);
 
        //2. 获取认证报文,timestamp为当前日期,老旧日期无法请求成功
        String authorization = getAuthorization(UnionpayContent.APPID,UnionpayContent.APPKEY,"20190809171200","nonce",reqBody.toString());
        System.out.println("authorization:\n"+authorization);
 
        //3. 发送http请求,并解析返回信息
        String response = request(url,authorization,reqBody.toString());
        System.out.println("response:\n"+response);
    }
 
    /**
     * 发送http请求
     * @param url 请求url
     * @param authorization 认证报文
     * @param reqBody  请求体
     * @return response
     */
    static String request(String url, String authorization, String reqBody){
        String response = "";
        PrintWriter out = null;
        BufferedReader in = null;
        try{
            URL realUrl = new URL(url);
            URLConnection conn = realUrl.openConnection();
            HttpURLConnection httpUrlConnection = (HttpURLConnection) conn;
            httpUrlConnection.setRequestProperty("Content-Type", "application/json");
            httpUrlConnection.setRequestProperty("authorization",authorization);
            httpUrlConnection.setDoOutput(true);
            httpUrlConnection.setDoInput(true);
            out = new PrintWriter(httpUrlConnection.getOutputStream());
            out.write(reqBody);
            out.flush();
            httpUrlConnection.connect();
            in = new BufferedReader(new InputStreamReader(httpUrlConnection.getInputStream()));
            String line;
            while ((line = in.readLine()) != null) {
                response += line;
            }
        }catch(Exception e){
            e.printStackTrace();
        } finally {
            try {
                if (out != null) { out.close();}
                if (in != null) {in.close();}
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
        return response;
    }
 
    /**
     * 获取签名头
     * @param appid
     * @param appkey
     * @param timestamp 格式:"yyyyMMddHHmmss"
     * @param nonce 随机字符串,
     * @param body 请求体
     * @return authorization 认证报文
     * @throws Exception
     */
    static String getAuthorization(String appid, String appkey, String timestamp, String nonce, String body) throws Exception {
        byte[] data = body.getBytes("utf-8");
        InputStream is = new ByteArrayInputStream(data);
        String testSH = DigestUtils.sha256Hex(is);
        String s1 = appid+timestamp+nonce+testSH;
        Mac mac = Mac.getInstance("HmacSHA256");
        mac.init(new SecretKeySpec(appkey.getBytes("utf-8"),"HmacSHA256"));
        byte[] localSignature = mac.doFinal(s1.getBytes("utf-8"));
        String localSignatureStr = Base64.encodeBase64String(localSignature);
        return  "OPEN-BODY-SIG AppId="+"\""+appid+"\""+", Timestamp="+"\""+timestamp+"\""+", Nonce="+"\""+nonce+"\""+", Signature="+"\""+localSignatureStr+"\"";
    }
 
    static class SecureCancelBody{
        //消息ID
        String msgId;
        //报文请求时间,格式yyyy-MM-ddHH:mm:ss
        String requestTimestamp;
        //请求系统预留字段
        String srcReserve;
        //商户号
        String mid;
        //终端号
        String tid;
        //业务类型
        String instMid;
        //商户订单号
        String merOrderId;
 
        String toJson(){
            StringBuilder sb = new StringBuilder();
            sb.append("{");
            if (this.msgId != null) sb.append("\"msgId\":\"" + this.msgId + "\",");
            if (this.requestTimestamp != null) sb.append("\"requestTimestamp\":\"" + this.requestTimestamp + "\",");
            if (this.srcReserve != null) sb.append("\"srcReserve\":\"" + this.srcReserve + "\",");
            if (this.mid != null) sb.append("\"mid\":\"" + this.mid + "\",");
            if (this.tid != null) sb.append("\"tid\":\"" + this.tid + "\",");
            if (this.instMid != null) sb.append("\"instMid\":\"" + this.instMid + "\",");
            if (this.merOrderId != null) sb.append("\"merOrderId\":\"" + this.merOrderId + "\",");
            if (sb.charAt(sb.length() - 1) == ',')
                sb.deleteCharAt(sb.length() - 1);
            sb.append("}");
            return sb.toString();
        }
 
        public String toString(){
            return this.toJson();
        }
 
    }
 
}