注意的是
1、支付方法的路径必须在支付授权目录中设置的路径下边 否则报错
2、用于生成预支付id的签名参数必须和提交到微信的商品参数一致否则报错。
3、签名的问题:在使用商户平台提供的支付方式支付的时候只需要两个签名 得到预支付id需要的签名 和 支付时使用的签名, 如果使用公众平台提供的jssdk当中的支付方式需要三种签名 验证支付需要的签名、 得到预支付id需要的签名、 支付时使用的签名
微信支付的流程:
得到签名—>得到预支付id—>得到预支付id—>得到支付签名—->支付
// 准备字符串获得
public static String create_nonce_str() {
String uuid = UUID.randomUUID().toString();
uuid = uuid.replace("-", "");
if (uuid.length() > 32) {
uuid = uuid.substring(0, 32);
}
return uuid;
}
/**
* 微信签名 创建md5摘要,规则是:按参数名称a-z排序,遇到空值的参数不参加签名。
*/
public static String createSign(SortedMap<String, String> packageParams) {
StringBuffer sb = new StringBuffer();
Set es = packageParams.entrySet();// 所有参与传参的参数按照accsii排序(升序)
Iterator it = es.iterator();
while (it.hasNext()) {
Map.Entry entry = (Map.Entry) it.next();
String k = (String) entry.getKey();
String v = (String) entry.getValue();
if (null != v && !"".equals(v) && !"sign".equals(k) && !"key".equals(k)) {
sb.append(k + "=" + v + "&");
}
}
String Key = WinxinFinalValue.API_SECRET;
sb.append("key=" + Key);
System.out.println("md5 sb:" + sb);
String sign = MD5Utils.MD5Encode(sb.toString(), "UTF-8").toUpperCase();
System.out.println("packge签名:" + sign);
return sign;
}
package com.team.weixin.util;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import com.team.weixin.model.Pay;
import com.team.weixin.model.ReceiveXmlEntity;
public class SerializeXmlUtil {
/**
* @description 将xml字符串转换成map
* @param xml
* @return Map
*/
/**
* 解析微信xml消息
*
* @param strXml
* @return
*/
public static Pay getMsgEntity(String strXml) {
System.out.println("99999999999999999999999999999");
System.out.println(strXml);
System.out.println("99999999999999999999999999999");
Pay msg = null;
try {
if (strXml.length() <= 0 || strXml == null)
return null;
// 将字符串转化为XML文档对象
Document document = DocumentHelper.parseText(strXml);
// 获得文档的根节点
Element root = document.getRootElement();
// 遍历根节点下所有子节点
Iterator<?> iter = root.elementIterator();
// 遍历所有结点
msg = new Pay();
// 利用反射机制,调用set方法
// 获取该实体的元类型
System.out.println("在这里");
Class<?> c = Class.forName("com.team.weixin.model.Pay");
System.out.println("在这里55");
msg = (Pay) c.newInstance();// 创建这个实体的对象
while (iter.hasNext()) {
Element ele = (Element) iter.next();
// 获取set方法中的参数字段(实体类的属性)
Field field = c.getDeclaredField(ele.getName());
// 获取set方法,field.getType())获取它的参数数据类型
String first = ele.getName().substring(0, 1).toUpperCase();
String rest = ele.getName().substring(1, ele.getName().length());
String newStr = new StringBuffer(first).append(rest).toString();
System.out.println("set" +newStr+","+field.getType());
Method method = c.getDeclaredMethod("set" +newStr, field.getType());
method.invoke(msg, ele.getText());
// 调用set方法
}
} catch (Exception e) {
// TODO: handle exception
System.out.println("xml 格式异常: " + strXml);
e.printStackTrace();
}
return msg;
}
}
// 得到prepay_id
public static String getPayNo(String url, String xmlParam) {
DefaultHttpClient client = new DefaultHttpClient();
HttpPost httpost = new HttpPost(url);
client.getParams().setParameter(ClientPNames.ALLOW_CIRCULAR_REDIRECTS, true);
String prepay_id = "";
String nustr = "";
try {
httpost.setEntity(new StringEntity(xmlParam, "UTF-8"));
HttpResponse response = client.execute(httpost);
String jsonStr = EntityUtils.toString(response.getEntity(), "UTF-8");
Map<String, Object> dataMap = new HashMap<String, Object>();
System.out.println(jsonStr);
prepay_id = SerializeXmlUtil.getMsgEntity(jsonStr.toString()).getPrepay_id();
nustr = SerializeXmlUtil.getMsgEntity(jsonStr.toString()).getNonce_str();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return prepay_id + "," + nustr;
}
// 调用预支付订单
public static WeixinUnifiedOrder getUnifiedOrder(WeixinUnifiedOrder order, String openid)
throws UnknownHostException {
openid = "oJBwTwTjJTp4BNHlJC38c4Xczjjk";
String nonce_str = WeixinUtil.create_nonce_str();
String notify_url = "www.shujb.com" + "/weixingroup/weixin/paySuccess";
String spbill_create_ip = InetAddress.getLocalHost().getHostAddress().toString();// 获得本机IP
order.setAppid("appid 由商户提供");
order.setMch_id("商户id(商户平台提供) 由商户提供");
order.setNonce_str(nonce_str);
order.setNotify_url(notify_url);
order.setSpbill_create_ip(spbill_create_ip);
order.setTrade_type("JSAPI");
SortedMap<String, String> packageParams = new TreeMap<String, String>();
packageParams.put("appid", order.getAppid());
packageParams.put("mch_id", order.getMch_id());
packageParams.put("device_info", "WEB");
packageParams.put("nonce_str", order.getNonce_str());
packageParams.put("body", order.getBody());
packageParams.put("out_trade_no", order.getOut_trade_no());
packageParams.put("total_fee", order.getTotal_fee());
packageParams.put("spbill_create_ip", order.getSpbill_create_ip());
packageParams.put("notify_url", order.getNotify_url());
packageParams.put("trade_type", order.getTrade_type());
/* packageParams.put("attach", order.getAttach()); */
packageParams.put("openid", openid);
String sign = createSign(packageParams);// 创建用于获得预支付id的签名
String xml = "<xml>" + "<appid>" + order.getAppid() + "</appid>" + "<mch_id>" + order.getMch_id() + "</mch_id>"
+ "<device_info><![CDATA[WEB]]></device_info>" + "<nonce_str>" + order.getNonce_str() + "</nonce_str>"
+ "<sign><![CDATA[" + sign + "]]></sign>" + "<body>" + order.getBody() + "</body>" + "<out_trade_no>"
+ order.getOut_trade_no() + "</out_trade_no>" + "<total_fee>" + order.getTotal_fee() + "</total_fee>"
+ "<spbill_create_ip>" + order.getSpbill_create_ip() + "</spbill_create_ip>" + "<notify_url>"
+ order.getNotify_url() + "</notify_url>" + "<trade_type>" + order.getTrade_type() + "</trade_type>" +
/* "<attach>" + order.getAttach() + "</attach>"+ */
"<openid>" + openid + "</openid>" + "</xml>";
System.out.println(xml);
// 得到prepay_id
String createOrderURL = "https://api.mch.weixin.qq.com/pay/unifiedorder";
String prepay_id = "";
try {
String[] pi = getPayNo(createOrderURL, xml).split(",");
prepay_id = pi[0];
order.setPrepay_id(prepay_id);
if (prepay_id.equals("")) {
System.out.println("统一支付接口获取预支付订单出错");
}
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
return order;
}
这里是controller中的调用统一下单接口
//支付模块
//支付
@RequestMapping("/to_pay")
public String to_pay(@RequestParam("money") String money , HttpServletRequest request,HttpSession seeion,Model model){
//获得订单号
//获得
WeixinUnifiedOrder order = new WeixinUnifiedOrder();
order.setAttach("附加数据,在查询API和支付通知中原样返回,该字段主要用于商户携带订单的自定义数据");//附加消息
order.setTotal_fee("1");//金额
order.setBody("罗辑思维-图书");//
order.setOut_trade_no(primaryKeyFactory.generatePrimaryKey()+"");
try {
order = WeixinUtil.getUnifiedOrder(order, seeion.getAttribute("openid")+"");
//生成支付签名
String timestamp = WeixinUtil.create_timestamp();
String nonceStr =WeixinUtil.create_nonce_str();
String prepay_id = "prepay_id="+order.getPrepay_id();
//创建支付用的数据
SortedMap<String, String> finalpackage = new TreeMap<String, String>();
finalpackage.put("appId", WinxinFinalValue.AppID);
finalpackage.put("timeStamp", timestamp);
finalpackage.put("nonceStr", nonceStr);
finalpackage.put("package", prepay_id);
finalpackage.put("signType", "MD5");
String paySign = WeixinUtil.createSign(finalpackage);//创建支付用的签名
PayReg payReg = new PayReg();
payReg.setAppid(WinxinFinalValue.AppID);
payReg.setTimeStamp(timestamp);
payReg.setNonceStr(nonceStr);
payReg.setPackages("prepay_id="+order.getPrepay_id());
payReg.setSignType("MD5");
payReg.setSign(paySign);
model.addAttribute("obj",payReg);
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return "/dataTreasure/pay";
}