老早就像做支付模块的东西,因为觉得很高大上,很早就开始把微信支付模块的重心签名给做好了,一直就缺个商家的key,现在有幸来电商公司,哈哈,果然一切很顺利,能够很给力地App端提供支持;
个人觉得核心部分的代码:
签名:
//参数:开始生成签名
SortedMap<Object,Object> parameters = new TreeMap<Object,Object>();
parameters.put("appid", appid);
parameters.put("mch_id", mch_id);
parameters.put("nonce_str", nonce_str);
parameters.put("body", body);
parameters.put("nonce_str", nonce_str);
parameters.put("detail", detail);
parameters.put("attach", attach);
parameters.put("out_trade_no", out_trade_no);
parameters.put("total_fee", total_fee);
parameters.put("time_start", time_start);
parameters.put("time_expire", time_expire);
parameters.put("notify_url", notify_url);
parameters.put("trade_type", trade_type);
parameters.put("spbill_create_ip", spbill_create_ip);
/**
* 微信支付签名算法sign
* @param characterEncoding
* @param parameters
* @return
*/
@SuppressWarnings("rawtypes")
public static String createSign(String characterEncoding,SortedMap<Object,Object> parameters){
StringBuffer sb = new StringBuffer();
Set es = parameters.entrySet();//所有参与传参的参数按照accsii排序(升序)
Iterator it = es.iterator();
while(it.hasNext()) {
Map.Entry entry = (Map.Entry)it.next();
String k = (String)entry.getKey();
Object v = entry.getValue();
if(null != v && !"".equals(v)
&& !"sign".equals(k) && !"key".equals(k)) {
sb.append(k + "=" + v + "&");
}
}
sb.append("key=" + Key);
System.out.println("字符串拼接后是:"+sb.toString());
String sign = MD5Util.MD5Encode(sb.toString(), characterEncoding).toUpperCase();
return sign;
}
将一坨参数包装成XML格式丢给微信:
/**
* 构造xml参数
* @param xml
* @return
*/
public static String xmlInfo(Unifiedorder unifiedorder){
//构造xml参数的时候,至少有10个必传参数
/*
* <xml>
<appid>wx2421b1c4370ec43b</appid>
<attach>支付测试</attach>
<body>JSAPI支付测试</body>
<mch_id>10000100</mch_id>
<nonce_str>1add1a30ac87aa2db72f57a2375d8fec</nonce_str>
<notify_url>http://wxpay.weixin.qq.com/pub_v2/pay/notify.v2.php</notify_url>
<openid>oUpF8uMuAJO_M2pxb1Q9zNjWeS6o</openid>
<out_trade_no>1415659990</out_trade_no>
<spbill_create_ip>14.23.150.211</spbill_create_ip>
<total_fee>1</total_fee>
<trade_type>JSAPI</trade_type>
<sign>0CB01533B8C1EF103065174F50BCA001</sign>
</xml>
*/
if(unifiedorder!=null){
StringBuffer bf = new StringBuffer();
bf.append("<xml>");
bf.append("<appid><![CDATA[");
bf.append(unifiedorder.getAppid());
bf.append("]]></appid>");
bf.append("<mch_id><![CDATA[");
bf.append(unifiedorder.getMch_id());
bf.append("]]></mch_id>");
bf.append("<nonce_str><![CDATA[");
bf.append(unifiedorder.getNonce_str());
bf.append("]]></nonce_str>");
bf.append("<sign><![CDATA[");
bf.append(unifiedorder.getSign());
bf.append("]]></sign>");
bf.append("<body><![CDATA[");
bf.append(unifiedorder.getBody());
bf.append("]]></body>");
bf.append("<detail><![CDATA[");
bf.append(unifiedorder.getDetail());
bf.append("]]></detail>");
bf.append("<attach><![CDATA[");
bf.append(unifiedorder.getAttach());
bf.append("]]></attach>");
bf.append("<out_trade_no><![CDATA[");
bf.append(unifiedorder.getOut_trade_no());
bf.append("]]></out_trade_no>");
bf.append("<total_fee><![CDATA[");
bf.append(unifiedorder.getTotal_fee());
bf.append("]]></total_fee>");
bf.append("<spbill_create_ip><![CDATA[");
bf.append(unifiedorder.getSpbill_create_ip());
bf.append("]]></spbill_create_ip>");
bf.append("<time_start><![CDATA[");
bf.append(unifiedorder.getTime_start());
bf.append("]]></time_start>");
bf.append("<time_expire><![CDATA[");
bf.append(unifiedorder.getTime_expire());
bf.append("]]></time_expire>");
bf.append("<notify_url><![CDATA[");
bf.append(unifiedorder.getNotify_url());
bf.append("]]></notify_url>");
bf.append("<trade_type><![CDATA[");
bf.append(unifiedorder.getTrade_type());
bf.append("]]></trade_type>");
bf.append("</xml>");
return bf.toString();
}
return "";
}
//构造xml参数
String xmlInfo = HttpXmlUtils.xmlInfo(unifiedorder);
String wxUrl = "https://api.mch.weixin.qq.com/pay/unifiedorder";
String method = "POST";
String weixinPost = HttpXmlUtils.httpsRequest(wxUrl, method, xmlInfo).toString();
因为body部分是商品的名称什么的,设计到中文,这个过程可能毁在统一下单的时候提醒:body不是UTF-8编码(我擦,我就在这里折腾了半天的
然后开始统一下单得到预支付ID,包装好给app端,app端处理好后再由微信开始回调,回调就会跳转到你的回调地址上,微信说建议校验下签名,照做就是的!
/**
* 微信支付回调
* @param request
* @param resposne
*/
@RequestMapping(value="/notifyUrlWeixin")
public void notifyWeixinPayment(HttpServletRequest request,HttpServletResponse response){
try{
BufferedReader reader = request.getReader();
String line = "";
StringBuffer inputString = new StringBuffer();
try{
PrintWriter writer = response.getWriter();
while ((line = reader.readLine()) != null) {
inputString.append(line);
}
if(reader!=null){
reader.close();
}
System.out.println("----[微信回调]接收到的报文---"+inputString.toString());
if(!StringUtils.isEmpty(inputString.toString())){
WXPayResult wxPayResult = JdomParseXmlUtils.getWXPayResult(inputString.toString());
if("SUCCESS".equalsIgnoreCase(wxPayResult.getReturn_code())){
SortedMap<Object,Object> parameters = new TreeMap<Object,Object>();
parameters.put("appid", wxPayResult.getAppid());
parameters.put("attach", wxPayResult.getAttach());
parameters.put("bank_type", wxPayResult.getBank_type());
parameters.put("cash_fee", wxPayResult.getCash_fee());
parameters.put("fee_type", wxPayResult.getFee_type());
parameters.put("is_subscribe", wxPayResult.getIs_subscribe());
parameters.put("mch_id", wxPayResult.getMch_id());
parameters.put("nonce_str", wxPayResult.getNonce_str());
parameters.put("openid", wxPayResult.getOpenid());
parameters.put("out_trade_no", wxPayResult.getOut_trade_no());
parameters.put("result_code", wxPayResult.getResult_code());
parameters.put("return_code", wxPayResult.getReturn_code());
parameters.put("time_end", wxPayResult.getTime_end());
parameters.put("total_fee", wxPayResult.getTotal_fee());
parameters.put("trade_type", wxPayResult.getTrade_type());
parameters.put("transaction_id", wxPayResult.getTransaction_id());
//反校验签名
String sign = WXSignUtils.createSign("UTF-8", parameters);
if(sign.equals(wxPayResult.getSign())){
//修改订单的状态
orderService.alipayNotifyPayment(wxPayResult.getOut_trade_no(), wxPayResult.getTransaction_id(),2);
writer.write(HttpXmlUtils.backWeixin("SUCCESS","OK"));
}else{
writer.write(HttpXmlUtils.backWeixin("FAIL","签名失败"));
}
}else{
writer.write(HttpXmlUtils.backWeixin("FAIL",wxPayResult.getReturn_msg()));
System.out.println("---------微信支付返回Fail----------"+wxPayResult.getReturn_msg());
}
if(writer!=null){
writer.close();
}
}else{
writer.write(HttpXmlUtils.backWeixin("FAIL","未获取到微信返回的结果"));
}
}catch(Exception e){
e.printStackTrace();
}
}catch(Exception ex){
ex.printStackTrace();
}
}
到这里差不多这个流程就算完了!!!!
注:1、修改资源文件中的 resources/sys.properties
#weixin apy
appid=你们的appid
mch_id=你们的mch_id
notify_url=你们的回调地址
2、key weixin/Utils/WXSignUtils.java
//http://mch.weixin.qq.com/wiki/doc/api/index.php?chapter=4_3
//商户Key:改成公司申请的即可
//32位密码设置地址:http://www.sexauth.com/ jdex1hvufnm1sdcb0e81t36k0d0f15nc
private static String Key = "你们的Key";
好了后新建一个Test的项目就可以直接运行了