1.前端 index.html
<%@page import="com.tenpay.configure.WxPayConfig"%>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<html>
<style>
#fukuan{
font-size: 50px;
margin-top: 450px;
}
.amount{
width: 400px;
height: 80px;
font-size: 50px;
text-align: center;
}
#shouquan {
display: inline-block;
width: 600px;
height: 120px;
border-radius: 30px;
font-size: 55px;
background-color: #00bbff;
color: white;
line-height: 120px;
margin-top: 100px;
}
</style>
<body>
<div style="text-align: center;margin-top:50px;">
<h3>
<!-- redirect_uri:是你自己的,主要要url编码
state:可以是任意参数,我一般理解为商品id,你在后台WxPayAction中可以获取到,在到数据库中查询商品详细信息,我写死是1000000
scope: snsapi_userinfo(用户有感知,需用户点击授权) snsapi_base(默认授权)
-->
<div id="fukuan">
付款金额:<input type="text" name="amount" class="amount"> 元
</div>
<h1>
<div id="shouquan">
授权支付
</div>
</h1>
</h3>
</div>
</body>
</html>
<script type="text/javascript" src="${pageContext.request.contextPath }/resources/jquery-1.9.0.min.js"></script>
<script type="text/javascript">
$(function(){
$(document).on("click","#shouquan",function(){
var price = $("input[name='amount']").val();
alert("付款金额====="+price);
location="https://open.weixin.qq.com/connect/oauth2/authorize?appid=<%=WxPayConfig.APP_ID %>&redirect_uri=<%=WxPayConfig.REDIRECT_URI %>&response_type=code&scope=snsapi_userinfo&state="+price+"#wechat_redirect";
})
})
</script>
2.前端 pay.html
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<%
String appId = (String)request.getAttribute("appId");
String timeStamp = (String)request.getAttribute("timeStamp");
String nonceStr = (String)request.getAttribute("nonceStr");
String _package = (String)request.getAttribute("package");
String signType = (String)request.getAttribute("signType");
String paySign = (String)request.getAttribute("paySign");
String totalFee = (String)request.getAttribute("totalFee");
%>
<script type="text/javascript">
function callpay()
{
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();
}
}
function onBridgeReady() {
alert("appId=<%=appId %>,timeStamp=<%=timeStamp %>,nonceStr=<%=nonceStr %>,package=<%=_package %>,signType=<%=signType %>,paySign=<%=paySign %>");
WeixinJSBridge.invoke('getBrandWCPayRequest', {
"appId" : "<%=appId %>",
"timeStamp" : "<%=timeStamp %>",
"nonceStr" : "<%=nonceStr %>",
"package" : "<%=_package %>",
"signType" : "<%=signType %>",
"paySign" : "<%=paySign %>"
}, function(res) {
if (res.err_msg == "get_brand_wcpay_request:ok") {
location="https://www.appbi.com/wechat/";
}
if (res.err_msg == "get_brand_wcpay_request:cancel") {
alert("交易取消");
}
if (res.err_msg == "get_brand_wcpay_request:fail") {
alert("支付失败");
}
});
}
</script>
</head>
<style>
#price{
width:100%;
font-size: 50px;
text-align: center;
margin-top: 400px;
margin-bottom: 100px;
}
</style>
<body>
<div id="price"><span style="font-size: 50px;color:red;font-weight: 900;"><%=totalFee %></span> 元 </div>
<div style="text-align: center;margin-top: 50px;"><h1><button type="button" style="display:inline-block;width:600px;height:200px;border-radius:30px; background-color: #00bbff;font-size:50px" onclick="callpay()">确认支付</button></h1></div>
</body>
</html>
3. 前端 notify.html
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>恭喜你,支付成功</title>
</head>
<body>
<div style="text-align:center;">
<h1>...恭喜你,支付成功...</h1>
<h3><a href="https://www.appbi.com/wechat/">跳回首页</a></h3>
</div>
</body>
</html>
4.后台配置
package com.tenpay.configure;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
public class WxPayConfig {
public static String APP_ID = "wx9b4ab423461b9";
public static String APP_SECRET = "668d58d15703cf09d3ad8da996";
public static String MCH_ID = "16079885";
public static String KEY = "shanghaishuzikeji123456";
public static String NOTIFY_URL = "https://www.appbi.com/wechat/v_3/notify.html";
public static String CHARTSET = "UTF-8";
public static String SIGN_TYPE = "MD5";
public static String REDIRECT_URI;
static {
try {
REDIRECT_URI = URLEncoder.encode("http://www.appbi.com/wechat/v_3/pay", CHARTSET);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
}
5.后台业务逻辑
package com.tenpay.action;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.jdom2.JDOMException;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import com.tenpay.RequestHandler;
import com.tenpay.configure.WxPayConfig;
import com.tenpay.service.ServiceUtil;
import com.tenpay.util.MD5Util;
import com.tenpay.util.Sha1Util;
import com.tenpay.util.XMLUtil;
import net.sf.json.JSONObject;
@Controller
@RequestMapping("/v_3")
public class WxPayAction {
@RequestMapping("pay")
public String order(HttpServletRequest request, HttpServletResponse response,
@RequestParam(value="code",required=false) String code,
@RequestParam(value="state",required=false) Double state
) throws Exception {
System.out.println("code=" + code + ",state=" + state);
String openid = ServiceUtil.getOpenId(code);
String noncestr = Sha1Util.getNonceStr();
String timestamp = Sha1Util.getTimeStamp();
String out_trade_no = "NO" + System.currentTimeMillis() + "0001";
BigDecimal a1 = new BigDecimal(String.valueOf(state));
BigDecimal b1 = new BigDecimal(String.valueOf(100));
Integer resultState = a1.multiply(b1).intValue();
String order_price = String.valueOf(resultState);
String body = "商品描述,测试....";
RequestHandler reqHandler = new RequestHandler(request, response);
reqHandler.init();
reqHandler.setParameter("appid", WxPayConfig.APP_ID);
reqHandler.setParameter("mch_id", WxPayConfig.MCH_ID);
reqHandler.setParameter("device_info", "WEB");
reqHandler.setParameter("nonce_str", noncestr);
reqHandler.setParameter("body", body);
reqHandler.setParameter("out_trade_no", out_trade_no);
reqHandler.setParameter("total_fee", order_price);
reqHandler.setParameter("spbill_create_ip", "123.57.58.123");
reqHandler.setParameter("notify_url", WxPayConfig.NOTIFY_URL);
reqHandler.setParameter("trade_type", "JSAPI");
reqHandler.setParameter("openid", openid);
String requestXml = reqHandler.getRequestXml();
System.out.println("requestXml:" + requestXml);
String prepay_id = ServiceUtil.unifiedorder(requestXml);
SortedMap<String, String> params = new TreeMap<String, String>();
params.put("appId", WxPayConfig.APP_ID);
params.put("timeStamp", timestamp);
params.put("nonceStr", noncestr);
params.put("package", "prepay_id=" + prepay_id);
params.put("signType", "MD5");
System.out.println("params:" + JSONObject.fromObject(params).toString());
SortedMap<Object,Object> signMap = new TreeMap<Object,Object>();
signMap.put("appId", WxPayConfig.APP_ID);
signMap.put("timeStamp", timestamp);
signMap.put("nonceStr", noncestr);
signMap.put("package", "prepay_id=" + prepay_id);
signMap.put("signType", "MD5");
String paySign = MD5Util.createSign(signMap, WxPayConfig.KEY);
System.out.println("PaySIGN:" + paySign);
request.setAttribute("appId", WxPayConfig.APP_ID);
request.setAttribute("timeStamp", timestamp);
request.setAttribute("nonceStr", noncestr);
request.setAttribute("package", "prepay_id=" + prepay_id);
request.setAttribute("signType", WxPayConfig.SIGN_TYPE);
request.setAttribute("paySign", paySign);
request.setAttribute("totalFee", state.toString());
return "pay";
}
@RequestMapping("notify")
public String notify(HttpServletRequest request, HttpServletResponse response) {
try {
InputStream inStream = request.getInputStream();
ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len = 0;
while ((len = inStream.read(buffer)) != -1) {
outSteam.write(buffer, 0, len);
}
outSteam.close();
inStream.close();
String resultStr = new String(outSteam.toByteArray(), WxPayConfig.CHARTSET);
Map<String, String> resultMap = XMLUtil.doXMLParse(resultStr);
System.out.println("微信回调结果:" + resultMap.toString());
String result_code = resultMap.get("result_code");
String is_subscribe = resultMap.get("is_subscribe");
String out_trade_no = resultMap.get("out_trade_no");
String transaction_id = resultMap.get("transaction_id");
String sign = resultMap.get("sign");
String time_end = resultMap.get("time_end");
String bank_type = resultMap.get("bank_type");
String return_code = resultMap.get("return_code");
if (return_code.equals("SUCCESS")) {
}
request.setAttribute("out_trade_no", out_trade_no);
response.getWriter().write(RequestHandler.setXML("SUCCESS", ""));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (JDOMException e) {
e.printStackTrace();
}
return "notify";
}
}
6. 上述需要源码插件的链接地址
项目demo参考: https://download.csdn.net/download/qq_39951524/88146803