OfficialWeChatRequest.java
下单
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.SortedMap;
import java.util.TreeMap;
import net.sf.json.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.alibaba.dts.common.util.StringUtil;
import com.suyu.pay.way.Base64;
import com.suyu.pay.way.channel.suyupayV001.util.MD5;
import com.suyu.pay.way.channel.suyupayV001.util.XmlConverUtil;
import com.suyu.pay.way.channel.utils.SuPayWayConfig;
import com.taobao.tddl.executor.function.scalar.math.Rand;
public class OfficialWeChatRequest {
protected static Logger logger = LoggerFactory.getLogger(OfficialWeChatRequest.class);
//生成随机字符
public static String NonceStr() {
String res = Base64.encodeAsString(Math.random() + "::" + new Date().toString()).substring(0, 30);
return res;
}
//获取终端Ip
public static String GetIp() {
InetAddress ia = null;
try {
ia = InetAddress.getLocalHost();
String localip = ia.getHostAddress();
return localip;
} catch (Exception e) {
return null;
}
}
Map转xml数据
public static String GetMapToXML(Map<String, String> param) {
StringBuffer sb = new StringBuffer();
sb.append("<xml>");
for (Map.Entry<String, String> entry : param.entrySet()) {
sb.append("<" + entry.getKey() + ">");
sb.append(entry.getValue());
sb.append("</" + entry.getKey() + ">");
}
sb.append("</xml>");
return sb.toString();
}
//获取签名
public static String GetSign(SortedMap<String, String> signParams){
String StringA = Util.formatUrlMap(signParams, false, false);
String stringSignTemp = MD5.MD5Encode(StringA+"&key="+WeChatConfig.API_KEY).toUpperCase();
System.out.println(stringSignTemp);
return stringSignTemp;
}
/**
* 微信native
*/
public static JSONObject weixinNative(final String commodityName, final String amount, final String orderNo) {
SortedMap<String, String> signParams = new TreeMap<String, String>();
signParams.put("appid", WeChatConfig.APPID);// appid
signParams.put("mch_id", WeChatConfig.MCH_ID);// 商户号
signParams.put("trade_type", "NATIVE");// 支付类型
signParams.put("body", commodityName); //商品描述
signParams.put("out_trade_no", orderNo);// 商户订单号
signParams.put("total_fee", amount); //总金额
signParams.put("spbill_create_ip", GetIp()); //终端Ip
signParams.put("nonce_str", NonceStr()); //随机字符串
signParams.put("notify_url", SuPayWayConfig.OFFICIAL_WEIXINBACK_URL);// 后台回调URL
signParams.put("sign",GetSign(signParams));
String xmlData = GetMapToXML(signParams);
String resXml = HtmlUtil.postData("https://api.mch.weixin.qq.com/pay/unifiedorder", xmlData);
//处理返回值
HashMap<String, String> map = (HashMap<String, String>) XmlConverUtil.xmltoMap(resXml);
String codeUrl = map.get("code_url");
String returnCode = map.get("return_code");
Map<String, String> returnMap = new HashMap<String, String>();
if (StringUtil.isNotBlank(returnCode) && "SUCCESS".equals(returnCode)) {
returnMap.put("serverCode", "0000");
returnMap.put("returnMsg",codeUrl );
}else{
returnMap.put("serverCode", "0005");
returnMap.put("returnMsg", "系统错误" );
}
return JSONObject.fromObject(returnMap);
}
/**
* 微信JSAPI
*/
public static JSONObject weixinJsapi(final String commodityName, final String amount, final String orderNo ,final String openid) {
SortedMap<String, String> signParams = new TreeMap<String, String>();
signParams.put("appid", WeChatConfig.APPID);// appid
signParams.put("mch_id", WeChatConfig.MCH_ID);// 商户号
signParams.put("trade_type", "JSAPI");// 支付类型
signParams.put("openid", openid);// openid
signParams.put("body", commodityName); //商品描述
signParams.put("out_trade_no", orderNo);// 商户订单号
signParams.put("total_fee", amount); //总金额
signParams.put("spbill_create_ip", GetIp()); //终端Ip
signParams.put("nonce_str", NonceStr()); //随机字符串
signParams.put("notify_url", SuPayWayConfig.OFFICIAL_WEIXINBACK_URL);// 后台回调URL
signParams.put("sign",GetSign(signParams));
String xmlData = GetMapToXML(signParams);
String resXml = HtmlUtil.postData("https://api.mch.weixin.qq.com/pay/unifiedorder", xmlData);
//处理返回值
HashMap<String, String> map = (HashMap<String, String>) XmlConverUtil.xmltoMap(resXml);
String returnCode = map.get("return_code");
String resultCode = map.get("result_code");
Map<String, String> returnMap = new HashMap<String, String>();
if (StringUtil.isNotBlank(returnCode) && "SUCCESS".equals(returnCode) && "SUCCESS".equals(resultCode)) {
//处理JS参数
SortedMap<String, String> jsMap = new TreeMap<String, String>();
jsMap.put("appId",map.get("appid"));
jsMap.put("timeStamp", String.valueOf(System.currentTimeMillis()/1000));//时间戳 秒
jsMap.put("nonceStr", String.valueOf(new Random().nextInt(999999)));
jsMap.put("package", "prepay_id=" + map.get("prepay_id"));
jsMap.put("signType", "MD5");
jsMap.put("paySign", GetSign(jsMap));
returnMap.put("serverCode", "0000");
returnMap.put("returnMsg",JSONObject.fromObject(jsMap).toString() );
}else{
returnMap.put("serverCode", "0005");
returnMap.put("returnMsg", "系统错误" );
}
return JSONObject.fromObject(returnMap);
}
}
配置参数(一般是不变的)WeChatConfig.java
public class WeChatConfig {
//appid
public final static String APPID = "公众号appid";
//编码
public final static String _INPUT_CHARSET = "UTF-8";
//商户号刚改了
public final static String MCH_ID = "商户号";
//随机字符串
public final static String NONCE_STR = "";
//签名
public final static String SIGN="";
//签名方式
public final static String SIGN_TYPE = "MD5";
//商品描述
public final static String BODY = "";
//商户订单号
public final static String OUT_TRADE_NO = "";
//标价金额
public final static String TOTAL_FEE = "";
//终端IP
public final static String SPBILL_CREATE_IP="";
//通知地址
public final static String NOTIFY_URL ="http://*/*/officialWeixinNotify";
//交易类型
public final static String TRADE_TYPE = "";
//APIKEY
public final static String API_KEY = "***";
//接口地址
public final static String URL_ONLINE = "https://api.mch.weixin.qq.com/pay/unifiedorder";
}
生成签名的工具类
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
public class Util {
/**
*
* 方法用途: 对所有传入参数按照字段名的 ASCII 码从小到大排序(字典序),并且生成url参数串<br>
* 实现步骤: <br>
*
* @param paraMap 要排序的Map对象
* @param urlEncode 是否需要URLENCODE
* @param keyToLower 是否需要将Key转换为全小写
* true:key转化成小写,false:不转化
* @return
*/
public static String formatUrlMap(Map<String, String> paraMap, boolean urlEncode, boolean keyToLower)
{
if(paraMap == null){
return "";
}
String buff = "";
Map<String, String> tmpMap = paraMap;
try
{
List<Map.Entry<String, String>> infoIds = new ArrayList<Map.Entry<String, String>>(tmpMap.entrySet());
// 对所有传入参数按照字段名的 ASCII 码从小到大排序(字典序)
Collections.sort(infoIds, new Comparator<Map.Entry<String, String>>()
{
@Override
public int compare(Map.Entry<String, String> o1, Map.Entry<String, String> o2)
{
return (o1.getKey()).toString().compareTo(o2.getKey());
}
});
// 构造URL 键值对的格式
StringBuilder buf = new StringBuilder();
for (Map.Entry<String, String> item : infoIds)
{
String key = item.getKey();
String val = item.getValue();
if (urlEncode)
{
val = URLEncoder.encode(val, "utf-8");
}
if (keyToLower)
{
buf.append(key.toLowerCase() + "=" + val);
} else
{
buf.append(key + "=" + val);
}
buf.append("&");
}
buff = buf.toString();
if (buff.isEmpty() == false)
{
buff = buff.substring(0, buff.length() - 1);
}
} catch (Exception e)
{
return null;
}
return buff;
}
}
post工具
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.URL;
import java.net.URLConnection;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class HtmlUtil {
private static Logger logger_ = LoggerFactory.getLogger(HtmlUtil.class);
private final static int CONNECT_TIMEOUT = 5000; // in milliseconds
private final static String DEFAULT_ENCODING = "UTF-8";
public static String postData(String urlStr, String data){
return postData(urlStr, data, null);
}
public static String postData(String urlStr, String data, String contentType) {
BufferedReader reader = null;
try {
URL url = new URL(urlStr);
URLConnection conn = url.openConnection();
conn.setDoOutput(true);
conn.setConnectTimeout(CONNECT_TIMEOUT);
conn.setReadTimeout(CONNECT_TIMEOUT);
if(StringUtils.isNotBlank(contentType))
conn.setRequestProperty("content-type", contentType);
OutputStreamWriter writer = new OutputStreamWriter(conn.getOutputStream(), DEFAULT_ENCODING);
if(data == null)
data = "";
writer.write(data);
writer.flush();
writer.close();
reader = new BufferedReader(new InputStreamReader(conn.getInputStream(), DEFAULT_ENCODING));
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line);
sb.append("\r\n");
}
return sb.toString();
} catch (IOException e) {
logger_.error("Error connecting to " + urlStr + ": " + e.getMessage());
} finally {
try {
if (reader != null)
reader.close();
} catch (IOException e) {
}
}
return null;
}
}