Java中调用微信支付功能的实例分析

这篇文章主要介绍了Java编程调用微信支付功能的方法,结合实例形式详细分析了java微信支付功能的原理、操作流程及相关实现技巧,需要的朋友可以参考下

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

从调用处开始

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

支付按钮

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

支付按钮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;    }}//解析XMLprivate 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,自己看着传参数吧,反正都是后台来的。

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

//先写一个点击事件,当点击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中调用微信支付功能的实例分析的详细内容,更多请关注其它相关文章!

如果困难是堵砖墙,拍拍它说你还不够高。

Java中调用微信支付功能的实例分析

相关文章:

你感兴趣的文章:

标签云: