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算法相关内容感兴趣的读者可查看本站专题:《Java字符与字符串操作技巧总结》、《Java数组操作技巧总结》、《Java数学运算技巧总结》、《Java编码操作技巧总结》和《Java数据结构与算法教程》

希望本文所述对大家java程序设计有所帮助。

(0)

相关推荐

  • Java编程调用微信分享功能示例

    本文实例讲述了Java编程调用微信分享功能.分享给大家供大家参考,具体如下: 这篇文章介绍如何使用java开发微信分享功能,因为工作,已经开发完成,可使用. 如果想要自定义微信的分享功能,首先在自己的页面内首先使用AJAX.下面我具体举例. 首先是在页面内写入请求后台的AJAX /** * 调用微信分享接口 * */ public void WXConfig(){ String url = getPara("href"); WXConfigController scan = new W

  • Java编程实现非对称加密的方法详解

    本文实例讲述了Java编程实现非对称加密的方法.分享给大家供大家参考,具体如下: 对称加密算法在加密和解密时使用的是同一个秘钥:而非对称加密算法需要两个密钥来进行加密和解密,这两个秘钥是公开密钥(public key,简称公钥)和私有密钥(private key,简称私钥). 是一种 高级的双保险加密方式,一般的实现加密方式有DH密钥交换算法,RSA基于因子分解算法,ElGamal离散对数算法及ECC椭圆曲线加密等. DH加密解密 /** * 非对称加密之:DH加密 * 非对称DH,是安全性基于

  • java编程中实现调用js方法分析

    本文实例讲述了java编程中实现调用js方法.分享给大家供大家参考,具体如下: /* * 加载脚本引擎,并在java中调用js方法 */ public void test2() { ScriptEngineManager manager = new ScriptEngineManager(); ScriptEngine engine = manager.getEngineByName("javascript"); try { String str="2&1"

  • Java网络编程基础篇之单向通信 原创

    在网络编程中如果只要求客户机向服务器发送消息,不要求服务器向客户机发送消息,称为单线通信.客户机套接字和服务器套接字链接成功后,可估计通过输出流发送数据,服务器则通过输入流接受数据,下面是简单的单向通信的例子. 实例1:本实例是一个TCP服务器端程序,在 getserver() 方法中建立服务器套接字,调用getClienMessage()方法获取客户端信息.代码如下: import java.io.BufferedReader; import java.io.IOException; impo

  • Java编程获取文本框的内容实例解析

    在JAVA中如何获取文本框中输入的值,并保存在一个文件之中.具体代码如下: import java.io.*; import javax.swing.*; import java.awt.FlowLayout; import java.awt.event.*; public class WriterTo extends JFrame implements ActionListener{ JButton b;JTextField t; public WriterTo(){ super("文本框内容

  • Java编程倒计时实现方法示例

    实现Java编程中倒计时的方法有许多,下面我们通过三个示例来简单了解下它的实现过程. 1.简易方式实现 /** * @see * @author Al_assad yulinying_1994@outlook.com * @date 2016年10月18日 上午3:10:13 * @version V1.0 * Description: 倒计时简易实现,只用单线程 */ import java.util.*; import java.util.concurrent.*; public class

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

    本文实例讲述了Java编程调用微信支付功能的方法.分享给大家供大家参考,具体如下: 微信开发文档地址:https://mp.weixin.qq.com/wiki/home/ 从调用处开始 我的流程: 1.点击"支付"按钮,去后台 --> 2.后台生成支付所需数据返回页面 --> 3.页面点击"确认支付"调用微信支付js.完成支付功能. 支付按钮 <div class="button" id="pay" onc

  • Java调用微信支付功能的方法示例代码

    Java 使用微信支付 前言百度搜了一下微信支付,都描述的不太好,于是乎打算自己写一个案例,希望以后拿来直接改造使用. 因为涉及二维码的前端显示,所以有前端的内容 一. 准备工作 所需微信公众号信息配置 APPID:绑定支付的APPID(必须配置) MCHID:商户号(必须配置) KEY:商户支付密钥,参考开户邮件设置(必须配置) APPSECRET:公众帐号secert(仅JSAPI支付的时候需要配置) 我这个案例用的是尚硅谷一位老师提供的,这里不方便提供出来,需要大家自己找,或者公司提供 二

  • 小程序微信退款功能实现方法详解【基于thinkPHP】

    本文实例讲述了小程序微信退款功能实现方法.分享给大家供大家参考,具体如下: ☹. 背景 微信开发中,既然涉及到了微信支付,对于合理的购物网站,必定会有用户退款请求 当然,一种方式是登录 微信商户平台,在 交易列表 中进行微信退款操作 但是,如果业务量庞大,作为友好交互,自然需要进行代码实现 微信退款 操作咯 稍作一提,这是针对 小程序退款申请 的方法指导(目测跟公众号退款没啥区别) 理论上,请对应参考文章:小程序微信支付 实例配置详解 编程语言:PHP 使用框架:ThinkPHP3.2.3 (我

  • Java编程调用微信接口实现图文信息推送功能

    本文实例讲述了Java编程调用微信接口实现图文信息等推送功能.分享给大家供大家参考,具体如下: Java调用微信接口工具类,包含素材上传.获取素材列表.上传图文消息内的图片获取URL.图文信息推送. 微信图文信息推送因注意html代码字符串中将双引号(")替换成单引号('),不然信息页面中包含图片将无法显示且图片后面的内容也不会显示 官方文档:http://mp.weixin.qq.com/wiki/home/ StringBuilder sb=new StringBuilder(); sb.a

  • JS通过调用微信API实现微信支付功能的方法示例

    本文实例讲述了JS通过调用微信API实现微信支付功能的方法.分享给大家供大家参考,具体如下: 最近在做微信公众号开发,在微信支付上遇到一些问题,困惑了3天,今天终于搞定.期间要感谢一些大神的帮助,趁热下面分享一下我的经验. 在实现微信支付之前,需要到微信开发平台认证,这些认证和配置信息我就不多说了,这里主要从代码层面实现支付. function onBridgeReady(){ WeixinJSBridge.invoke( 'getBrandWCPayRequest', { "appId&quo

  • 小程序微信支付功能配置方法示例详解【基于thinkPHP】

    本文实例讲述了小程序微信支付功能配置方法.分享给大家供大家参考,具体如下: ★ 背景 近期进行小程序的开发,毕竟是商城项目的开发,最后牵扯到的微信支付是必要的 个人开发过程中也是遇到各种问题,在此,我根据自己的实际操作,进行了代码的详细配置,以方便小程序新手的快速操作 -  使用语言:PHP             # PHP世界上最好的语言 HaHahahaaha -  使用框架:ThinkPHP 3.2    # 版本有点低而已,没啥大碍 -  测试工具:微信开发者工具    # 其实还挺好

  • java并发编程_线程池的使用方法(详解)

    一.任务和执行策略之间的隐性耦合 Executor可以将任务的提交和任务的执行策略解耦 只有任务是同类型的且执行时间差别不大,才能发挥最大性能,否则,如将一些耗时长的任务和耗时短的任务放在一个线程池,除非线程池很大,否则会造成死锁等问题 1.线程饥饿死锁 类似于:将两个任务提交给一个单线程池,且两个任务之间相互依赖,一个任务等待另一个任务,则会发生死锁:表现为池不够 定义:某个任务必须等待池中其他任务的运行结果,有可能发生饥饿死锁 2.线程池大小 注意:线程池的大小还受其他的限制,如其他资源池:

  • Java实现统计在线人数功能的方法详解

    目录 1. 监听器的简介 2. Java监听器的类型 (1)ServletContextListener (2)HttpSessionListener (3)ServletRequestListener (4)ServletContextAttributeListener (5)HttpSessionAttributeListener (6)ServletRequestAttributeListener (7)HttpSessionActivationListener 3.监听器Listener

  • WPF仿微信实现截图功能的方法详解

    目录 前言 一.ScreenCut.cs 代码如下 二.ScreenCut.xaml 代码如下 三.ScreenCutExample.xaml 代码如下 每日一笑 肚子疼,去厕所排便,结果什么都没拉出来.看着自己坐在马桶上痛苦又努力却一无所获的样子,仿佛看到了自己平凡的一生. 前言 有小伙伴需要在软件反馈窗体增加截图功能需求,所以今天来实现一个仿微信的截图. 效果预览(更多效果请下载源码体验) 一.ScreenCut.cs 代码如下 using Microsoft.Win32; using Sy

随机推荐