JSAPI微信支付,这个写法只针对本人仅供参考,
1.获取openID
https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=获取openID方法(该地址需要使用UrlEncode转)&response_type=code&scope=snsapi_base&state=123#wechat_redirect
1.1获取openID代码
code是通过获取openID的时候一起获取的
@RequestMapping(value = "getOpenId")
public String getOpenId(HttpServletRequest request) {
String code = request.getParameter("code");
System.out.println(code);
StringBuffer url = new StringBuffer("https://api.weixin.qq.com/sns/oauth2/access_token");
StringBuffer param = new StringBuffer();
param.append("appid=" + APPID);
param.append("&secret=" + APPSECRET);
param.append("&code=" + code);
param.append("&grant_type=authorization_code");
try {
String info = TestURL.getUserInfo(url.toString(), param.toString());
System.out.println(info);
JSONObject json = JSONObject.parseObject(info);
System.out.println(json);
request.setAttribute("openId", json.getString("openid"));
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return "test";
}
2.通过test.jsp会调用支付接口
2.1我的test.jsp页面还加了一个添加用户信息的操作,操作成功后会调用支付接口
2.2返回的pay是本人自己写的页面和微信官方提供的script
<script type="text/javascript" src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>
<script type="text/javascript">
function pay() {
WeixinJSBridge.invoke(
'getBrandWCPayRequest', ${re}, function(res){
alert(JSON.stringify(res));
if(res.err_msg == "get_brand_wcpay_request:ok" ) {
alert("成功");
$.ajax({
type : 'POST',
url : 'upCertInfo',
data : {'key':'ok'},//手动补充
dataType : 'json',
success : function(result) {
location.href="paySuccess";
},
error : function(r) {
alert('错误');
}
});
//doit 这里处理支付成功后的逻辑,通常为页面跳转
} else {
alert('支付失败');
$.ajax({
type : 'POST',
url : 'upCertInfo',
data : {'key':'fail'},//手动补充
dataType : 'json',
success : function(result) {
},
error : function(r) {
}
});
}
}
);
}
if (typeof WeixinJSBridge == "undefined"){
if( document.addEventListener ){
document.addEventListener('WeixinJSBridgeReady', onBridgeReady, false);
}else if (document.attachEvent){
document.attachEvent('WeixinJSBridgeReady', onBridgeReady);
document.attachEvent('onWeixinJSBridgeReady', onBridgeReady);
}
}else{
onBridgeReady();
}
</script>
2.3支付主接口
@SuppressWarnings("rawtypes")
@RequestMapping("/wxpay")
public String wxpay(HttpSession httpSession, HttpServletRequest request, HttpServletResponse response) {
String openid = request.getParameter("openId");
System.out.println("\n\n<openid>:" + openid + "\n\n");
String trade_no = MD5Util.makeUUID();
String appid = "APPID";// 公众账号ID 天津
String mch_id = "商户ID";// 商户号 天津
String nonce_str = MD5Util.getRandomString(32);// 随机字符串 不长于32位
String body = "EMS";
String out_trade_no = trade_no;// 订单号
String total_fee = "1200";// 订单金额 单位是分
String spbill_create_ip = request.getRemoteAddr();// 用户ip
String notify_url = "http://www.*****.com/WeChatPay/wxpayget";// 回调通知地址
String trade_type = "JSAPI";// 交易类型 JSAPI,写死不动.
String key = "商户秘钥";
SortedMap<Object, Object> parameters = new TreeMap<Object, Object>();
parameters.put("appid", appid);
parameters.put("mch_id", mch_id);
parameters.put("nonce_str", nonce_str);
parameters.put("body", body);
parameters.put("out_trade_no", out_trade_no);
parameters.put("total_fee", total_fee);
parameters.put("spbill_create_ip", spbill_create_ip);
parameters.put("notify_url", notify_url);
parameters.put("trade_type", trade_type);
parameters.put("sign_type", "MD5");
parameters.put("openid", openid);
String characterEncoding = "UTF-8";
String mySign = MD5Util.createSign(characterEncoding, parameters,
key);
System.out.println(mySign);
parameters.put("sign", mySign);
try {
System.out.println(body);
body = new String(body.getBytes("UTF-8"));// 商品描述
System.out.println(body + "=============");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
String param = XMLUtil.getRequestXml(parameters);
System.out.println(param);
PrintWriter out = null;
BufferedReader in = null;
String result = "";
try {
URL realUrl = new URL(
"https://api.mch.weixin.qq.com/pay/unifiedorder");
// 打开和URL之间的连接
URLConnection conn = realUrl.openConnection();
// 设置通用的请求属性
conn.setRequestProperty("accept", "*/*");
conn.setRequestProperty("connection", "Keep-Alive");
conn.setRequestProperty("user-agent",
"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
// 发送POST请求必须设置如下两行
conn.setDoOutput(true);
conn.setDoInput(true);
// 获取URLConnection对象对应的输出流
out = new PrintWriter(conn.getOutputStream());
// 发送请求参数
out.write(param);
// flush输出流的缓冲
out.flush();
// 定义BufferedReader输入流来读取URL的响应
in = new BufferedReader(
new InputStreamReader(conn.getInputStream()));
String line;
while ((line = in.readLine()) != null) {
result += line;
}
System.err.println(result);
} catch (Exception e) {
System.out.println("发送 POST 请求出现异常!" + e);
e.printStackTrace();
}
// 使用finally块来关闭输出流、输入流
finally {
try {
if (out != null) {
out.close();
}
if (in != null) {
in.close();
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
try {
result = new String(result.getBytes(), "UTF-8");
System.out.println(result);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
System.out.println("==============================================");
// System.out.println(result);
try {
Map m = XMLUtil.doXMLParse(result);
System.out.println(m);
String prepay_id = m.get("prepay_id").toString();
SortedMap<Object, Object> para = new TreeMap<Object, Object>();
para.put("appId", APPID);
para.put("nonceStr", MD5Util.getRandomString(32));
para.put("timeStamp", String.valueOf(new Date().getTime()/1000));
para.put("package", "prepay_id=" + prepay_id);
para.put("signType", "MD5");
String sign = MD5Util.createSign(characterEncoding, para, key);
System.out.println("<sign>:" + sign);
para.put("paySign", sign);
String xml = XMLUtil.getRequestXml(para);
System.out.println("\n" + xml + "\n");
System.out.println("参数为:-----------\n" + para);
request.setAttribute("re", JSONObject.toJSON(para));
} catch (JDOMException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return "pay";
}
3.微信回调接口
/**
* 微信回调方法 返回是否支付成功
*
* @param request
* @param response
* @return
*/
@RequestMapping("/wxpayget")
@ResponseBody
public String wxpayget(HttpServletRequest request,
HttpServletResponse response) {
String inputLine = null;
String s = "";
// 接收到的数据
StringBuffer recieveData = new StringBuffer();
BufferedReader in = null;
try {
in = new BufferedReader(new InputStreamReader(
request.getInputStream(), "UTF-8"));
while ((inputLine = in.readLine()) != null) {
recieveData.append(inputLine);
s += inputLine;
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (null != in) {
in.close();
}
} catch (IOException e) {
}
}
try {
param = XMLUtil.doXMLParse(s);
} catch (JDOMException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("/n"+"param-----------------------------"+param);
String openid = (String) param.get("openid");
if (param.get("return_code").toString().equals("SUCCESS")) {
if (param.get("result_code").equals("SUCCESS")) {
String out_trade_no = param.get("out_trade_no").toString();
System.out.println("支付成功"+out_trade_no);
System.out.println("openid----------------------------------"+openid);
}else{
System.out.println("支付取消");
}
return "<xml><return_code><![CDATA[SUCCESS]]></return_code></xml>";
} else {
System.out.println("支付失败");
return "<xml><return_code><![CDATA[FAIL]]></return_code></xml>";
}
}
4.在以上操作的基础上必须设置微信公众号
请参考
https://blog.csdn.net/javaYouCome/article/details/79473743,
https://www.cnblogs.com/cinlap/p/11077632.html
解:域名必须ICP备案,测试用域名的服务器
5.用到的工具类
微信开发调试软件:https://download.csdn.net/download/qq_42703531/11803651
生成XML&MD5算法:https://download.csdn.net/download/qq_42703531/11803683