一:简介
开发之前我们需要做一些准备工作,如下:
首先我们需要拿到微信的商户号,appid,API密钥等信息。在微信支付自己账号下获取。
之后我们查看微信支付统一下单的api接口文档。
https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=9_1
话不啰嗦,接下来开始实战吧
二:集成步骤
1.引入微信支付SDK依赖:
<dependency>
<groupId>com.github.wxpay</groupId>
<artifactId>wxpay-sdk</artifactId>
<version>0.0.3</version>
</dependency>
2.微信app支付参数配置:
public class ConfigUtil {
/**
* 服务号相关信息
*/
public final static String APPID = "XXXXX";//服务号的应用号
public final static String MCH_ID = "XXXXXX";//商户号
public final static String API_KEY = "XXXXX";//API密钥
public final static String SIGN_TYPE = "MD5";//签名加密方式D
public final static String UNIFIED_ORDER_URL = "https://api.mch.weixin.qq.com/pay/unifiedorder";//请求下单的http
}
3.微信支付接口代码
/**
* 微信支付
* @return
*/
@PostMapping("/weChatPay")
public HttpResult weChatPay(@RequestBody SysOrder order) throws Exception {
log.info(">>>>>>>>>>>>>微信支付开始>>>>>>>>>>>>>>>");
Map<String, String> parameters = buildWeChatPayOrderMap(sysOrder);
//设置签名--微信SKD提供了获取签名的方法
String sign=WXPayUtil.generateSignature(parameters,ConfigUtil.API_KEY);
parameters.put("sign", sign);
//封装请求参数结束 将map转xml
String requestXML = new String(WXPayUtil.mapToXml(parameters).getBytes("utf-8"), "iso8859-1");
//调用统一下单接口--见标题4
String result = PayCommonUtil.httpPostXML(ConfigUtil.UNIFIED_ORDER_URL, requestXML); /**统一下单接口返回正常的prepay_id,再按签名规范重新生成签名后,将数据传输给APP。参与签名的字段名为appId,partnerId,prepayId,nonceStr,timeStamp,package。注意:package的值格式为Sign=WXPay**/
String prepay_id = "";// 预支付id
if (result.indexOf("SUCCESS") != -1) {//判断统一下单是否成功
Map<String, String> map = WXPayUtil.xmlToMap(result);
prepay_id = (String) map.get("prepay_id");
}
Map<String, String> payMap = new HashMap<String, String>();
payMap.put("appid", ConfigUtil.APPID);
payMap.put("partnerid", ConfigUtil.MCH_ID);
payMap.put("prepayid", prepay_id);//预支付id
payMap.put("noncestr", WXPayUtil.generateNonceStr());
payMap.put("package", "Sign=WXPay");
payMap.put("timestamp", String.valueOf(System.currentTimeMillis()/1000).substring(0, 10));
String paySign = WXPayUtil.generateSignature(payMap, ConfigUtil.API_KEY);
payMap.put("sign", paySign);
//将获取到的订单信息给到APP端
JSONObject JSONObj = JSONObject.parseObject(JSON.toJSONString(payMap));
return HttpResult.ok(JSONObj);
}
/**
* 构造微信支付订单参数列表
*/
private Map<String, String> buildWeChatPayOrderMap(SysOrder sysOrder) {
BigDecimal amount=sysOrder.getAmountPayable();//订单金额
amount = amount.multiply(new BigDecimal(100));// 单位分
amount = amount.setScale(0, RoundingMode.DOWN);//取整
Map<String, String> parameters = new HashMap<String, String>();
parameters.put("appid", ConfigUtil.APPID);
parameters.put("mch_id", ConfigUtil.MCH_ID);
parameters.put("nonce_str", WXPayUtil.generateNonceStr());//32位以内的随机数
parameters.put("body", "测试购买内容");//购买内容
parameters.put("out_trade_no",XXX); //订单id
parameters.put("fee_type", "CNY");
// 微信中金额 1=0.01元。所以计算金额记得换算 X*100
parameters.put("total_fee",String.valueOf(amount));//支付金额单位为【分】*100
parameters.put("spbill_create_ip", "127.0.0.1");
parameters.put("notify_url", "http://XXXXXXX-------/weCahtComback");//回调接口地址
parameters.put("trade_type", "APP");
return parameters;
}
4.统一下单请求(标题4)
public class PayCommonUtil {
/**
* post请求并得到返回结果
* @param requestUrl
* @param xml
* @return
*/
public static String httpPostXML(String requestUrl, String xml) {
CloseableHttpClient httpClient = HttpClients.createDefault();
HttpPost httpPost = new HttpPost(requestUrl);
StringEntity postEntity = new StringEntity(xml, "UTF-8");
httpPost.addHeader("Content-Type", "text/xml;charset=UTF-8");
httpPost.setEntity(postEntity);
try {
HttpResponse response = httpClient.execute(httpPost);
HttpEntity entity = response.getEntity();
return EntityUtils.toString(entity, "UTF-8");
} catch (Exception var7) {
}
return "";
}
}
注:注意HttpResponse 引入的包是 package org.apache.http;下面的
5.微信回调接口
@RequestMapping("/weCahtComback")
public void wxNotify(HttpServletRequest request,HttpServletResponse response) throws Exception{
BufferedReader br = new BufferedReader(new InputStreamReader((ServletInputStream)request.getInputStream()));
String line = null;
StringBuilder sb = new StringBuilder();
while((line = br.readLine()) != null){
sb.append(line);
}
br.close();
//sb为微信返回的xml
String notityXml = sb.toString();
String resXml = "";
Map parameters = WXPayUtil.xmlToMap(notityXml);
String returnCode = (String) parameters.get("return_code");
if("SUCCESS".equals(returnCode)){
//验证签名是否正确(根据订单信息重新获取签名)
String sign=WXPayUtil.generateSignature(parameters,ConfigUtil.API_KEY);
//根据微信官网的介绍,此处不仅对回调的参数进行验签,还需要对返回的金额与系统订单的金额进行比对等
if(sign.equals(parameters.get("sign"))){
// 这里是支付成功
//执行自己的业务逻辑
String out_trade_no = (String) parameters.get("out_trade_no"); //订单号id
String transaction_id = (String) parameters.get("transaction_id"); //微信支付订单号
}
}
/**回调逻辑代码编写*/
//通知微信服务器已经支付成功
resXml = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>"
+ "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> ";
} else {
System.out.println("微信支付回调失败!签名不一致");
}
}else{
resXml = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>"
+ "<return_msg><![CDATA[报文为空]]></return_msg>" + "</xml> ";
}
System.out.println(resXml);
System.out.println("微信支付回调数据结束");
BufferedOutputStream out = new BufferedOutputStream(
response.getOutputStream());
out.write(resXml.getBytes());
out.flush();
out.close();
}
如果觉得笔者写的文章对你有些用处,麻烦点个赞让我知道一下~哈哈,谢谢!!有问题同学也可以留言,大家一起学习~~
展示下支付页面