微信支付

1 绑定域名
2 在页面中添加微信页面授权的js
<script src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>
3 获取微信版本:(代码如下)
Map<String, Object> jsonMap = new HashMap<String, Object>();
jsonObj = new JSONObject();
String userAgent = ServletActionContext.getRequest().getHeader("user-agent");
// 通过微信访问我们的网页的时候,userAgent中含有微信的版本号,结构如“... MicroMessenger/6.3.5 ...”
String interceptStr = "MicroMessenger/";// 需要判断位置的字符串
int temp = userAgent.indexOf(interceptStr);
temp = temp + interceptStr.length();
// 取判断位置的字符串的下一位,即为当前微信的版本号第一位数字
String s = userAgent.substring(temp, temp + 1);
int versionNumber = Integer.parseInt(s);
if (versionNumber == 5 || versionNumber > 5) {
jsonMap.put("success", true);
} else {
// 该版本微信不支持微信支付功能,提示用户更新微信
jsonMap.put("success", false);
jsonMap.put("msg", "您使用的微信版本过低,不支持微信支付功能!请您先更新微信!");
}
jsonObj = JSONObject.fromObject(jsonMap);
return SUCCESS;
4 取微信签名,获取支付权限:(代码如下)(该签名只是微信页面授权的签名,下面还有支付签名。望注意!)
String host = request.getHeader("Host");
URL url = new URL("https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=" + access_token + "&type=jsapi");
//注:access_token是公众号的全局唯一票据,公众号调用各接口时都需使用access_token。
URLConnection connection = url.openConnection();
connection.setDoOutput(true);
InputStream in = connection.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(in, "UTF-8"));
StringBuilder sb = new StringBuilder("");
String res;
while ((res = reader.readLine()) != null) {
sb.append(res.trim());
}
String resultStr = sb.toString();
JSONObject jsonObject = JSONObject.fromObject(resultStr);
Map<String, Object> dataMap = (Map<String, Object>) JSONObject.toBean(jsonObject, Map.class);
String jsapi_ticket = "";
int errcode = (Integer) dataMap.get("errcode");
if (errcode == 0) {
jsapi_ticket = (String) dataMap.get("ticket");
} else {
jsapi_ticket = "error";
}
String nonce_str = create_nonce_str();
nonce_str = nonce_str.replace("-", "");
String timestamp = create_timestamp();
String taskUrl = "http://" + host + "/xinghuoban/page_pageJump.html?pageName=wxRecharge";
String signature = "";
// 注意这里参数名必须全部小写,且必须有序
String string1 = "jsapi_ticket=" + jsapi_ticket + "&noncestr=" + nonce_str + "&timestamp=" + timestamp + "&url="+ taskUrl;
MessageDigest crypt = MessageDigest.getInstance("SHA-1");
crypt.reset();
crypt.update(string1.getBytes("UTF-8"));
signature = byteToHex(crypt.digest());
Map<String, Object> resultMap = new HashMap<String, Object>();
resultMap.put("signature", signature);
resultMap.put("nonceStr", nonce_str);
resultMap.put("timestamp", timestamp);
resultMap.put("appid", appid);
jsonObj = JSONObject.fromObject(resultMap);
return jsonObj;
//注:注意红色字体。
当通过java代码实现获取签名以后,数据传送到页面时,通过config接口注入权限验证配置
wx.config({
   debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
   appId: appId, // 必填,公众号的唯一标识
   timestamp: timestamp, // 必填,生成签名的时间戳
   nonceStr: nonceStr, // 必填,生成签名的随机串
   signature: signature,// 必填,签名
   jsApiList: [
"chooseWXPay"//微信支付。还有别的一些接口,如“页面分享”、“录音”、“扫一扫”等。
   ] // 必填,需要使用的JS接口列表
});
//注:注意红色字体。
5 取微信支付签名:(代码如下,高潮来了!)
Map<String, Object> jsonMap = new HashMap<String, Object>();
jsonObj = new JSONObject();
//在配置文件中获取微信支付的相关数据
Properties properties = GetPropertiesFile.getPropObjFromBundle("path");
String appid = (String) properties.get("appid");
String mchId = (String) properties.get("mchId");
String notify_url = (String) properties.get("notify_url");
String spbill_create_ip = (String) properties.get("spbill_create_ip");

