枭鹞
枭鹞
  • 发布:2017-07-30 15:48
  • 更新:2017-07-30 15:48
  • 阅读:5827

纯jsp实现微信支付,无需Java程序,完整绿色版复制即可用!

分类:HTML5+

本代码优点:无需依赖java程序,两个jsp文件走天下,方便多个项目复制使用,完整绿色无污染!

吐槽一下腾讯,给的示例代码太复杂不好调试,直接给个简单能跑通的多好,先能跑通再加复杂逻辑才是王道!

1、先要有微信开放平台的账号,并创建应用,审核通过。并且获取微信支付能力。
2、创建应用在填写Android的签名的时候要去掉冒号,并且小写(备注: 签名是用的md5 )
3、微信支付,一定要打包为apk 格式的文件,并且需要用到自己的keystore证书
4、打包好的apk文件,安装在手机测试

废话不多说,上代码:

1、HBuilder端js代码,放个按钮调用doWxPay()方法即可:

  
var channels = null;            
mui.plusReady(function() {  
	// 获取支付通道  
	plus.payment.getChannels(function(cs) {  
		channels = cs;  
	}, function(e) {  
		alert("获取支付通道失败:" + e.message);  
	});				  
});  
  
var w=null;  
function doWxPay() {  
	if (w) return;   
 	w = plus.nativeUI.showWaiting();  
	//获取支付通道  
	var channel;  
	for(var i in channels) {  
		if(channels[i].id == "wxpay") {  
			channel = channels[i];  
		}  
	}  
	mui.ajax('http://www.mywebsitexxx.com/pay_wx.jsp', {  
		data: {  
			total: "1", //支付金额1分  
			body: "Test", //支付界面标题  
			out_trade_no: "123456789"  //订单编号  
		},  
		type: 'post',  
		dataType: 'text',  
		timeout:20000,  
		success: function(data) {  
			w.close();  
			w = null;  
			data=data.replace(/\r\n/g,"").trim();  
			console.log(data);  
			plus.payment.request(channel, data, saveSuccess, saveFail);  
		},  
		error: function(xhr, errorType, error) {  
			w.close();  
			w = null;  
			alert(" error:"+error);  
		}  
	});  
}  
  
function saveSuccess(){  
	mui.toast("支付成功!");	  
}  
  
function saveFail(error){  
	alert("支付失败!"+JSON.stringify(error));  
}  

2、服务端jsp代码pay_wx.jsp,放在网站根目录:

  
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>  
<%@page import="java.util.*"%>  
<%@page import="java.io.*"%>  
<%@page import="org.w3c.dom.*"%>  
<%@page import="javax.xml.parsers.*"%>  
<%@page import="javax.xml.transform.stream.*"%>  
<%@page import="javax.xml.transform.*"%>  
<%@page import="javax.xml.transform.dom.*"%>  
<%@page import="java.security.MessageDigest"%>  
<%@page import="org.apache.http.util.EntityUtils"%>  
<%@page import="org.apache.http.client.HttpClient"%>  
<%@page import="org.apache.http.*"%>  
<%@page import="org.apache.http.entity.StringEntity"%>  
<%@page import="org.apache.http.client.config.RequestConfig"%>  
<%@page import="org.apache.http.client.methods.HttpPost"%>  
<%@page import="org.apache.http.impl.client.HttpClientBuilder"%>  
<%@page import="org.apache.http.conn.ssl.SSLConnectionSocketFactory"%>  
<%@page import="org.apache.http.conn.socket.PlainConnectionSocketFactory"%>  
<%@page import="org.apache.http.conn.socket.ConnectionSocketFactory"%>  
<%@page import="org.apache.http.config.RegistryBuilder"%>  
<%@page import="org.apache.http.impl.conn.BasicHttpClientConnectionManager"%>  
<%!  
public static String AppID="wxea521866668888";//  
public static String MchID="13866668888";//商户id  
public static String Key="UNaaaaabbbb87349866668888";//支付秘钥key  
public String httpsPost(String url, String data) throws Exception {  
	BasicHttpClientConnectionManager connManager = new BasicHttpClientConnectionManager(  
                RegistryBuilder.<ConnectionSocketFactory>create()  
                        .register("http", PlainConnectionSocketFactory.getSocketFactory())  
                        .register("https", SSLConnectionSocketFactory.getSocketFactory())  
                        .build(),  
                null,  
                null,  
                null  
        );  
  
    HttpClient httpClient = HttpClientBuilder.create()  
            .setConnectionManager(connManager)  
            .build();  
  
    HttpPost httpPost = new HttpPost(url);  
  
    RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(200000).setConnectTimeout(200000).build();  
    httpPost.setConfig(requestConfig);  
  
    StringEntity postEntity = new StringEntity(data, "UTF-8");  
    httpPost.addHeader("Content-Type", "text/xml");  
    httpPost.setEntity(postEntity);  
  
    HttpResponse httpResponse = httpClient.execute(httpPost);  
    HttpEntity httpEntity = httpResponse.getEntity();  
    return EntityUtils.toString(httpEntity, "UTF-8");  
}  
  
