Java编程调用微信支付功能的方法详解

本文实例讲述了Java编程调用微信支付功能的方法。分享给大家供大家参考,具体如下:

微信开发文档地址:https://mp.weixin.qq.com/wiki/home/

从调用处开始

我的流程: 1.点击“支付”按钮,去后台 ―-> 2.后台生成支付所需数据返回页面 ―-> 3.页面点击“确认支付”调用微信支付js。完成支付功能

支付按钮

<div class="button" id="pay" onclick="payBox()">支付</div>

支付按钮js

function payBox(){

//获得支付的钱数

var money = $(".money input").val();

//后台路径,加上参数

location.href = "/XXX/XXX/XXXX/XXXX?money ="+money;

}

后台方法(例:index())

注释:

getPara( ) == request.getParameter(name);

setAttr( ) == request.setAttribute(name, value);

render() == 我现在所用框架返回页面的一种方法。

首先得OpenId;下面是具体方法。

public String getOpenId(){

String code = getPara("code");

String openid = "";

if (StringUtils.isEmpty(openid) && !StringUtils.isEmpty(code)) {

SnsAccessToken token = SnsAccessTokenApi.getSnsAccessToken("你的APPID","你的appsecret密码",

code);

openid = token.getOpenid();

}

getSession().setAttribute("openandid",openid);

return openid;

}

public void index() throws Exception{

String openid = getOpenId();

//得到金额

String money= getPara("money");

Map<String ,String > map=new HashMap<String,String>();

//获取随机串

String nonceStr=UUID.randomUUID().toString().substring(0, 32);

//可以是支付物品的订单号。一个号码,看自己怎么给

String out_trade_no="123456789";

//支付金额。微信默认支付是(1=0.01)的比例,下面是将金额换算成微信可识别的

BigDecimal re1=new BigDecimal(expressCharge);

BigDecimal re2=new BigDecimal(Float.toString(100.00f));

Float aa = re1.multiply(re2).floatValue();

String total_fee = String.valueOf(aa);

String[] smill = total_fee.split("\\.");

total_fee = smill[0];

//微信的appid

String appid="XXXXXXXXXXXXXXXXX";

String mch_id="XXXXXXXXX";//商户号

String body="xxxxxxx";//商品信息,可以自己起最好写英文

//密匙,商户平台的支付API密匙,注意是商户平台,不是微信平台

String key = "XXXXXXXXXXXXXXXXXXXXXXXXXXXX";

long timestamp = System.currentTimeMillis() / 1000;

map.put("appid", appid );

map.put("mch_id", mch_id);

map.put("nonce_str",nonceStr);

map.put("body", body);

map.put("out_trade_no", out_trade_no);

map.put("total_fee", total_fee);

map.put("spbill_create_ip",getRequest().getRemoteAddr());

//这里是支付成功后返回的地址,微信会以XML形式放回数据,就是本篇文章的下一类(例:wxxml())方法名。

map.put("notify_url", "http://www.XXXX.com/XXXX/XXXX/xxxx/wxxml");

map.put("trade_type", "JSAPI");

map.put("openid", openid);//传入OpenId

//这里传入Map集合和key商户支付密匙

String paySign=getPayCustomSign(map,key);

map.put("sign",paySign);

//将map转为XML格式

String xml= ArrayToXml(map);

//统一下单,这里不用改

String url = "https://api.mch.weixin.qq.com/pay/unifiedorder";

String xmlStr = HttpKit.post(url, xml);

//prepayid由微信返回的 。

String prepayid = "";

if (xmlStr.indexOf("SUCCESS") != -1) {

Map<String, String> map2 = doXMLParse(xmlStr);

prepayid = (String) map2.get("prepay_id");

}

String paySign2=getPayCustomSign(signMap,key);

setAttr("model", model);

setAttr("appId", appid);

setAttr("paytimestamp", String.valueOf(timestamp));

setAttr("paynonceStr", nonceStr);

setAttr("paypackage", "prepay_id="+prepayid);

setAttr("paysignType","MD5");

setAttr("paySign", paySign2);

//去到确认支付页面,返回页面方式不同,(例:pay.html页面),下面

render("/XXXX/pay.html");

}

/**

* 获取支付所需签名

* @param ticket

* @param timeStamp

* @param card_id

* @param code

* @return

* @throws Exception

*/

public static String getPayCustomSign(Map<String, String> bizObj,String key) throws Exception {

String bizString = FormatBizQueryParaMap(bizObj, false);

return sign(bizString, key);

}

/**

* 字典排序

* @param paraMap

* @param urlencode

* @return

* @throws Exception

*/

public static String FormatBizQueryParaMap(Map<String, String> paraMap,

boolean urlencode) throws Exception {

String buff = "";

try {

List<Map.Entry<String, String>> infoIds = new ArrayList<Map.Entry<String, String>>(paraMap.entrySet());

Collections.sort(infoIds,

new Comparator<Map.Entry<String, String>>() {

public int compare(Map.Entry<String, String> o1,

Map.Entry<String, String> o2) {

return (o1.getKey()).toString().compareTo(

o2.getKey());

}

});

for (int i = 0; i < infoIds.size(); i++) {

Map.Entry<String, String> item = infoIds.get(i);

//System.out.println(item.getKey());

if (item.getKey() != "") {

String key = item.getKey();

String val = item.getValue();

if (urlencode) {

val = URLEncoder.encode(val, "utf-8");

}

buff += key + "=" + val + "&";

}

}

if (buff.isEmpty() == false) {

buff = buff.substring(0, buff.length() - 1);

}

} catch (Exception e) {

throw new Exception(e.getMessage());

}

return buff;

}

