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(); } } }