java开发微信小程序和公众号支付部分
首先先上官方文档
https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=7_4&index=3
主要是下图圈起来的部分.
预支付之前必须要生成订单,之后需要的数据从订单中抓取 如 金额 商品名称等
用到的jar
<dependency>
<groupId>com.github.wxpay</groupId>
<artifactId>wxpay-sdk</artifactId>
<version>0.0.3</version>
</dependency>
/**
* 微信预支付
* @return
*/
@PostMapping("wxPay")
public R wxPay(HttpServletRequest request) {
//预支付
SortedMap<String, Object> map = wechatService.wxJSAPIPrePaymentTradingCard(order, openId, request);
return R.ok().put(map);
}
@Override
public SortedMap<String, Object> wxJSAPIPrePaymentTradingCard(String openId, OrderEntity order, HttpServletRequest request) {
try {
//order为订单表 看自己需求
//根据API给的签名规则进行签名
SortedMap<String, String> httpReq = new TreeMap<String, String>();
httpReq.put("appid", Wechat.APPID);
httpReq.put("mch_id", Wechat.MCH_ID);//商户号
httpReq.put("nonce_str", Util.getRandomStringByLength(32));
//httpReq.put("attach", "");//附加数据,非必填项
String name = "***";
httpReq.put("body", name);//产品名称
httpReq.put("out_trade_no", order.getOrderCode());//商户订单号
httpReq.put("total_fee", order.getOrderAmount().toString());//交易金额
httpReq.put("spbill_create_ip", IPUtils.getIpAddr(request)); //来源ip
String notifyUrl = "支付成功后的通知地址";
httpReq.put("notify_url", notifyUrl);////通知地址
httpReq.put("trade_type", "JSAPI");//交易类型
httpReq.put("openid", openId);//openId
//httpReq.put("time_expire", tradingEndTime);
String sign = WXPayUtil.generateSignature(httpReq, Wechat.KEY, WXPayConstants.SignType.MD5);
httpReq.put("sign", sign);
PlanConfig config = PlanConfig.getInstance();
WXPay wxPay = new WXPay(config);
String respXml = wxPay.requestWithoutCert(WXPayConstants.UNIFIEDORDER_URL, httpReq, config.getHttpConnectTimeoutMs(), config.getHttpReadTimeoutMs());
Map<String, String> respData = xmlToMap(respXml);
logger.info("预付返回:" + respData);
String return_code = null;
if (respData.containsKey("return_code")) {
return_code = respData.get("return_code");
}
if (return_code.equals(WXPayConstants.SUCCESS)) {
if (WXPayUtil.isSignatureValid(respData, config.getKey(), WXPayConstants.SignType.MD5)) {
//签名正确
if (respData.containsKey("result_code")) {
String resultCode = respData.get("result_code");
if (resultCode.equals(WXPayConstants.SUCCESS)) {
SortedMap<String, Object> map = new TreeMap<String, Object>();
map.put("appId", Wechat.APPID);
map.put("nonceStr", WXPayUtil.generateNonceStr());
map.put("package", "prepay_id=" + respData.get("prepay_id"));
map.put("signType", "MD5");
map.put("timeStamp", Util.getTimeStamp());
sign = PayUtils.createSign(map, Wechat.KEY);
map.put("paySign", sign);
return map;
} else {
throw new RRException(respData.get("err_code_des"), RRException.ERRORCODE);
}
} else {
throw new RRException("微信返回信息不正确", RRException.ERRORCODE);
}
} else {
throw new RRException("验证签名失败", RRException.ERRORCODE);
}
} else {
throw new RRException(respData.get("return_msg"), RRException.ERRORCODE);
}
} catch (Exception e) {
throw new RRException(e.getLocalizedMessage(), RRException.ERRORCODE);
}
}
public class PayUtils {
public static String createSign(SortedMap parameters, String key) {
StringBuffer sb = new StringBuffer();
Set es = parameters.entrySet();
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 + "&");
}
}
sb.append("key=" + key);
String sign = MD5Util.MD5Encode(sb.toString(), "UTF-8").toUpperCase();
System.out.println("加密后sign的值:"+sign);
return sign;
}
}
/**
* 微信支付后台通知接口(反复收到同样商户订单号的通知)
* @return
* @throws Exception
*/
@PostMapping("wxpayNotifyUrl")
public void wxpayNotifyUrl(HttpServletResponse response, HttpServletRequest request) throws Exception {
log.info("开始进入微信支付成功通知接口");
PrintWriter out = response.getWriter();
String ordercode = null;
try {
String requestXml = IOUtils.toString(request.getInputStream(), request.getCharacterEncoding());
log.info("wxpayNotifyUrl异步通知返回参数:" + requestXml);
//ClientResponseHandler queryRes = new ClientResponseHandler();
//queryRes.setContent(requestXml);
//SortedMap map = queryRes.getAllParameters();
//xmlToMap防止XXE攻击
Map<String, String> map = WechatServiceImpl.xmlToMap(requestXml);
if ("SUCCESS".equals((String) map.get("return_code"))) {
//String key = Wechat.KEY;//**
String sign = (String) map.get("sign");
log.info("微信支付后台通知接口参数:" + map.toString());
log.info("sign:" + sign);
String signMe = WXPayUtil.generateSignature(map, Wechat.KEY, WXPayConstants.SignType.MD5);
log.info("signMe:" + signMe);
if (sign.equals(signMe)) {
//签名成功
//查询该笔订单是否已经支付,如果已经支付则不在修改订单信息
if ("SUCCESS".equals(map.get("result_code"))) {
wechatService.wxpayNotifyHandler(map);
log.info("微信支付通知接口更新订单表更新成功,订单号:" + map.get("out_trade_no"));
success(out);
} else {
log.error("通知失败");
error(out, "通知失败");
}
} else {
log.error("签名失败");
error(out, "签名失败");
}
} else {
log.error("通知失败");
error(out, "通知失败");
}
} catch (Exception e) {
log.error("微信异步通知异常");
log.error(ExceptionUtils.getStackTrace(e));
e.printStackTrace();
error(out, "微信异步通知异常");
}
}
不懂留言.写的比较粗