这里有新鲜出炉的 Java 并发编程示例,程序狗速度看过来!
Java 程序设计语言
java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由 Sun Microsystems 公司于 1995 年 5 月推出的 Java 程序设计语言和 Java 平台(即 JavaEE(j2ee), JavaME(j2me), JavaSE(j2se))的总称.
这篇文章主要介绍了 Java 编程调用微信支付功能的方法, 结合实例形式详细分析了 java 微信支付功能的原理,操作流程及相关实现技巧, 需要的朋友可以参考下
本文实例讲述了 Java 编程调用微信支付功能的方法.分享给大家供大家参考,具体如下:
微信开发文档地址: https://mp.weixin.qq.com/wiki/home/
从调用处开始
我的流程: 1. 点击 "支付" 按钮,去后台 —-> 2. 后台生成支付所需数据返回页面 —-> 3. 页面点击 "确认支付" 调用微信支付 js.完成支付功能.
支付按钮
<div class="button" id="pay" onclick="payBox()">支付</div>
支付按钮 js
后台方法(例:index())
function payBox() {
//获得支付的钱数
var money = $(".money input").val();
//后台路径,加上参数
location.href = "/XXX/XXX/XXXX/XXXX?money =" + money;
}
注释:
render() == 我现在所用框架返回页面的一种方法.
getPara() == request.getParameter(name);
setAttr() == request.setAttribute(name, value);
首先得 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);
}
/**
pay 页面(上面步骤执行完后去的页面)
* @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;
}
此处是页面 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="http://www.h3399.cn/uploads/body/img.phperz.com/data/img/20171107_4/1510063219_1415.png">
我所导入的包(java 后台,就是 index 方法.)
希望本文所述对大家 java 程序设计有所帮助.
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;
来源: http://www.phperz.com/article/18/0112/354844.html