HttpSession session = ServletActionContext.getRequest().getSession();
String openId = (String) session.getAttribute("openid");

String orderNo = NumUtility.getOrderNo();
//创建随机字符串
String nonce_str = create_nonce_str();
nonce_str = nonce_str.replace("-", "");
// 微信支付Sign 签名生成
String signStr = getWXPaySign(totalFee, orderNo, nonce_str, openId);
String prepayId = "";
//创建时间戳
String timestamp = create_timestamp();

StringBuilder sb = new StringBuilder();
sb.append("<xml>");
sb.append("<appid><![CDATA[" + appid + "]]></appid>");// 微信分配的公众账号 ID
sb.append("<body><![CDATA[***-充值]]></body>");// 商品描述
sb.append("<mch_id><![CDATA[" + mchId + "]]></mch_id>");// 微信支付分配的商户号
sb.append("<nonce_str><![CDATA[" + nonce_str + "]]></nonce_str>");// 随机字符串
sb.append("<notify_url><![CDATA[" + notify_url + "]]></notify_url>");// 接收微信支付成功通知地址
sb.append("<openid><![CDATA[" + openId + "]]></openid>");// 用户标识
sb.append("<out_trade_no><![CDATA[zf" + orderNo + "]]></out_trade_no>");// 商户系统内部的订单号
sb.append("<spbill_create_ip>" + spbill_create_ip + "</spbill_create_ip>");// 订单生成的机器IP
sb.append("<total_fee><![CDATA[" + totalFee + "]]></total_fee>");// 订单总金额
sb.append("<trade_type><![CDATA[JSAPI]]></trade_type>");// 交易类型:JSAPI、NATIVE、APP
sb.append("<sign><![CDATA[" + signStr + "]]></sign>");// 签名
sb.append("</xml>");

