微信支付说明
1.统一下单接口
统一支付接口:
url: https://api.mch.weixin.qq.com/pay/unifiedorder
目的:通过此接口来创建预支付订单,获取订单支付需要的prepay_id
过程:
1.对所有的支付中使用到的参数以字典序排序,然后使用商户的key进行MD5加密,获得加密字符串sign,
2.然后将sign加入以上信息中将其转化为xml,调用统一下单接口,获取prepay_id。
代码说明:
1.构建支付参数
//写购买商品的详情
JSONObject object = new JSONObject();
JSONArray array = new JSONArray();
JSONObject object1 = new JSONObject();
object1.put("goods_id","购买商品id");
object1.put("goods_name","购买商品名称");
object1.put("quantity","购买商品数量");
object1.put("price","商品单价");
array.add(object1);
object.put("goods_detail",array);
//构建统一下单需要的参数
Map<String,String> map = new HashMap<>();
map.put('appid',"支付的微信公众号的appid");
map.put("mch_id","支付的商户号");
map.put("device_info","设备编号");
map.put("sign_type","加密类型,一般使用MD5");
map.put("body","商品描述");
map.put("out_trade_no","商户订单号");
map.put("total_url","购买总金额");
map.put("notify_url","支付成功后微信的回掉地址,地址不许带参数");
map.put("trade_type","交易类型");
map.put("nonce_str","随机字符串");
map.put("detail","商品详情");
map.put("openid","支付人的openid");
map.put("spbill_create_ip","支付人ip地址");
//将统一下单参数进行字典序排序,进行签名 /**
* 微信支付签名算法(详见:https://pay.weixin.qq.com/wiki/doc/api/tools/cash_coupon.php?chapter=4_3).
*
* @param params 参数信息
* @param signType 签名类型,如果为空,则默认为MD5
* @param signKey 签名Key
* @param ignoreSignType 签名时,是否忽略signType
* @return 签名字符串
*/
public static String createSign(Map<String, String> params, String signType, String signKey, boolean ignoreSignType) {
SortedMap<String, String> sortedMap = new TreeMap<>(params); StringBuilder toSign = new StringBuilder();
for (String key : sortedMap.keySet()) {
String value = params.get(key);
boolean shouldSign = false;
if (ignoreSignType && "sign_type".equals(key)) {
shouldSign = false;
} else if (StringUtils.isNotEmpty(value)
&& !Lists.newArrayList("sign", "key", "xmlString", "xmlDoc", "couponList").contains(key)) {
shouldSign = true;
} if (shouldSign) {
toSign.append(key).append("=").append(value).append("&");
}
} toSign.append("key=").append(signKey);
if ("HMAC_SHA256".equals(signType)) {
return createHmacSha256Sign(toSign.toString(), signKey);
} else {
return DigestUtils.md5Hex(toSign.toString()).toUpperCase();
}
} //将上一步得到的签名加入上一个支付参数中,转为xml请求统一支付下单接口,获取订单支付需要的prepay_id
map.put("sign","上一步得到的签名");
//将map转为xml
public static String map2XmlString(Map<String, String> map) {
String xmlResult = ""; StringBuffer sb = new StringBuffer();
sb.append("<xml>");
for (String key : map.keySet()) {
String value = "<![CDATA[" + map.get(key) + "]]>";
sb.append("<" + key + ">" + value + "</" + key + ">");
}
sb.append("</xml>");
xmlResult = sb.toString();
return xmlResult;
}
//进行网络请求 public static String httpPostWithXml(String xml, String url){
StringBuffer stringBuffer = new StringBuffer();
HttpPost post = null;
try {
HttpClient httpClient = new DefaultHttpClient(); // 设置超时时间
//httpClient.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 2000);
//httpClient.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT, 2000); post = new HttpPost(url);
// 构造消息头
post.setHeader("Content-type", "application/json; charset=utf-8");
post.setHeader("Connection", "Close"); // 构建消息实体
StringEntity entity = new StringEntity(xml,"UTF-8");
entity.setContentEncoding("UTF-8");
// 发送Json格式的数据请求
entity.setContentType("application/json");
post.setEntity(entity); HttpResponse response = httpClient.execute(post);
// 检验返回码
int statusCode = response.getStatusLine().getStatusCode();
if(statusCode != HttpStatus.SC_OK){
LogUtil.info("请求出错: "+statusCode);
}else{
InputStream inputStream = response.getEntity().getContent();
BufferedReader br = new BufferedReader(new InputStreamReader(inputStream,"utf-8")); String str= "";
while((str = br.readLine()) != null){
stringBuffer .append(str );
}
}
} catch (Exception e) {
e.printStackTrace();
}
return stringBuffer.toString();
}
//得到了prepay_id,获取支付的签名
Map<String,String> map = new HashMap<>();
map.put('appId',"支付的微信公众号的appid");
map.put("signType","加密类型");
map.put("nonceStr","随机字符串");
map.put("package","固定格式: prepay_id=上一步获得的prepay_id");
map.put("timeStamp","当前时间戳");
//将上面的参数使用商户key进行签名,得到paysign,将paySign加入上面的参数之中,发给h5页面调起支付。
map.put(paySign,"得到的签名"); //h5页面调起支付
WeixinJSBridge.invoke(
'getBrandWCPayRequest', {
"appId":rs.appId, //公众号名称,由商户传入
"timeStamp":rs.timeStamp, //时间戳,自1970年以来的秒数
"nonceStr":rs.nonceStr, //随机串
"package":rs.package,
"signType":"MD5", //微信签名方式:
"paySign":rs.paySign //微信签名
},
function(res){
if(res.err_msg == "get_brand_wcpay_request:ok" ) {
//支付成功
}else if(res.err_msg =="get_brand_wcpay_request:fail"){
//支付失败
}else if(res.err_msg == "get_brand_wcpay_request:cancel"){
//取消支付
}else {
//其他情况
}
}
);