以上是官网文档说明:
下面是根据文档 梳理下思路:
/**
关于签名的算法,api提供的原文是:
1.签名算法
签名生成的通用步骤如下:
第一步,设所有发送或者接收到的数据为集合M,将集合M内非空参数值的参数按照参数名ASCII码从小到大排序(字典序),使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串stringA。
特别注意以下重要规则:
参数名ASCII码从小到大排序(字典序);
如果参数的值为空不参与签名;
参数名区分大小写;
验证调用返回或微信主动通知签名时,传送的sign参数不参与签名,将生成的签名与该sign值作校验。
微信接口可能增加字段,验证签名时必须支持增加的扩展字段
第二步,在stringA最后拼接上key=(API密钥的值)得到stringSignTemp字符串,并对stringSignTemp进行MD5运算,再将得到的字符串所有字符转换为大写,得到sign值signValue。
举例:
假设传送的参数如下:
appid: wx8888888888888888
mch_id: 1900000109
device_info: 013467007045764
body: test
nonce_str: 5K8264ILTKCH16CQ2502SI8ZNMTM67VS
第一步:对参数按照key=value的格式,并按照参数名ASCII字典序排序如下:
stringA="appid=wx8888888888888888&body=test&device_info=013467007045764&mch_id=1900000109&nonce_str=5K8264ILTKCH16CQ2502SI8ZNMTM67VS";
第二步:拼接API密钥:
stringSignTemp="stringA&key=332F17B766FC787203EBE9D6E40457A1"
sign=MD5(stringSignTemp).toUpperCase()="332F17B766FC787203EBE9D6E40457A1"
*/
微信支付签名算法sign:
String keywx = "9e4b63793722c61a555696be897d61f8";
/**
* 微信支付签名算法sign
* 创建md5摘要,规则是:按参数名称a-z排序,遇到空值的参数不参加签名。
创建签名 签名 sign
*/
protected void createSign(SortedMap
MD5Util方法:
public class MD5Util {
private static String byteArrayToHexString(byte b[]) {
StringBuffer resultSb = new StringBuffer();
for (int i = 0; i < b.length; i++)
resultSb.append(byteToHexString(b[i]));
return resultSb.toString();
}
private static String byteToHexString(byte b) {
int n = b;
if (n < 0)
n += 256;
int d1 = n / 16;
int d2 = n % 16;
return hexDigits[d1] + hexDigits[d2];
}
public static String MD5Encode(String origin, String charsetname) {
String resultString = null;
try {
resultString = new String(origin);
MessageDigest md = MessageDigest.getInstance("MD5");
if (charsetname == null || "".equals(charsetname))
resultString = byteArrayToHexString(md.digest(resultString
.getBytes()));
else
resultString = byteArrayToHexString(md.digest(resultString
.getBytes(charsetname)));
} catch (Exception exception) {
}
return resultString;
}
private static final String hexDigits[] = { "0", "1", "2", "3", "4", "5",
"6", "7", "8", "9", "a", "b", "c", "d", "e", "f" };
}
参数包装成XML格式丢给微信:
/**
* 参数包装成XML格式丢给微信
* */
public String GetpayXmlRequest(String appid,String spid,String getNonce_str,String sign, String trans_time, String bill_type)
{
/*
wx8888888888888888
20160426
ALL
1900000109
21df7dc9cd8616b56919f20d9f679233
E8778F1C4C953C0BF37AA45C3BC379D0
*/
StringBuffer sb = new StringBuffer();
sb.append("");
sb.append(" ");
sb.append(" ");
sb.append(" ");
sb.append(" ");
sb.append(" ");
sb.append(" ");
sb.append(" ");
return sb.toString();
/*
sb.append("");
sb.append(appid);
sb.append(" ");
sb.append("");
sb.append(trans_time);
sb.append(" ");
sb.append("");
sb.append(bill_type);
sb.append(" ");
sb.append("");
sb.append(spid);
sb.append(" ");
sb.append("");
sb.append(stamp);
sb.append(" ");
sb.append("");
sb.append(sign);
sb.append(" ");
sb.append("");
return sb.toString();
*/
}
post发送请求数据:
/** 请求的参数 */
protected SortedMap parameters;
protected HttpServletRequest request;
protected HttpServletResponse response;
/** 密钥 */
protected String key;
/** debug信息 */
protected String debugInfo;
/**
*获取密钥
*/
public String getKey() {
return key;
}
/**
*设置密钥
*/
public void setKey(String key) {
this.key = key;
}
/**
* post发送请求数据
* @param urlStr
*/
public void testPost(String urlStr) {
BufferedReader br= null;
HttpURLConnection con=null;
OutputStreamWriter out=null;
try {
URL url = new URL(urlStr);
// URLConnection con = url.openConnection();
con = (HttpURLConnection) url.openConnection();
// 发送POST请求必须设置如下两行
con.setDoOutput(true); // POST方式
con.setDoInput(true);
con.setUseCaches(false);
con.setRequestMethod("POST");
// 设置通用的请求属性
con.setRequestProperty("accept", "*/*");
con.setRequestProperty("connection", "Keep-Alive");
con.setRequestProperty("user-agent",
"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
// con.setRequestProperty("Pragma:", "no-cache");
// con.setRequestProperty("Cache-Control", "no-cache");
// con.setRequestProperty("Content-Type", "text/xml");
// 输出流,写数据
out = new OutputStreamWriter(con
.getOutputStream(),"UTF-8");
// 发送请求参数
String xmlInfo = GetpayXmlRequest("wx8888888888888888","1900000109","1462240367309","56B106AFDDF1802B12DF8634C2E73B92","20160623","ALL");
System.out.println("urlStr=" + urlStr);
System.out.println("xmlInfo=" + xmlInfo);
out.write(new String(xmlInfo.getBytes("UTF-8")));
// flush输出流的缓冲
out.flush();
// out.close();
//读取服务器的响应内容并显示 定义BufferedReader输入流来读取URL的响应
br = new BufferedReader(new InputStreamReader(con
.getInputStream(),"UTF-8"));
String line = "";
StringBuffer buffer = new StringBuffer();
// for (line = br.readLine(); line != null; line = br.readLine()) {
// System.out.println(line);
// buffer.append(line);// 将读到的内容添加到 buffer 中
// buffer.append("\n"); // 添加换行符
//
// }
while ((line = br.readLine()) != null)
{
buffer.append(line); // 将读到的内容添加到 buffer 中
buffer.append("\n"); // 添加换行符
System.out.println(line);
}
//con.getOutputStream().close();
}
catch (MalformedURLException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
// 使用finally块来关闭输入流
finally {
try {
if(out!=null){
out.close();
}
if (br != null)
{
br.close();
con.disconnect();
}
} catch (Exception e2) {
e2.printStackTrace();
}
}
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
String url = "https://api.mch.weixin.qq.com/pay/downloadbill";
new HttpPostTest().testPost(url);
//微信api提供的参数 赋值
String appid="wx8888888888888888";
String spid="1900000109";// 1221024001
String getNonce_str="1462240367309";//1462240367309 ibuaiVcKdpRxkhJA
String trans_time="20160623";
String bill_type="ALL";
String sign ="";
// 获取值
SortedMap
注意 以上单元测试时要先 创建生成签名后,再把签名的值传到参数中去,然后进行httppost请求即可。
这里商户号 一定都要改成自己申请的appid 和 mch_id 这样就会有微信返回结果数据显示了,结果实例就不在这里展现出来。
获取到对账信息后就是后续的业务处理了,根据不同的需求进行不同的业务处理了,主要就是解析数据格式,生成文档,保存到本地以及导入到数据库的逻辑操作了。