try {
//获取微信支付所需prepay_id
prepayId = getWXPayPrepayId(sb.toString());

if (prepayId.split(":")[0].equals("FAIL")) {
jsonMap.put("success", false);
jsonMap.put("msg", prepayId);
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//获取支付签名(页面支付用)
String paySign = getPaySign(appid, prepayId, timestamp, nonce_str);

jsonMap.put("success", true);
jsonMap.put("appid", appid);
jsonMap.put("sign", signStr);
jsonMap.put("prepayId", prepayId);
jsonMap.put("timestamp", timestamp);
jsonMap.put("nonceStr", nonce_str);
jsonMap.put("paySign", paySign);
jsonObj = JSONObject.fromObject(jsonMap);
//注:这些是最终返回的数据,下面那些代码全是为获取这些数据做准备的。

return SUCCESS;

// 微信支付Sign 签名生成(取prepay_id用)
public static String getWXPaySign(int totalFee, String orderNo, String nonce_str, String openId) {
Properties properties = GetPropertiesFile.getPropObjFromBundle("path");
mchId = (String) properties.get("mchId");
zfKey = (String) properties.get("zfKey");
String notify_url = (String) properties.get("notify_url");
String spbill_create_ip = (String) properties.get("spbill_create_ip");

String signStr = "appid=" + appid// 公众账号 ID
+ "&body=行伙伴-充值"// 商品描述
+ "&mch_id=" + mchId// 商户号
+ "&nonce_str=" + nonce_str// 随机字符串
+ "&notify_url=" + notify_url// 回调地址
+ "&openid=" + openId + "&out_trade_no=zf" + orderNo// 商户订单号
// (微信用来判断当前支付的唯一性)
+ "&spbill_create_ip=" + spbill_create_ip + "&total_fee=" + totalFee// 订单总金额,单位为分
+ "&trade_type=JSAPI" + "&key=" + zfKey;// 商户支付密钥
// System.out.println("signStr---------" + signStr);

// md5加密
String md5Str = MD5Utility.md5Hex(signStr);
// System.out.println("md5Str---------" + md5Str);

// 将md5加密过后的字符串所有字母都变成大写字母
String sign = md5Str.toUpperCase();
// System.out.println("sign---------" + sign);

return sign;
}

//取微信支付所需prepay_id
public static String getWXPayPrepayId(String paramsStr) throws Exception {
PrintWriter out = null;

URL url = new URL("https://api.mch.weixin.qq.com/pay/unifiedorder");
URLConnection connection = url.openConnection();
// post
connection.setDoOutput(true);
connection.setDoInput(true);
connection.setRequestProperty("Pragma:", "no-cache");
connection.setRequestProperty("Cache-Control", "no-cache");
connection.setRequestProperty("Content-Type", "text/xml");
// 获取URLConnection对象对应的输出流
out = new PrintWriter(connection.getOutputStream());
// 发送请求参数
out.print(paramsStr);
// flush输出流的缓冲
out.flush();

InputStream in = connection.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(in, "UTF-8"));

StringBuilder sb = new StringBuilder("");
String res;
while ((res = reader.readLine()) != null) {
sb.append(res.trim());
}

// System.out.println("sb.toString()---------" + sb.toString());

String prepay_id = readStringXml(sb.toString());

return prepay_id;
}

// 解析xml
public static String readStringXml(String xml) {
String returnStr = "";
Document doc = null;
try {
// 读取并解析XML文档
// 下面的是通过解析xml字符串的
doc = DocumentHelper.parseText(xml); // 将字符串转为XML
Element rootElt = doc.getRootElement(); // 获取根节点

String return_code = rootElt.elementTextTrim("return_code"); // 获取根节点下的子节点return_code
String return_msg = rootElt.elementTextTrim("return_msg"); // 获取根节点下的子节点return_msg

if (return_code.equals("SUCCESS")) {
String result_code = rootElt.elementTextTrim("result_code"); // 获取根节点下的子节点result_code
if (result_code.equals("SUCCESS")) {
String prepay_id = rootElt.elementTextTrim("prepay_id"); // 获取根节点下的子节点prepay_id
returnStr = prepay_id;
}
} else {
returnStr = "FAIL:" + return_msg;
}
} catch (DocumentException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
// System.out.println("returnStr-----" + returnStr);
return returnStr;
}

// 获取支付签名(页面支付用)
public static String getPaySign(String appid, String prepayId, String timestamp, String nonce_str) {

prepayId = "prepay_id=" + prepayId;

String signStr = "appId=" + appid// 公众账号 ID
+ "&nonceStr=" + nonce_str// 随机字符串
+ "&package=" + prepayId// 统一支付接口返回的prepay_id参数值,提交格式如:prepay_id=***
+ "&signType=MD5"// 秘钥加密方式
+ "&timeStamp=" + timestamp// 时间戳
+ "&key=" + zfKey;
// System.out.println("signStr2---------" + signStr);

// md5加密
String md5Str = MD5Utility.md5Hex(signStr);
// System.out.println("md5Str2---------" + md5Str);

// 将md5加密过后的字符串所有字母都变成大写字母
String paySign = md5Str.toUpperCase();
// System.out.println("paySign---------" + paySign);

return paySign;
}
//取随机字符串
public static String create_nonce_str() {
return UUID.randomUUID().toString();
}
//取时间戳
public static String create_timestamp() {
return Long.toString(System.currentTimeMillis() / 1000);
}
6 将微信支付所需数据传回微信支付页面后,调起微信支付js接口。代码如下:
wx.chooseWXPay({
timestamp:timestamp, // 支付签名时间戳,注意微信jssdk中的所有使用timestamp字段均为小写。但最新版的支付后台生成签名使用的timeStamp字段名需大写其中的S字符
nonceStr:nonceStr, // 支付签名随机串,不长于 32 位
package:prepayId, // 统一支付接口返回的prepay_id参数值,提交格式如:prepay_id=***)
signType:'MD5', // 签名方式,默认为'SHA1',使用新版支付需传入'MD5'
paySign:paySign, // 支付签名
success: function (res) {支付成功处理},
cancel: function () {用户取消处理},
error: function (e) {支付失败处理}
});
//注:注意参数大小写问题,及红色字体部分。

微信开发详细技术文档可以参看http://mp.weixin.qq.com/wiki/home/index.html。微信公众平台开发者文档。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值