public static String randomStr(int length) {  
    String base = "abcdefghijklmnopqrstuvwxyz0123456789";  
    Random random = new Random();  
    StringBuffer sb = new StringBuffer();  
    for (int i = 0; i < length; i++) {  
        int number = random.nextInt(base.length());  
        sb.append(base.charAt(number));  
    }  
    return sb.toString();  
}  
  
public static String MD5(String data) throws Exception {  
    java.security.MessageDigest md = MessageDigest.getInstance("MD5");  
    byte[] array = md.digest(data.getBytes("UTF-8"));  
    StringBuilder sb = new StringBuilder();  
    for (byte item : array) {  
        sb.append(Integer.toHexString((item & 0xFF) | 0x100).substring(1, 3));  
    }  
    return sb.toString().toUpperCase();  
}  
  
public static String generateSignature(final Map<String, String> data, String key) throws Exception {  
    Set<String> keySet = data.keySet();  
    String[] keyArray = keySet.toArray(new String[keySet.size()]);  
    Arrays.sort(keyArray);  
    StringBuilder sb = new StringBuilder();  
    for (String k : keyArray) {  
    	sb.append(k).append("=").append(data.get(k).trim()).append("&");  
    }  
    sb.append("key=").append(key);  
    return MD5(sb.toString());  
}  
  
public static String mapToXml(Map<String, String> data) throws Exception {  
    DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();  
    DocumentBuilder documentBuilder= documentBuilderFactory.newDocumentBuilder();  
    org.w3c.dom.Document document = documentBuilder.newDocument();  
    org.w3c.dom.Element root = document.createElement("xml");  
    document.appendChild(root);  
    for (String key: data.keySet()) {  
        String value = data.get(key);  
        if (value == null) {  
            value = "";  
        }  
        value = value.trim();  
        org.w3c.dom.Element filed = document.createElement(key);  
        filed.appendChild(document.createTextNode(value));  
        root.appendChild(filed);  
    }  
    TransformerFactory tf = TransformerFactory.newInstance();  
    Transformer transformer = tf.newTransformer();  
    DOMSource source = new DOMSource(document);  
    transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");  
    transformer.setOutputProperty(OutputKeys.INDENT, "yes");  
    StringWriter writer = new StringWriter();  
    StreamResult result = new StreamResult(writer);  
    transformer.transform(source, result);  
    String output = writer.getBuffer().toString(); //.replaceAll("\n|\r", "");  
    try {  
        writer.close();  
    }  
    catch (Exception ex) {  
    }  
    return output;  
}  
public static Map<String, String> xmlToMap(String strXML) throws Exception {  
    try {  
        Map<String, String> data = new HashMap<String, String>();  
        DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();  
        DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();  
        InputStream stream = new ByteArrayInputStream(strXML.getBytes("UTF-8"));  
        org.w3c.dom.Document doc = documentBuilder.parse(stream);  
        doc.getDocumentElement().normalize();  
        NodeList nodeList = doc.getDocumentElement().getChildNodes();  
        for (int idx = 0; idx < nodeList.getLength(); ++idx) {  
            Node node = nodeList.item(idx);  
            if (node.getNodeType() == Node.ELEMENT_NODE) {  
                org.w3c.dom.Element element = (org.w3c.dom.Element) node;  
                data.put(element.getNodeName(), element.getTextContent());  
            }  
        }  
        try {  
            stream.close();  
        } catch (Exception ex) {  
        }  
        return data;  
    } catch (Exception ex) {  
        throw ex;  
    }  
  
}  
%>  
<%  
HashMap<String, String> reqData = new HashMap<String, String>();  
reqData.put("appid", AppID);  
reqData.put("mch_id", MchID);  
reqData.put("body", request.getParameter("body"));// 商品描述  
reqData.put("out_trade_no", request.getParameter("out_trade_no")); // 商户订单号  
reqData.put("total_fee", request.getParameter("total"));//支付金额  
reqData.put("fee_type", "CNY");// 币种  
reqData.put("spbill_create_ip", request.getRemoteAddr());  
reqData.put("notify_url", "http://www.mywebsitexxx.com/webhook_wx.jsp");//微信回调notify页面  
reqData.put("trade_type", "APP");  
reqData.put("nonce_str",randomStr(20));  
String sign = generateSignature(reqData, Key);  
reqData.put("sign", sign);//打包签名		  
String reqBody = mapToXml(reqData);  
String result = httpsPost("https://api.mch.weixin.qq.com/pay/unifiedorder", reqBody);  
//System.out.println(result);  
Map map = xmlToMap(result);  
String prepay_id = (String) map.get("prepay_id");  
String timestamp = String.valueOf(System.currentTimeMillis() / 1000);  
String nonce_str = randomStr(20);  
String str = "appid=" + AppID + "&noncestr=" + nonce_str  
        + "&package=Sign=WXPay" + "&partnerid=" + MchID  
        + "&prepayid=" + prepay_id + "&timestamp=" + timestamp  
        + "&key=" + Key;  
