import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import ***********************.WeChatConst;//一些常量
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import java.io.*;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
/**
* Created by Arthur on 2015/11/10 16:45.
*/
public class WeChatUtil {
/**
* 通过Code 获取用户 openid 和 access_token
* @param code
* @return
* @throws IOException
*/
public static Map getOpenIdByCode(String code) throws IOException {
/**
* 设置访问路径
*/
HttpPost httppost = new HttpPost("https://api.weixin.qq.com/sns/oauth2/access_token");
/**
* 组装请求参数
*/
String reqEntityStr = "appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code";
reqEntityStr = reqEntityStr.replace("APPID", WeChatConst.APPID);
reqEntityStr = reqEntityStr.replace("SECRET", WeChatConst.APP_SECRET);
reqEntityStr = reqEntityStr.replace("CODE", code);
StringEntity reqEntity = new StringEntity(reqEntityStr);
/**
* 设置浏览器
*/
DefaultHttpClient httpclient = new DefaultHttpClient();
/**
* 设置参数
*/
httppost.setEntity(reqEntity);
/**
* 发起请求
*/
HttpResponse response = httpclient.execute(httppost);
/**
* 获得请求内容
*/
String strResult = EntityUtils.toString(response.getEntity(), Charset.forName("utf-8"));
/**
* 分析内容
*/
JSONObject jsonObject = (JSONObject) JSON.parse(strResult);
Map map = new HashMap<>();
map.put("openid",jsonObject.get("openid"));
map.put("access_token",jsonObject.get("access_token"));
map.put("refresh_token",jsonObject.get("refresh_token"));
return map;
}
/**
* 统一下单
* 获得PrePayId
* @param body 商品或支付单简要描述
* @param out_trade_no 商户系统内部的订单号,32个字符内、可包含字母
* @param total_fee 订单总金额,单位为分
* @param IP APP和网页支付提交用户端ip
* @param notify_url 接收微信支付异步通知回调地址
* @param openid 用户openId
* @throws IOException
*/
public static String unifiedorder(String body,String out_trade_no,Integer total_fee,String IP,String notify_url,String openid)throws IOException {
/**
* 设置访问路径
*/
HttpPost httppost = new HttpPost("https://api.mch.weixin.qq.com/pay/unifiedorder");
/**
* 组装请求参数
* 按照ASCII排序
*/
String reqEntityStr = "appid=APPID" +
"&body=BODY" +
"&mch_id=MCH_ID" +
"&nonce_str=NONCE_STR" +
"¬ify_url=NOTIFY_URL" +
"&openid=OPENID" +
"&out_trade_no=OUT_TRADE_NO" +
"&spbill_create_ip=IP" +
"&total_fee=TOTAL_FEE" +
"&trade_type=TRADE_TYPE"
;//这个字段是用于之后MD5加密的,字段要按照ascii码顺序排序
/**
* 设置数据
*/
String nonce_str = getNonceStr().toUpperCase();//随机数据
reqEntityStr = reqEntityStr.replace("APPID", WeChatConst.APPID);
reqEntityStr = reqEntityStr.replace("MCH_ID", WeChatConst.MCH_ID);
reqEntityStr = reqEntityStr.replace("NONCE_STR", nonce_str);
reqEntityStr = reqEntityStr.replace("BODY", body);
reqEntityStr = reqEntityStr.replace("OUT_TRADE_NO", out_trade_no);
reqEntityStr = reqEntityStr.replace("TOTAL_FEE", total_fee.toString());
reqEntityStr = reqEntityStr.replace("IP", IP);
reqEntityStr = reqEntityStr.replace("NOTIFY_URL", notify_url);
reqEntityStr = reqEntityStr.replace("TRADE_TYPE", WeChatConst.TRADE_TYPE);
reqEntityStr = reqEntityStr.replace("OPENID", openid);
/**
* 生成sign的数据
*/
String sign = reqEntityStr + "&key="+WeChatConst.KEY;
sign = MD5Util.MD5(sign).toUpperCase();
/**
* 组装XML
*/
StringBuilder sb = new StringBuilder("");
sb.append("");
setXmlKV(sb,"appid",WeChatConst.APPID);
setXmlKV(sb,"body",body);
setXmlKV(sb,"mch_id",WeChatConst.MCH_ID);
setXmlKV(sb,"nonce_str",nonce_str);
setXmlKV(sb,"notify_url",notify_url);
setXmlKV(sb,"openid",openid);
setXmlKV(sb,"out_trade_no",out_trade_no);
setXmlKV(sb,"spbill_create_ip",IP);
setXmlKV(sb,"total_fee",total_fee.toString());
setXmlKV(sb,"trade_type",WeChatConst.TRADE_TYPE);
setXmlKV(sb,"sign",sign);
sb.append("");
// reqEntityStr = reqEntityStr.replace("sign", sign);
StringEntity reqEntity = new StringEntity(new String (sb.toString().getBytes("UTF-8"),"ISO8859-1"));//这个处理是为了防止传中文的时候出现签名错误
httppost.setEntity(reqEntity);
DefaultHttpClient httpclient = new DefaultHttpClient();
HttpResponse response = httpclient.execute(httppost);
String strResult = EntityUtils.toString(response.getEntity(), Charset.forName("utf-8"));
// System.out.println(strResult);
return getPrePayId(strResult);
}
/**
* 获得32位随机字符串
* @return
*/
public static String getNonceStr(){
String str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
StringBuilder sb = new StringBuilder();
Random rd = new Random();
for(int i = 0 ; i < 32 ; i ++ ){
sb.append(str.charAt(rd.nextInt(str.length())));
}
return sb.toString();
}
/**
* 插入XML标签
* @param sb
* @param Key
* @param value
* @return
*/
public static StringBuilder setXmlKV(StringBuilder sb,String Key,String value){
sb.append("
sb.append(Key);
sb.append(">");
sb.append(value);
sb.append("");
sb.append(Key);
sb.append(">");
return sb;
}
/**
* 解析XML 获得 PrePayId
* @param xml
* @return
*/
public static String getPrePayId(String xml){
int start = xml.indexOf("");
int end = xml.indexOf("");
if(start < 0 && end < 0){
return null;
}
return xml.substring(start + "".length(),end)
.replace("","");
}
}