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
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
package com.panzhihua.applets.unionpay;
 
import com.panzhihua.common.utlis.DateUtils;
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;
import java.time.LocalDateTime;
 
/**
 * @author kkqiao0
 * 全民付移动支付小程序支付订单交易查询接口
 * 说明:
 * 钱包支付时,因通讯故障、服务器故障等原因,造成收银机最终没有收到支付结果通知,收银员不确定
 * 该笔支付后台处理结果,可以在收银机上发起“查询”交易,查询该笔交易订单在钱包后台的支付结果,
 * 并将支付结果返回给收银机。
 *  测试环境:http://58.247.0.18:29015/v1/netpay/query
 *  生产环境:https://api-mop.chinaums.com/v1/netpay/query
 */
public class Query {
    static String url = "https://api-mop.chinaums.com/v1/netpay/query";
 
    /**
     * 查询接口
     * @return
     */
    public static String query(String merOrderId)
    {
        //1. 组建请求报文
        LocalDateTime time= DateUtils.getCurrentDate();
        QueryBody reqBody = new QueryBody();
        reqBody.requestTimestamp = time.format(DateUtils.format_ymdhms);//"2019-08-09 17:32:55";
        reqBody.mid = UnionpayContent.MID;
        reqBody.tid = UnionpayContent.TID;
        reqBody.instMid = UnionpayContent.INSTMID;
        reqBody.merOrderId = merOrderId;
        System.out.println("request body:\n"+reqBody);
 
        //2. 获取认证报文,timestamp为当前日期,老旧日期无法请求成功
        String authorization = null;
        try {
            authorization = getAuthorization(UnionpayContent.APPID,UnionpayContent.APPKEY,
                    time.format(DateUtils.format_ymdhms_string),"nonce",reqBody.toString());
        } catch (Exception e) {
            e.printStackTrace();
            return "订单交易查询失败";
        }
        System.out.println("authorization:\n"+authorization);
 
        //3. 发送http请求,并解析返回信息
        String response = request(url,authorization,reqBody.toString());
        System.out.println("response:\n"+response);
        return 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 QueryBody{
        //消息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();
        }
 
    }
 
}