String newSign = MD5(str);  
StringBuffer json = new StringBuffer();  
json.append("{\"appid\":\"");  
json.append(AppID);  
json.append("\",\"noncestr\":\"");  
json.append(nonce_str);  
json.append("\",\"package\":\"");  
json.append("Sign=WXPay");  
json.append("\",\"partnerid\":\"");  
json.append(MchID);  
json.append("\",\"prepayid\":\"");  
json.append(prepay_id);  
json.append("\",\"timestamp\":");  
json.append(timestamp);  
json.append(",\"sign\":\"");  
json.append(newSign);  
json.append("\"}");  
//System.out.println(json.toString());  
out.print(json.toString());  
%>  

3、微信回调notify页面jsp代码webhook_wx.jsp,放在网站根目录:

  
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>  
<%@page import="java.net.HttpURLConnection"%>  
<%@page import="java.net.URL"%>  
<%@page import="java.util.*"%>  
<%@page import="java.io.*"%>  
<%@page import="org.w3c.dom.*"%>  
<%@page import="javax.xml.parsers.*"%>  
<%!  
public static Map<String, String> xmlToMap(String strXML) throws Exception {  
    try {  
        Map<String, String> data = new HashMap<String, String>();  
        DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();  
        DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();  
        InputStream stream = new ByteArrayInputStream(strXML.getBytes("UTF-8"));  
        org.w3c.dom.Document doc = documentBuilder.parse(stream);  
        doc.getDocumentElement().normalize();  
        NodeList nodeList = doc.getDocumentElement().getChildNodes();  
        for (int idx = 0; idx < nodeList.getLength(); ++idx) {  
            Node node = nodeList.item(idx);  
            if (node.getNodeType() == Node.ELEMENT_NODE) {  
                org.w3c.dom.Element element = (org.w3c.dom.Element) node;  
                data.put(element.getNodeName(), element.getTextContent());  
            }  
        }  
        try {  
            stream.close();  
        } catch (Exception ex) {  
        }  
        return data;  
    } catch (Exception ex) {  
        throw ex;  
    }  
}  
%>  
<%  
StringBuffer xmlStr = new StringBuffer();  
String line = null;  
try {  
    request.setCharacterEncoding("utf-8");  
    BufferedReader reader = request.getReader();  
    while ((line = reader.readLine()) != null) {  
    	xmlStr.append(line);  
    }  
} catch (Exception e) {  
    e.printStackTrace();  
}  
System.out.println("微信支付:"+xmlStr);  
Map data = xmlToMap(xmlStr.toString());  
if("SUCCESS".equals(data.get("return_code"))   
		&& "SUCCESS".equals(data.get("result_code"))){  
	Double totalFee = new Double(data.get("total_fee").toString())/100;  
	//TODO:这里加判断逻辑,编写更新订单状态的代码,或直接调用写好的Java类  
	System.out.println(totalFee );  
        out.println("<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>");  
	} catch (Exception e) {  
		e.printStackTrace();  
	}	  
}else{  
	out.println("ERROR");  
}  
%>  
  

完毕,打包apk即可测试。
注:各种依赖jar包还得自行去下载。

1 关注 分享
4***@qq.com

要回复文章请先登录注册

移动达人

移动达人

不错,有php版的有没有? jsp的看不懂,只有用猜了。
2017-07-30 22:07
雪之梦技术驿站

雪之梦技术驿站

火钳留名
2017-07-30 18:45