happybird00 2018-11-26
由于目前电商的用户使用微信访问的居多,所以要在商城集成微信支付,官网Demo仅为工具类及流程,并没有向支付宝那样拿来即用的示例代码,故在这里记录下踩过的坑
1、确保你的微信公众账号已经认证,认证费每年¥300
2、确保已开通微信支付,且已开通微信支付的相应产品,如:扫码支付、H5支付等
3、登录微信支付后台,产品中心>>开发配置>>支付配置,设置相应支付产品的业务域名;获取到后台的下列值
private final String appId = ""; private final String appSecret = ""; private final String mch_id = ""; private final String key = "";//32位apiKey
4、开始踩坑:公众号支付
4.1:支付页面请求后台获取微信支付初始配置参数
var wxPayConfig;
function getWxPayConfig(cb){
$.ajax({
type: "GET",
url: "/xxx/order/wxPayConfig",
data:{
url : encodeURIComponent(window.location.href)
},
dataType:"json",
beforeSend: function () {
$("#xxx").attr({ "disabled": "disabled" });//获取到配置之前,禁止点击付款按钮
},
success: function (data) {
wxPayConfig = data;
$("#xxx").removeAttr("disabled");//获取到配置,打开付款按钮
wx.config({
debug: true, // 开启调试模式,成功失败都会有alert框
appId: data.appId, // 必填,公众号的唯一标识
timestamp: data.timeStamp, // 必填,生成签名的时间戳
nonceStr: data.nonceStr, // 必填,生成签名的随机串
signature: data.signatureShaHex,// 必填,签名
jsApiList: ['chooseWXPay'] // 必填,需要使用的JS接口列表
});
wx.ready(function () {
// config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中。
cb();
});
wx.error(function (res) {
// config信息验证失败会执行error函数,如签名过期导致验证失败,具体错误信息可以打开config的debug模式查看,也可以在返回的res参数中查看,对于SPA可以在这里更新签名。
//alert(res);
});
}
});
}先配置参数类:BlsWXPayConfig
public class BlsWXPayConfig extends WXPayConfig {
private final String appId = "";
private final String appSecret = "";
private final String mch_id = "";
private final String key = "";//32位apiKey
private final String wxPayNotify = "http://www.xxx.com/xxx/wxPayNotify.jsp";//注意不能带参数
public String getNotifyUrl(){
return this.wxPayNotify;
}
/* (non-Javadoc)
* @see com.wxpay.sdk.WXPayConfig#getAppID()
*/
@Override
public String getAppID() {
return appId;
}
/* (non-Javadoc)
* @see com.wxpay.sdk.WXPayConfig#getMchID()
*/
@Override
public String getMchID() {
return mch_id;
}
/* (non-Javadoc)
* @see com.wxpay.sdk.WXPayConfig#getKey()
*/
@Override
public String getKey() {
return key;
}
public String getAppSecret() {
return appSecret;
}
/* (non-Javadoc)
* @see com.wxpay.sdk.WXPayConfig#getCertStream()
*/
@Override
InputStream getCertStream() {
return null;
}
/* (non-Javadoc)
* @see com.wxpay.sdk.WXPayConfig#getWXPayDomain()
*/
@Override
IWXPayDomain getWXPayDomain() {
return new IWXPayDomain(){
@Override
public void report(String domain, long elapsedTimeMillis,
Exception ex) {
// TODO Auto-generated method stub
}
@Override
public DomainInfo getDomain(WXPayConfig config) {
return new DomainInfo("www.xxx.com", true);
}
};
}票据工具类:JsapiTicketUtil
public class JsapiTicketUtil {
public static final Log LOG = LogFactory.getLog(JsapiTicketUtil.class);
public static String getJsapiTicket(BlsWXPayConfig wxConfig) {
String requestUrl = "https://api.weixin.qq.com/cgi-bin/token?";
String params = "grant_type=client_credential&appid=" + wxConfig.getAppID() + "&secret=" + wxConfig.getAppSecret() + "";
String result = httpGet(requestUrl + params);
String access_token = JsonUtils.fromJson(result, WxAuthPros.class).getAccess_token();
requestUrl = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?";
params = "access_token=" + access_token + "&type=jsapi";
result = httpGet(requestUrl + params);
String jsapi_ticket = JsonUtils.fromJson(result, WxAuthPros.class).getTicket();
return jsapi_ticket;
}
/**
* post请求
* @param url
* @return
*/
public static String httpPost(String url) {
//post请求返回结果
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpPost method = new HttpPost(url);
String str = "";
try {
HttpResponse result = httpClient.execute(method);
url = URLDecoder.decode(url, "UTF-8");
/**请求发送成功,并得到响应**/
if (result.getStatusLine().getStatusCode() == 200) {
try {
/**读取服务器返回过来的json字符串数据**/
str = EntityUtils.toString(result.getEntity());
} catch (Exception e) {
LOG.error("post请求提交失败:" + url, e);
}
}
} catch (IOException e) {
LOG.error("post请求提交失败:" + url, e);
}
return str;
}
/**
* get 请求、
* @param url
* @return
*/
public static String httpGet(String url) {
//get请求返回结果
String strResult = null;
try {
DefaultHttpClient client = new DefaultHttpClient();
//发送get请求
HttpGet request = new HttpGet(url);
HttpResponse response = client.execute(request);
/**请求发送成功,并得到响应**/
if (response.getStatusLine().getStatusCode() == org.apache.http.HttpStatus.SC_OK) {
/**读取服务器返回过来的json字符串数据**/
strResult = EntityUtils.toString(response.getEntity());
} else {
LOG.error("get请求提交失败:" + url);
}
} catch (IOException e) {
LOG.error("get请求提交失败:" + url, e);
}
return strResult;
}对应后台代码:
/**
* 获取微信初始化配置
* @param mapping
* @param form
* @param request
* @param response
* @return
*/
public ActionForward wxPayConfig(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response){
long timeStamp = WXPayUtil.getCurrentTimestamp();
String nonceStr = WXPayUtil.generateNonceStr();
Map<String, String> data = new TreeMap<String, String>();
BlsWXPayConfig wxConfig = new BlsWXPayConfig();
try {
String url = URLDecoder.decode(request.getParameter("url").split("#")[0], "UTF-8");
String jsapi_ticket = JsapiTicketUtil.getJsapiTicket(wxConfig);
data.put("jsapi_ticket", jsapi_ticket);
data.put("noncestr", nonceStr);
data.put("timestamp", String.valueOf(timeStamp));
data.put("url", url);
String string1 = "jsapi_ticket=" + jsapi_ticket +
"&noncestr=" + nonceStr +
"×tamp=" + timeStamp +
"&url=" + url;
MessageDigest crypt = MessageDigest.getInstance("SHA-1");
crypt.reset();
crypt.update(string1.getBytes("UTF-8"));
String signatureMd5 = WXPayUtil.generateSignature(data, wxConfig.getKey());
String signatureShaHex = DigestUtils.shaHex(string1);;
JSONObject jsonData = new JSONObject();
jsonData.put("jsapi_ticket", jsapi_ticket);
jsonData.put("url", url);
jsonData.put("appId", wxConfig.getAppID());
jsonData.put("timeStamp", timeStamp);
jsonData.put("nonceStr" , nonceStr);
jsonData.put("signatureMd5", signatureMd5);
jsonData.put("signatureShaHex", signatureShaHex);
super.responseWrite(response, jsonData);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}4.2 点击按钮唤起微信支付,调用前需要先获得Code
function getQueryString(name){
var reg = new RegExp("(^|&)"+ name +"=([^&]*)(&|$)");
var r = window.location.search.substr(1).match(reg);
if(r!=null)return unescape(r[2]); return null;
}
var code = getQueryString("code");
if(code != "" && code != "null"){//授权后直接唤起支付
startWxPay();
}
function startWxPay() {
if(!wxPayConfig){
return getWxPayConfig(startWxPay)
}
var code = getQueryString("code");
if(code == "" || code == "null"){
var url = window.location.href;
return window.location.href = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=" + wxPayConfig.appId +
"&redirect_uri=" + encodeURIComponent(url)
"&response_type=code" +
"&scope=snsapi_base" +
"&state=123" +
"#wechat_redirect";
}
$.ajax({
type: "POST",
url: "/xxx/order/getWxPaySign",
data: {
"code": code,
"orderId" : $("#ordId").val(),
"orderNumber" : $("#orderNumber").val(),
"total_fee" : $("#ototalPrice").val()
},
dataType:"json",
beforeSend: function () {
$("#xxx").attr({ "disabled": "disabled" });
},
success: function (res) {
$("#xxx").removeAttr("disabled");
if (res.openid != null && res.openid != undefined && res.openid != "") {
window.localStorage.setItem("openid", res.openid);
}
wx.chooseWXPay({
timestamp: res.timeStamp, // 支付签名时间戳
nonceStr: res.nonceStr, // 支付签名随机串,不长于32 位
"package": res["package"], // 统一支付接口返回的prepay_id参数值,提交格式如:prepay_id=***)
signType: res.signType, // 签名方式,默认为'SHA1',使用新版支付需传入'MD5'
paySign: res.paysign, // 支付签名
success: function (res) {
//支付成功
window.location.href = "/xxx/order/detail?id=" + $("#ordId").val();
},
cancel: function (res) {
//支付取消
}
});
}
});
var isPageHide = false;
window.addEventListener('pageshow', function() {
if(isPageHide) {
window.location.reload();//自己重新刷新,这一步相当于模拟了跳转
}
});
window.addEventListener('pagehide', function() {
isPageHide = true;
});
}对应后台代码:
public String getIp(HttpServletRequest request) {
String ip = request.getHeader("x-forwarded-for");
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
}
return ip;
}
/**
* @param mapping
* @param form
* @param request
* @param response
* @return
*/
public ActionForward getWxPaySign(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response){
String code = request.getParameter("code") ;
BlsWXPayConfig wxPayConfig = new BlsWXPayConfig();
String key = wxPayConfig.getKey();//32位apiKey
String nonceStr = WXPayUtil.generateNonceStr();
String notify_url = wxPayConfig.getNotifyUrl();//支付结果回调地址,不能带参数(PayNotifyUrl回调里能接到订单号out_trade_no参数)
String out_trade_no = request.getParameter("orderNumber");//订单号
String spbill_create_ip = getIp(request);//用户端IP
String trade_type = "JSAPI";//JSAPI,NATIVE,APP,WAP
//#region 获取用户微信OpenId
String openidExt = null;
try {
Map<String, String> reqData = new TreeMap<String, String>();
openidExt = PayCommonUtil.getOpenId(code, wxPayConfig);
//#region 调用统一支付接口获得prepay_id(预支付交易会话标识)
reqData.put("appid", wxPayConfig.getAppID());
reqData.put("mch_id", wxPayConfig.getMchID());
reqData.put("nonce_str", nonceStr);
reqData.put("body", out_trade_no);// + " 购货金额");
reqData.put("out_trade_no", out_trade_no);
String total_fee = request.getParameter("total_fee");
int total_fee_int = new BigDecimal(Double.parseDouble(total_fee) * 100).setScale(2, RoundingMode.HALF_UP).intValue();//
reqData.put("total_fee", String.valueOf(total_fee_int));//单位为分
reqData.put("spbill_create_ip", spbill_create_ip);
reqData.put("notify_url", notify_url);
reqData.put("trade_type", trade_type);
String attach = request.getParameter("orderId");//附加数据:订单id
reqData.put("attach", attach);
reqData.put("openid", openidExt);
String sign = WXPayUtil.generateSignature(reqData, key);
reqData.put("sign", sign);
WxAuthPros wxAuth = PayCommonUtil.unifiedorder(PayCommonUtil.getxml(reqData));
String prepay_id = wxAuth.getPrepay_id();
//#endregion
long timestamp = WXPayUtil.getCurrentTimestamp();
Map<String, String> paySignMap = new TreeMap<String, String>();
paySignMap.put("appId", wxPayConfig.getAppID());
paySignMap.put("nonceStr", nonceStr);
paySignMap.put("package", "prepay_id=" + prepay_id);
paySignMap.put("signType", "MD5");
paySignMap.put("timeStamp", String.valueOf(timestamp));
String paySign = WXPayUtil.generateSignature(paySignMap, key);
JSONObject resData = new JSONObject();
resData.put("openid", openidExt);
resData.put("appId", wxPayConfig.getAppID());
resData.put("timeStamp", WXPayUtil.getCurrentTimestamp());
resData.put("nonceStr", nonceStr);
resData.put("package", "prepay_id=" + prepay_id);
resData.put("signType", "MD5");
resData.put("sign", sign);
resData.put("paysign", paySign);
resData.put("openid", openidExt);
resData.put("result_code", wxAuth.getResult_code());
resData.put("return_msg", wxAuth.getReturn_msg());
//#endregion
super.responseWrite(response, resData.toString());
} catch (Exception e) {
LOG.error("获取微信支付签名异常", e);
}
return null;
}工具类:PayCommonUtil
public class PayCommonUtil {
private static String OPENIDURL = "https://api.weixin.qq.com/sns/oauth2/access_token?"; // 获取微信openid的链接
private static String UNURL = "https://api.mch.weixin.qq.com/pay/unifiedorder"; // 微信统一下单链接
/**
* ** 接收微信的异步通知
*
* @throws IOException
*/
public static String reciverWx(HttpServletRequest request)
throws IOException {
InputStream inputStream;
StringBuffer sb = new StringBuffer();
inputStream = request.getInputStream();
String s;
BufferedReader in = new BufferedReader(new InputStreamReader(
inputStream, "UTF-8"));
while ((s = in.readLine()) != null) {
sb.append(s);
}
in.close();
inputStream.close();
return sb.toString();
}
/**
* 获取openId
* @param code
* @param config
* @return
*/
public static String getOpenId(String code, BlsWXPayConfig config) {
String openIdUrl = OPENIDURL + "appid=" + config.getAppID()
+ "&secret=" + config.getAppSecret() + "&code=" + code
+ "&grant_type=authorization_code";
try {
HttpRequest request = HttpRequest.post(openIdUrl).contentType(
"application/json;charset=utf-8");
String res = request.body();
if (res != null) {
WxAuthPros wxAuth = JsonUtils.fromJson(res, WxAuthPros.class);
return wxAuth.getOpenid();
}
return null;
} catch (Exception e) {
return null;
}
}
//组装统一下订单参数并进行签名
public static String getxml(Map<String, String> reqData){
StringBuilder returnXml = new StringBuilder();
try {
returnXml.append("<xml>");
returnXml.append("<appid>").append(reqData.get("appid")).append("</appid>");
returnXml.append("<mch_id>").append( reqData.get("mch_id")).append("</mch_id>");
returnXml.append("<nonce_str>").append(reqData.get("nonce_str")).append("</nonce_str>");
returnXml.append("<body>").append(reqData.get("body")).append("</body>");
returnXml.append("<out_trade_no>").append(reqData.get("out_trade_no")).append("</out_trade_no>");
returnXml.append("<total_fee>").append(reqData.get("total_fee")).append("</total_fee>");
returnXml.append("<spbill_create_ip>").append(reqData.get("spbill_create_ip")).append("</spbill_create_ip>");
returnXml.append("<notify_url>").append(reqData.get("notify_url")).append("</notify_url>");
returnXml.append("<trade_type>").append(reqData.get("trade_type")).append("</trade_type>" );
if(reqData.containsKey("product_id")){
returnXml.append("<product_id>").append(reqData.get("product_id")).append("</product_id>" );
}
returnXml.append("<attach>").append(reqData.get("attach")).append("</attach>");
if(reqData.containsKey("openid")){
returnXml.append("<openid>").append(reqData.get("openid")).append("</openid>");
}
returnXml.append("<sign>").append(reqData.get("sign")).append("</sign>");
returnXml.append("</xml>");
} catch (Exception e) {
}
return returnXml.toString();
}
// 调用微信统一下单接口
public static WxAuthPros unifiedorder(String xml){
String returnxml=null;
WxAuthPros wxAuth = new WxAuthPros();
try {
HttpRequest request = HttpRequest.post(UNURL).contentType( "application/json;charset=utf-8").send(xml);
returnxml = request.body();
// System.out.println("-------------------------------------------");
// System.out.println(xml);
// System.out.println("++++++++++++++++++++++++++++++++++++++++++++");
// System.out.println(returnxml);
// System.out.println("-------------------------------------------");
Document doc = DocumentHelper.parseText(returnxml);
Element rootElt = doc.getRootElement(); // 获取根节点
wxAuth.setPrepay_id(rootElt.elementText("prepay_id"));
wxAuth.setResult_code(rootElt.elementText("result_code"));
wxAuth.setErr_code(rootElt.elementText("err_code"));
wxAuth.setErr_code(rootElt.elementText("err_code"));
wxAuth.setErr_code_des(rootElt.elementText("err_code_des"));
wxAuth.setReturn_msg(rootElt.elementText("return_msg"));
wxAuth.setCode_url(rootElt.elementText("code_url"));
wxAuth.setMweb_url(rootElt.elementText("mweb_url"));
} catch (Exception e) {
}
return wxAuth;
}
/** 获取二维码url
* @param ip
* @param vcWeixinPay
* @return
* @throws Exception
*/
private static WxAuthPros weixin_pay(String ip,
String attach, String out_trade_no, Double totalPrice,
BlsWXPayConfig wxPayConfig,
String trade_type) throws Exception {
String key = wxPayConfig.getKey(); // key
String nonce_str = WXPayUtil.generateNonceStr();
// 获取发起电脑 ip
String spbill_create_ip = ip;
Map<String, String> reqData = new TreeMap<String, String>();
//#endregion
//#region 调用统一支付接口获得prepay_id(预支付交易会话标识)
reqData.put("appid", wxPayConfig.getAppID());
reqData.put("mch_id", wxPayConfig.getMchID());
reqData.put("nonce_str", nonce_str);
reqData.put("body", out_trade_no);// + " 购货金额");
reqData.put("out_trade_no", out_trade_no);
int total_fee_int = new BigDecimal(totalPrice * 100).setScale(2, RoundingMode.HALF_UP).intValue();//
reqData.put("total_fee", String.valueOf(total_fee_int));//单位为分
reqData.put("spbill_create_ip", spbill_create_ip);
reqData.put("notify_url", wxPayConfig.getNotifyUrl());
reqData.put("trade_type", trade_type);
reqData.put("product_id", attach);//trade_type = NATIVE 时,必填
reqData.put("attach", attach);
String sign = WXPayUtil.generateSignature(reqData, key);
reqData.put("sign", sign);
WxAuthPros wxAuth = PayCommonUtil.unifiedorder(PayCommonUtil.getxml(reqData));
return wxAuth;
}
/** 网页二维码扫码支付
* @param ip
* @param attach
* @param out_trade_no
* @param totalPrice
* @param wxPayConfig
* @return
* @throws Exception
*/
public static WxAuthPros weixin_payByQrcode(String ip,
String attach, String out_trade_no, Double totalPrice,
BlsWXPayConfig wxPayConfig) throws Exception {
return weixin_pay(ip, attach, out_trade_no, totalPrice, wxPayConfig, "NATIVE");
}
/** 网页二维码扫码支付
* @param ip
* @param attach
* @param out_trade_no
* @param totalPrice
* @param wxPayConfig
* @return
* @throws Exception
*/
public static WxAuthPros weixin_payByH5(String ip,
String attach, String out_trade_no, Double totalPrice,
BlsWXPayConfig wxPayConfig) throws Exception {
return weixin_pay(ip, attach, out_trade_no, totalPrice, wxPayConfig, "MWEB");
}5、扫码支付:用户点击按钮提交参数到后台,后台调用微信支付生成二维码链接内容,前台显示二维码,用户扫码支付,前台轮训后台是否支付成功。
后台代码:
/**
* 订单列表点击 微信支付
* @param mapping
* @param form
* @param request
* @param response
* @return
*/
public ActionForward wxpay(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response){
String ip = super.getIp(request);
BlsWXPayConfig wxPayConfig = new BlsWXPayConfig();
WxAuthPros wxAuthPros;
try {
wxAuthPros = PayCommonUtil.weixin_payByQrcode(
ip == null ? "" : ip.toString(),
request.getParameter("orderId"),
request.getParameter("orderNumber"),
Double.parseDouble(request.getParameter("tenantOrderFee")),
wxPayConfig);
request.setAttribute("wxAuthPros", wxAuthPros);
request.setAttribute("orderId", request.getParameter("ordId"));
request.getRequestDispatcher("order/weixinPay.jsp").forward(
request, response);
} catch (Exception e) {
LOG.error("调用微信支付 异常", e);;
}
return null;
}jsp 代码,显示二维码<%
com.wxpay.sdk.WxAuthPros wxAuthPros = (com.wxpay.sdk.WxAuthPros)request.getAttribute("wxAuthPros");
%>
<div style="padding: 30px;text-align: center;">
<div id="qrcode" urlText="<%=wxAuthPros.getCode_url() %>"
orderId="<%=request.getAttribute("orderId") %>"
errorMsg="<%=wxAuthPros.getReturn_msg() %>">
</div>
<div style="line-height: 30px;font-size: 16px;">
请使用微信扫码,完成支付。
</div>
</div> Js代码, 显示二维码使用jquery.qrcode方式$(function(){
var urlText = $('#qrcode').attr("urlText");
$('#qrcode').qrcode({
render: "canvas", //也可以替换为table
width: 200,
height: 200,
text: urlText
});
if(urlText != "null"){
setInterval(function(){
$.ajax({
url : "/xxx/vlidateWxPay",
data : {
orderId : $('#qrcode').attr("orderId")
},
success: function(res){
if(res == "true"){
alert("恭喜,支付成功!点击确定跳转至“我的订单”页面");
//支付成功 跳转到我的订单页面
window.location.href = "/xxx/order.html";
}
}
});
}, 1000);
}
}); 6、H5支付,用户点击按钮触发支付,请求后台得到微信统一下单H5支付链接,前台跳转到微信支付链接,支付成功,微信请求回调页面(如果为app端唤起微信支付,返回后需轮询后台验证是否支付成功)JS代码:
/**
* 微信外浏览器唤起微信支付
* */
function startWxH5Pay(){
$.ajax({
type: "POST",
url: "/xxx/order/getWxH5Url",
data: {
"orderId" : $("#ordId").val(),
"orderNumber" : $("#orderNumber").val(),
"total_fee" : $("#ototalPrice").val()
},
dataType:"json",
beforeSend: function () {
$("#xxx").attr({ "disabled": "disabled" });
},
success: function (res) {
if(res && res.mweb_url){
//弹出提示框
mui("#payModal").popover("show", this);
$("#payCancel").on("click", function(){
mui("#payModal").popover("hide", this);
});
$("#payComplate").on("click", function(){
mui("#payModal").popover("hide", this);
setInterval(function(){
$.ajax({
url : "/xxx/order/vlidateWxPay",
data : {
orderId : $("#ordId").val()
},
success: function(res){
if(res == "true"){
alert("恭喜,支付成功!点击确定跳转至“我的订单”页面");
//支付成功 跳转到我的订单页面
window.location.href = "/xxx/order.html";
}
}
});
}, 1000);
});
window.location.href = res.mweb_url;
}
}
});
} 对应后台代码:/**
* 手机端:微信外浏览器h5支付
* @param mapping
* @param form
* @param request
* @param response
* @return
*/
public ActionForward getWxH5Url(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response){
String ip = super.getIp(request);
BlsWXPayConfig wxPayConfig = new BlsWXPayConfig();
WxAuthPros wxAuthPros;
try {
wxAuthPros = PayCommonUtil.weixin_payByH5(
ip == null ? "" : ip.toString(),
request.getParameter("orderId"),
request.getParameter("orderNumber"),
Double.parseDouble(request.getParameter("total_fee")),
wxPayConfig);
super.responseWrite(response, new JSONObject(wxAuthPros));
} catch (Exception e) {
LOG.error("调用微信支付 异常", e);;
}
return null;
} 以上为微信支付的几种代码调用方式,回调代码如下(由于回调不能写参数,所有暂时使用的jsp代码)
<!-- 该引入的要引入 -->
<%@page import="java.io.PrintWriter"%>
<%@page import="org.springframework.web.context.WebApplicationContext" %>
<%@page import="org.springframework.web.context.support.WebApplicationContextUtils" %>
<%@page import="com.xxx.moder.BlsWxPayInfo" %>
<%@page import="com.wxpay.sdk.WXPayUtil" %>
<%@page import="com.wxpay.sdk.PayCommonUtil" %>
<%@page import="java.util.Map" %>
<%@page import="java.util.List" %>
<%@page import="java.util.HashMap" %>
<%@page import="java.util.TreeMap" %>
<%@page import="java.util.SortedMap" %>
<%@page import="java.util.Iterator" %>
<%@page import="java.io.BufferedOutputStream" %>
<%@page import="org.dom4j.DocumentHelper" %>
<%@page import="org.dom4j.Document" %>
<%@page import="org.dom4j.Element" %>
<%
WebApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(this.getServletContext());
com.xxx.service.OrderService orderService = (com.xxx.service.OrderService) ctx.getBean("OrderService");
//orderService.
String result = PayCommonUtil.reciverWx(request); // 接收到异步的参数
Map<String, String> m = new TreeMap<String, String>();// 解析xml成map
if (result != null && !"".equals(result)) {
try {
Document doc = DocumentHelper.parseText(result);
Element rootElt = doc.getRootElement(); // 获取根节点
List<Element> child = rootElt.elements();
for(Element e : child){
m.put(e.getName(), e.getText());
}
} catch (Exception e) {
e.printStackTrace();
}
}
// 判断签名是否正确
String resXml = "";
if(WXPayUtil.isSignatureValid(m, "Blissunnnnnnnnnnnnnnnnnnnnnnnnnn")){
if ("SUCCESS".equals((String) m.get("result_code"))) {
// 如果返回成功
String mch_id = (String) m.get("mch_id"); // 商户号
String out_trade_no = (String) m.get("out_trade_no"); // 商户订单号
String total_fee = (String) m.get("total_fee");
String transaction_id = (String) m.get("transaction_id"); // 微信支付订单号
String attach = (String) m.get("attach"); // 微信支付订单号
BlsWxPayInfo blsWxPayInfo = new BlsWxPayInfo();
blsWxPayInfo.setMch_id(mch_id);
blsWxPayInfo.setOut_trade_no(out_trade_no);
blsWxPayInfo.setTotal_fee(Double.parseDouble(total_fee));
blsWxPayInfo.setTransaction_id(transaction_id);
blsWxPayInfo.setDevice_info((String)m.get("device_info"));
blsWxPayInfo.setNonce_str((String)m.get("nonce_str"));
blsWxPayInfo.setSign((String)m.get("sign"));
blsWxPayInfo.setResult_code((String)m.get("result_code"));
blsWxPayInfo.setTrade_type((String)m.get("trade_type"));
blsWxPayInfo.setAttach((String)m.get("attach"));
orderService.saveBlsWxPayInfo(blsWxPayInfo);
resXml = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>"
+ "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> ";
} else {// 如果微信返回支付失败,将错误信息返回给微信
resXml = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>"
+ "<return_msg><![CDATA[交易失败]]></return_msg>" + "</xml> ";
}
} else {
resXml = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>"
+ "<return_msg><![CDATA[通知签名验证失败]]></return_msg>" + "</xml> ";
}
// 处理业务完毕,将业务结果通知给微信
// ------------------------------
try{
BufferedOutputStream outStream = new BufferedOutputStream(response.getOutputStream());
outStream.write(resXml.getBytes());
outStream.flush();
outStream.close();
}catch(Exception e){
}
%>至此已完成微信支付的几种代码的编写,开始的时候老是提示签名错误,微信签名一定要注意参数的名称及顺序(为了保证顺序请使用TreeMap),还有公众号支付时需要二次签名,签名的 参数值不能为空,trade_type=NATIVE时product_id必填,trade_type=JSAPI时openid必填。