最近工作中接触到一些关于微信支付方面的东西,看到给的DEMO都是PHP版本的,再加上微信支付文档写的确实不敢恭维,趟过不少坑之后闲下来做个总结。
一、前期准备
做微信开发首先要申请一个公共账号,申请成功后会以邮件形式发给你一些必要信息,公共账号中有开发文档以及开发中必要信息,以及测试的数据查询。
二、工具类
1.MD5加密工具类
package com.pay.utils.weixin;
import java.security.MessageDigest;
public class MD5Util {
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();
// 获得MD5摘要算法的 MessageDigest 对象
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;
}
}
}
2.CommonUtil工具类,用于装换成微信所需XML。以下return new String(xml.toString().getBytes(),"ISO8859-1");将工具类中的utf-8改成iso8859-1,否则微信订单中的中文会出现乱码,改后可以正确显示。
package com.pay.utils.weixin;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.*;
import java.util.Map.Entry;
public class CommonUtil {
public static String CreateNoncestr(int length) {
String chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
String res = "";
for (int i = 0; i < length; i++) {
Random rd = new Random();
res += chars.indexOf(rd.nextInt(chars.length() - 1));
}
return res;
}
public static String CreateNoncestr() {
String chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
String res = "";
for (int i = 0; i < 16; i++) {
Random rd = new Random();
res += chars.charAt(rd.nextInt(chars.length() - 1));
}
return res;
}
public static String FormatQueryParaMap(HashMap parameters)
throws SDKRuntimeException {
String buff = "";
try {
List> infoIds = new ArrayList>(
parameters.entrySet());
Collections.sort(infoIds,
new Comparator>() {
public int compare(Map.Entry o1,
Map.Entry o2) {
return (o1.getKey()).toString().compareTo(
o2.getKey());
}
});
for (int i = 0; i < infoIds.size(); i++) {
Map.Entry item = infoIds.get(i);
if (item.getKey() != "") {
buff += item.getKey() + "="
+ URLEncoder.encode(item.getValue(), "utf-8") + "&";
}
}
if (buff.isEmpty() == false) {
buff = buff.substring(0, buff.length() - 1);
}
} catch (Exception e) {
throw new SDKRuntimeException(e.getMessage());
}
return buff;
}
public static String FormatBizQueryParaMap(HashMap paraMap,
boolean urlencode) throws SDKRuntimeException {
String buff = "";
try {
List> infoIds = new ArrayList>(
paraMap.entrySet());
Collections.sort(infoIds,
new Comparator>() {
public int compare(Map.Entry o1,
Map.Entry o2) {
return (o1.getKey()).toString().compareTo(
o2.getKey());
}
});
for (int i = 0; i < infoIds.size(); i++) {
Map.Entry 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.toLowerCase() + "=" + val + "&";
}
}
if (buff.isEmpty() == false) {
buff = buff.substring(0, buff.length() - 1);
}
} catch (Exception e) {
throw new SDKRuntimeException(e.getMessage());
}
return buff;
}
public static boolean IsNumeric(String str) {
if (str.matches("\d *")) {
return true;
} else {
return false;
}
}
public static String ArrayToXml(HashMap arr) {
String xml = "";
Iterator> iter = arr.entrySet().iterator();
while (iter.hasNext()) {
Entry entry = iter.next();
String key = entry.getKey();
String val = entry.getValue();
if (IsNumeric(val)) {
xml += "<" + key + ">" + val + "" + key + ">";
} else
xml += "<" + key + ">" + key + ">";
}
xml += " ";
try {
return new String(xml.toString().getBytes(),"ISO8859-1");
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return "";
}
}
3.ClientCustomSSL工具类,用于生成sign以及创建微信订单package com.pay.utils.weixin;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.util.StringUtils;
public class ClientCustomSSL {
public static String GetBizSign(HashMap bizObj)
throws SDKRuntimeException {
HashMap bizParameters = new HashMap();
List> infoIds = new ArrayList>(
bizObj.entrySet());
System.out.println(infoIds);
Collections.sort(infoIds, new Comparator>() {
public int compare(Map.Entry o1,
Map.Entry o2) {
return (o1.getKey()).toString().compareTo(o2.getKey());
}
});
System.out.println("--------------------");
System.out.println(infoIds);
for (int i = 0; i < infoIds.size(); i++) {
Map.Entry item = infoIds.get(i);
if (item.getKey() != "") {
bizParameters.put(item.getKey().toLowerCase(), item.getValue());
}
}
//bizParameters.put("key", "12345678123456781234567812345671");
String bizString = CommonUtil.FormatBizQueryParaMap(bizParameters,
false);
bizString += "&key=12345678123456781234567812345671";
System.out.println("***************");
System.out.println(bizString);
// return SHA1Util.Sha1(bizString);
return MD5Util.MD5(bizString);
}
public static String CreateNativePackage(String nonceStr,String orderDescribe,String orderNo,String price,String timeStart,String timeExpire) throws SDKRuntimeException {
HashMap nativeObj = new HashMap();
nativeObj.put("appid", "见公众账号"); //公众账号Id
nativeObj.put("mch_id", "见邮件"); //商户号
nativeObj.put("nonce_str", nonceStr);//随机字符串
nativeObj.put("body", orderDescribe); //商品描述
nativeObj.put("attach", "tradeno"); //附加数据
nativeObj.put("out_trade_no", orderNo); //商户订单号(全局唯一)
nativeObj.put("total_fee", price); //总金额(单位为分,不能带小数点)
nativeObj.put("spbill_create_ip","192.168.0.144"); //终端Ip
nativeObj.put("time_start", timeStart); //交易起始时间
nativeObj.put("time_expire", timeExpire); //交易结束时间
nativeObj.put("notify_url", CustomizedPropertyPlaceholderConfigurer.getContextProperty("wxurl")+"/weixin_callback/weixinCallback/init.action"); //回调通知地址
nativeObj.put("trade_type", "NATIVE"); //交易类型
String sign = GetBizSign(nativeObj);
nativeObj.put("sign", sign.toUpperCase());
return CommonUtil.ArrayToXml(nativeObj);
}
public static String SearchNativePackage(String transactionId,String outTradeNo,String nonceStr) throws SDKRuntimeException {
HashMap nativeObj = new HashMap();
nativeObj.put("appid", "见公众共账号"); //公众账号Id
nativeObj.put("mch_id", "见邮件");//商户号
nativeObj.put("nonce_str", nonceStr);//随机字符串
if(!StringUtils.isEmpty(transactionId)){
nativeObj.put("transaction_id", transactionId);
}
if(!StringUtils.isEmpty(outTradeNo)){
nativeObj.put("out_trade_no", outTradeNo);//随机字符串
}
String sign = GetBizSign(nativeObj);
nativeObj.put("sign", sign.toUpperCase());
return CommonUtil.ArrayToXml(nativeObj);
public static String RefundNativePackage(String outTradeNo,String outRefundNo,String totalFee,String refundFee,String nonceStr) throws SDKRuntimeException {
HashMap nativeObj = new HashMap();
nativeObj.put("appid", "见公众账号");//公众账号Id
nativeObj.put("mch_id", "见邮件");//商户号
nativeObj.put("nonce_str", nonceStr);//随机字符串
nativeObj.put("out_trade_no", outTradeNo);//商户订单号(全局唯一)
nativeObj.put("out_refund_no", outRefundNo);//商户退款单号(全局唯一)
nativeObj.put("total_fee", totalFee);//总金额(单位为分,不能带小数点)
nativeObj.put("refund_fee", refundFee);//退款金额(单位为分,不能带小数点)
nativeObj.put("op_user_id", "邮件");
String sign = GetBizSign(nativeObj);
nativeObj.put("sign", sign.toUpperCase());
return CommonUtil.ArrayToXml(nativeObj);
}
public static String CreateJsApiPackage(String nonceStr,String orderDescribe,String orderNo,String price,String timeStart,String timeExpire,String openId) throws SDKRuntimeException {
HashMap nativeObj = new HashMap();
nativeObj.put("appid", "见公众账号");//公众账号Id
nativeObj.put("openid", openId);//公众账号Id
nativeObj.put("mch_id", "见邮件")//商户号
nativeObj.put("nonce_str", nonceStr);//随机字符串
nativeObj.put("body", orderDescribe);//商品描述
nativeObj.put("attach", "tradeno");//附加数据
nativeObj.put("out_trade_no", orderNo);//商户订单号(全局唯一)
nativeObj.put("total_fee", price);//总金额(单位为分,不能带小数点)
nativeObj.put("spbill_create_ip","192.168.0.144");//终端Ip
nativeObj.put("time_start", timeStart);//交易起始时间
nativeObj.put("time_expire", timeExpire)//交易结束时间
nativeObj.put("notify_url",CustomizedPropertyPlaceholderConfigurer.getContextProperty("wxurl")+"/weixin_callback/weixinCallback/init.action");//通知地址
nativeObj.put("trade_type", "JSAPI");//交易类型
String sign = GetBizSign(nativeObj);
nativeObj.put("sign", sign.toUpperCase());
return CommonUtil.ArrayToXml(nativeObj);
}
public static String CreateCloseOrder(String outTradeNo,String nonceStr) throws SDKRuntimeException {
HashMap nativeObj = new HashMap();
nativeObj.put("appid", "见公众账号");//公众账号Id
nativeObj.put("mch_id", "见邮件");//商户号
nativeObj.put("out_trade_no", outTradeNo);//商户订单号(全局唯一)
nativeObj.put("nonce_str", nonceStr);//随机字符串
String sign = GetBizSign(nativeObj);
nativeObj.put("sign", sign.toUpperCase());
return CommonUtil.ArrayToXml(nativeObj);
}
}
4.调用微信支付接口
package com.pay.controller.weixin;
import java.io.File;
import java.io.FileInputStream;
import java.security.KeyStore;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import javax.net.ssl.SSLContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLContexts;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.dom4j.document;
import org.dom4j.documentHelper;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
import com.pay.bo.PayHist;
import com.pay.constants.PayHistoryPayStatus;
import com.pay.constants.PayHistoryPayType;
import com.pay.service.WeiXinPayService;
import com.pay.utils.weixin.ClientCustomSSL;
import com.pay.utils.weixin.CloseWeiXinOrderUtils;
import com.pay.utils.weixin.CustomizedPropertyPlaceholderConfigurer;
@RestController
@RequestMapping("/Pay")
public class WeiXinPayController {
@Autowired
WeiXinPayService weiXinPayService;
private static long standardTime = 1662652800000L;
@RequestMapping(value="/getUrl",method=RequestMethod.POST)
@ResponseStatus(HttpStatus.OK)
public Object getUrl(HttpServletResponse response,@RequestBody String body){
try{
JSonObject jsonO = JSONObject.fromObject(body);
PayHist ph = null;
// List
httpclient jar包和json jar包:下载地址。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持考高分网。