//支付所需签名处调用此方法

public static String sign(String content, String key)

throws Exception{

String signStr = "";

signStr = content + "&key=" + key;

return MD5(signStr).toUpperCase();

}

//上一方法,MD5加密处理

public final static String MD5(String s) {

char hexDigits[]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};

try {

byte[] btInput = s.getBytes();

MessageDigest mdInst = MessageDigest.getInstance("MD5");

mdInst.update(btInput);

byte[] md = mdInst.digest();

int j = md.length;

char str[] = new char[j * 2];

int k = 0;

for (int i = 0; i < j; i++) {

byte byte0 = md[i];

str[k++] = hexDigits[byte0 >>> 4 & 0xf];

str[k++] = hexDigits[byte0 & 0xf];

}

return new String(str);

} catch (Exception e) {

e.printStackTrace();

return null;

}

}

//转为XML格式

public static String ArrayToXml(Map<String, String> arr) {

String xml = "<xml>";

Iterator<Entry<String, String>> iter = arr.entrySet().iterator();

while (iter.hasNext()) {

Entry<String, String> entry = iter.next();

String key = entry.getKey();

String val = entry.getValue();

if (IsNumeric(val)) {

xml += "<" + key + ">" + val + "</" + key + ">";

} else

xml += "<" + key + "><![CDATA[" + val + "]]></" + key + ">";

}

xml += "</xml>";

return xml;

}

public static boolean IsNumeric(String str) {

if (str.matches("\\d *")) {

return true;

} else {

return false;

}

}

//解析XML

private Map<String, String> doXMLParse(String xml)

throws XmlPullParserException, IOException {

InputStream inputStream = new ByteArrayInputStream(xml.getBytes());

Map<String, String> map = null;

XmlPullParser pullParser = XmlPullParserFactory.newInstance()

.newPullParser();

pullParser.setInput(inputStream, "UTF-8");// 为xml设置要解析的xml数据

int eventType = pullParser.getEventType();

while (eventType != XmlPullParser.END_DOCUMENT) {

switch (eventType) {

case XmlPullParser.START_DOCUMENT:

map = new HashMap<String, String>();

break;

case XmlPullParser.START_TAG:

String key = pullParser.getName();

if (key.equals("xml"))

break;

String value = pullParser.nextText();

map.put(key, value);

break;

case XmlPullParser.END_TAG:

break;

}

eventType = pullParser.next();

}

return map;

}

pay页面(上面步骤执行完后去的页面)

此处是页面js代码,接受后台代码传回来的参数。现在用的是BSL模板引擎,参数可以以EL表达式方式接收。可先将后台传会的参数,放在几个input类型type=”hidden”标签标签中。

<input type="hidden" name="appId" value="${appId}" id="appid" />

js中得到值

var appid = $("#appid").val();

js引用

<script type="text/javascript" src="${staticPath}/front/js/weixin.js"></script>

下面是JS代码,由于是bsl,自己看着传参数吧,反正都是后台来的。

<div class="button" id="onlinePayNow">确认支付</div>

//先写一个点击事件,当点击id为onlinePayNow的按钮时,触发该事件。

$("#onlinePayNow").click(function getpay(){

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{

//如果报错,可用下面方法看看是不是参数缺少。

/* alert('${appId}');

alert('${paytimestamp}');

alert('${paynonceStr}');

alert('${paypackage}');

alert('${paysignType}');

alert('${paySign}'); */

//调用下面方法。开启微信支付。

onBridgeReady();

}

})

function onBridgeReady(){

WeixinJSBridge.invoke('getBrandWCPayRequest', {

"appId" : '${appId}', //公众号名称,由商户传入

"timeStamp" : '${paytimestamp}', //时间戳,自1970年以来的秒数

"nonceStr" : '${paynonceStr}', //随机串

"package" : '${paypackage}',

"signType" : '${paysignType}', //微信签名方式:

"paySign" : '${paySign}' //微信签名

}, function(res) {

//alert(res.err_msg); // 使用以上方式判断前端返回,微信团队郑重提示:res.err_msg将在用户支付成功后返

if(res.err_msg == "get_brand_wcpay_request:ok"){

//支付成功,完成后去到哪个页面。

window.location.href="/XXXX/xxxx.html" rel="external nofollow" ;

}

});

}

在微信公众平台配置,支付授权目录。

授权目录建议:

http://www.XXXX.com/XXXX/xxx/index/

我觉得最好写后台是action地址就写Action地址,Controller就写Controller地址,如果有Spring注解,就写注解后名称。

我所导入的包(java后台,就是index方法。)

import java.io.ByteArrayInputStream;

import java.io.IOException;

import java.io.InputStream;

import java.math.BigDecimal;

import java.net.URLEncoder;

import java.security.MessageDigest;

import java.util.ArrayList;

import java.util.Collections;

import java.util.Comparator;

import java.util.HashMap;

import java.util.Iterator;

import java.util.List;

import java.util.Map;

import java.util.Map.Entry;

import java.util.UUID;

import org.xmlpull.v1.XmlPullParser;

import org.xmlpull.v1.XmlPullParserException;

import org.xmlpull.v1.XmlPullParserFactory;

import com.jfinal.kit.HttpKit;

import com.uitrs.express.common.Constants;

以上是 Java编程调用微信支付功能的方法详解 的全部内容, 来源链接: utcz.com/p/214184.html

回到顶部