本人琢磨微信支付好几天了,终于完成了,下面是开发微信支付的流程:
1.先要有认证后的微信服务号,然后申请开通微信支付功能,通过之后,腾讯会跟你发一封邮件,如下图:
2.配置好微信支付的支付授权目录(配置错误,支付时微信会返回:http://ki.hdh.com/kjjk/jh未注册错误)
3.我们要参照微信传的参数,如下图:
4.生成prepay_id(在WeiXinUtils工具类里)
String getPrepayId = WeiXinUtils.getPayOrderByWeiXin(openid,String.valueOf(sumPrice*100),userIp,url,body,num+timeStamp);
public static String getPayOrderByWeiXin(String opentId, String total_fee, String userIp, String notifyUrl, String body, String orderNumber) {
SortedMap
5.工具类
package com.naonao.cmall.utils;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Formatter;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.SortedMap;
import java.util.UUID;
import org.springframework.cache.annotation.Cacheable;
import com.naonao.cmall.utils.http.HttpClient;
public class Sign {
@Cacheable(value="baseCache")
public static String getToken() {
String s = HttpClient.sendGet(
"https://api.weixin.qq.com/cgi-bin/token",
"grant_type=client_credential&appid=" + WeiXinUtils.APP_ID
+ "&secret=" + WeiXinUtils.APP_SECRET);
HashMap json = JsonUtil.stringToTObj(s, HashMap.class);
String token = json.get("access_token").toString();
return token;
}
@Cacheable(value="baseCache")
public static String getTicket() {
String token = Sign.getToken();
String s1 = HttpClient.sendGet(
"https://api.weixin.qq.com/cgi-bin/ticket/getticket",
"access_token=" + token + "&type=jsapi");
HashMap json1 = JsonUtil
.stringToTObj(s1, HashMap.class);
return json1.get("ticket").toString();
}
public static String getNonceStr() {
return create_timestamp();
}
//chatSet SHA-1 or MD5
public static Map sign(String url, String chatSet) {
Map ret = new HashMap();
String nonce_str = create_nonce_str();
String timestamp = create_timestamp();
String string1;
String signature = "";
String jsapi_ticket = getTicket();
// 注意这里参数名必须全部小写,且必须有序
string1 = "jsapi_ticket=" + jsapi_ticket + "&noncestr=" + nonce_str
+ "×tamp=" + timestamp + "&url=" + url;
// System.out.println(string1);
try {
MessageDigest crypt = MessageDigest.getInstance(chatSet);
crypt.reset();
crypt.update(string1.getBytes("UTF-8"));
signature = byteToHex(crypt.digest());
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
ret.put("url", url);
ret.put("jsapi_ticket", jsapi_ticket);
ret.put("nonceStr", nonce_str);
ret.put("timestamp", timestamp);
ret.put("signature", signature);
for (Map.Entry entry : ret.entrySet()) {
System.out.println(entry.getKey() + ", " + entry.getValue());
}
return ret;
}
private static String byteToHex(final byte[] hash) {
Formatter formatter = new Formatter();
for (byte b : hash) {
formatter.format("%02x", b);
}
String result = formatter.toString();
formatter.close();
return result;
}
private static String create_nonce_str() {
return UUID.randomUUID().toString();
}
private static String create_timestamp() {
return Long.toString(System.currentTimeMillis() / 1000);
}
public static String createSign(String characterEncoding, SortedMap parameters) {
StringBuffer sb = new StringBuffer();
Set es = parameters.entrySet();
Iterator it = es.iterator();
while (it.hasNext()) {
Map.Entry entry = (Map.Entry) it.next();
String k = (String) entry.getKey();
Object v = entry.getValue();
if (null != v && !"".equals(v) && !"sign".equals(k)
&& !"key".equals(k)) {
sb.append(k + "=" + v + "&");
}
}
sb.append("key=" + WeiXinUtils.APP_KEY);
String sign = MD5Util.MD5Encode(sb.toString(), characterEncoding).toUpperCase();
return sign;
}
public static String paySign(String characterEncoding, SortedMap parameters) {
StringBuffer sb = new StringBuffer();
Set es = parameters.entrySet();
Iterator it = es.iterator();
while (it.hasNext()) {
Map.Entry entry = (Map.Entry) it.next();
String k = (String) entry.getKey();
Object v = entry.getValue();
if (null != v && !"".equals(v) && !"sign".equals(k)
&& !"key".equals(k)) {
sb.append(k + "=" + v + "&");
}
}
//sb.replace(sb.length()-1, sb.length(), "?");
sb.append("key=" + WeiXinUtils.APP_KEY);
//sb.append("params=value");
System.out.println(sb);
String sign = MD5Util.MD5Encode(sb.toString(), characterEncoding).toUpperCase();
return sign;
}
}
package com.naonao.cmall.utils;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.SortedMap;
import javax.servlet.http.HttpServletRequest;
public class Utils {
// MD5加密
public static String getMd5(String plainText) {
try {
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(plainText.getBytes());
byte b[] = md.digest();
int i;
StringBuffer buf = new StringBuffer("");
for (int offset = 0; offset < b.length; offset++) {
i = b[offset];
if (i < 0)
i += 256;
if (i < 16)
buf.append("0");
buf.append(Integer.toHexString(i));
}
// 32
return buf.toString();
// 16
// return buf.toString().substring(8, 24);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
return null;
}
}
public static String getRemortIP(HttpServletRequest request) {
if (request.getHeader("x-forwarded-for") == null) {
return request.getRemoteAddr();
}
return request.getHeader("x-forwarded-for");
}
public static String encode(String str) {
try {
return java.net.URLEncoder.encode(str, "UTF-8");
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return str;
}
public static String getRequestXml(SortedMap parameters) {
StringBuffer sb = new StringBuffer();
sb.append("");
Set es = parameters.entrySet();
Iterator it = es.iterator();
while (it.hasNext()) {
Map.Entry entry = (Map.Entry) it.next();
String k = (String) entry.getKey();
String v = (String) entry.getValue();
if ("attach".equalsIgnoreCase(k) || "body".equalsIgnoreCase(k)
|| "sign".equalsIgnoreCase(k)) {
sb.append("<" + k + ">" + "" + k + ">");
} else {
sb.append("<" + k + ">" + v + "" + k + ">");
}
}
sb.append(" ");
return sb.toString();
}
public static String getOutTradeNo(Integer userId, Integer shopId) {
return userId + "c" + shopId + "c" + (new Date()).getTime();
}
/**
* 利用反射实现对象之间属性复制
*
* @param from
* @param to
*/
public static void copyProperties(Object from, Object to) throws Exception {
copyPropertiesExclude(from, to, null);
}
/**
* 复制对象属性
*
* @param from
* @param to
* @param excludsArray
* 排除属性列表
* @throws Exception
*/
public static void copyPropertiesExclude(Object from, Object to,
String[] excludsArray) throws Exception {
List excludesList = null;
if (excludsArray != null && excludsArray.length > 0) {
excludesList = Arrays.asList(excludsArray); // 构造列表对象
}
Method[] fromMethods = from.getClass().getDeclaredMethods();
Method[] toMethods = to.getClass().getDeclaredMethods();
Method fromMethod = null, toMethod = null;
String fromMethodName = null, toMethodName = null;
for (int i = 0; i < fromMethods.length; i++) {
fromMethod = fromMethods[i];
fromMethodName = fromMethod.getName();
if (!fromMethodName.contains("get"))
continue;
// 排除列表检测
if (excludesList != null
&& excludesList.contains(fromMethodName.substring(3)
.toLowerCase())) {
continue;
}
toMethodName = "set" + fromMethodName.substring(3);
toMethod = findMethodByName(toMethods, toMethodName);
if (toMethod == null)
continue;
Object value = fromMethod.invoke(from, new Object[0]);
if (value == null)
continue;
// 集合类判空处理
if (value instanceof Collection) {
Collection newValue = (Collection) value;
if (newValue.size() <= 0)
continue;
}
toMethod.invoke(to, new Object[] { value });
}
}
/**
* 对象属性值复制,仅复制指定名称的属性值
*
* @param from
* @param to
* @param includsArray
* @throws Exception
*/
public static void copyPropertiesInclude(Object from, Object to,
String[] includsArray) throws Exception {
List includesList = null;
if (includsArray != null && includsArray.length > 0) {
includesList = Arrays.asList(includsArray); // 构造列表对象
} else {
return;
}
Method[] fromMethods = from.getClass().getDeclaredMethods();
Method[] toMethods = to.getClass().getDeclaredMethods();
Method fromMethod = null, toMethod = null;
String fromMethodName = null, toMethodName = null;
for (int i = 0; i < fromMethods.length; i++) {
fromMethod = fromMethods[i];
fromMethodName = fromMethod.getName();
if (!fromMethodName.contains("get"))
continue;
// 排除列表检测
String str = fromMethodName.substring(3);
if (!includesList.contains(str.substring(0, 1).toLowerCase()
+ str.substring(1))) {
continue;
}
toMethodName = "set" + fromMethodName.substring(3);
toMethod = findMethodByName(toMethods, toMethodName);
if (toMethod == null)
continue;
Object value = fromMethod.invoke(from, new Object[0]);
if (value == null)
continue;
// 集合类判空处理
if (value instanceof Collection) {
Collection newValue = (Collection) value;
if (newValue.size() <= 0)
continue;
}
toMethod.invoke(to, new Object[] { value });
}
}
/**
* 从方法数组中获取指定名称的方法
*
* @param methods
* @param name
* @return
*/
public static Method findMethodByName(Method[] methods, String name) {
for (int j = 0; j < methods.length; j++) {
if (methods[j].getName().equals(name))
return methods[j];
}
return null;
}
/**
* map 转 Bean
*
* @param map
* @param cls
* @return
*/
public static Object map2Bean(Map map, Class cls) {
Object obj = null;
try {
obj = cls.newInstance();
} catch (Exception e) {
e.printStackTrace();
}
// 取出bean里的所有方法
Method[] methods = cls.getMethods();
for (int i = 0; i < methods.length; i++) {
// 取方法名
String method = methods[i].getName();
// 取出方法的类型
Class[] cc = methods[i].getParameterTypes();
if (cc.length != 1)
continue;
// 如果方法名没有以set开头的则退出本次for
if (method.indexOf("set") < 0)
continue;
// 类型
String type = cc[0].getSimpleName();
try {
// 转成小写
// Object value = method.substring(3).toLowerCase();
Object value = method.substring(3, 4).toLowerCase()
+ method.substring(4);
// 如果map里有该key
if (map.containsKey(value) && map.get(value) != null) {
// 调用其底层方法
setValue(type, map.get(value), i, methods, obj);
}
} catch (Exception e) {
e.printStackTrace();
}
}
return obj;
}
/**
* 调用底层方法设置值
*/
private static void setValue(String type, Object value, int i,
Method[] method, Object bean) {
if (value != null && !value.equals("")) {
try {
if (type.equals("String")) {
// 第一个参数:从中调用基础方法的对象 第二个参数:用于方法调用的参数
method[i].invoke(bean, new Object[] { value });
} else if (type.equals("int") || type.equals("Integer")) {
method[i].invoke(bean, new Object[] { new Integer(""
+ value) });
} else if (type.equals("double") || type.equals("Double")) {
method[i].invoke(bean,
new Object[] { new Double("" + value) });
} else if (type.equals("float") || type.equals("Float")) {
method[i].invoke(bean,
new Object[] { new Float("" + value) });
} else if (type.equals("long") || type.equals("Long")) {
method[i].invoke(bean,
new Object[] { new Long("" + value) });
} else if (type.equals("boolean") || type.equals("Boolean")) {
method[i].invoke(bean,
new Object[] { Boolean.valueOf("" + value) });
} else if (type.equals("BigDecimal")) {
method[i].invoke(bean, new Object[] { new BigDecimal(""
+ value) });
} else if (type.equals("Date")) {
Date date = null;
if (value.getClass().getName().equals("java.util.Date")) {
date = (Date) value;
} else {
String format = ((String) value).indexOf(":") > 0 ? "yyyy-MM-dd hh:mm:ss"
: "yyyy-MM-dd";
SimpleDateFormat sf = new SimpleDateFormat();
sf.applyPattern(format);
date = sf.parse((String) (value));
}
if (date != null) {
method[i].invoke(bean, new Object[] { date });
}
} else if (type.equals("byte[]")) {
method[i].invoke(bean,
new Object[] { new String(value + "").getBytes() });
}
} catch (Exception e) {
System.out
.println("将linkHashMap 或 HashTable 里的值填充到javabean时出错,请检查!");
e.printStackTrace();
}
}
}
/** 计算年龄 */
public static String getAge(Date birthDay) throws Exception {
Calendar cal = Calendar.getInstance();
if (cal.before(birthDay)) {
throw new IllegalArgumentException(
"The birthDay is before Now.It's unbelievable!");
}
int yearNow = cal.get(Calendar.YEAR);
int monthNow = cal.get(Calendar.MONTH) + 1;
int dayOfMonthNow = cal.get(Calendar.DAY_OF_MONTH);
cal.setTime(birthDay);
int yearBirth = cal.get(Calendar.YEAR);
int monthBirth = cal.get(Calendar.MONTH);
int dayOfMonthBirth = cal.get(Calendar.DAY_OF_MONTH);
int age = yearNow - yearBirth;
if (monthNow <= monthBirth) {
if (monthNow == monthBirth) {
// monthNow==monthBirth
if (dayOfMonthNow < dayOfMonthBirth) {
age--;
}
} else {
// monthNow>monthBirth
age--;
}
}
return age + "";
}
public static String getStringByFloat(Float d1) {
DecimalFormat Formator = new DecimalFormat("###.##");
return Formator.format(d1);
}
}
package com.naonao.cmall.utils.http;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.ConnectException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.util.HashMap;
import java.util.Map;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.alibaba.fastjson.JSONObject;
import com.naonao.cmall.utils.MyX509TrustManager;
public class PostRequest {
private static final Logger log = LoggerFactory
.getLogger(PostRequest.class);
public static String GET_URL = "";
public static String POST_URL = "";
public static String readContentFromGet() throws IOException {
String getURL = GET_URL;
URL getUrl = new URL(getURL);
// 根据拼凑的URL,打开连接,URL.openConnection函数会根据URL的类型,
// 返回不同的URLConnection子类的对象,这里URL是一个http,因此实际返回的是HttpURLConnection
HttpURLConnection connection = (HttpURLConnection) getUrl
.openConnection();
// 进行连接,但是实际上get request要在下一句的connection.getInputStream()函数中才会真正发到
// 服务器
connection.connect();
// 取得输入流,并使用Reader读取
BufferedReader reader = new BufferedReader(new InputStreamReader(
connection.getInputStream(), "utf-8"));// 设置编码,否则中文乱码
String line = "";
String lines = "";
while ((line = reader.readLine()) != null) {
// line = new String(line.getBytes(), "utf-8");
lines += line.trim();
}
reader.close();
// 断开连接
connection.disconnect();
return lines;
}
public static void contentFromGet() throws IOException {
String getURL = GET_URL;
URL getUrl = new URL(getURL);
// 根据拼凑的URL,打开连接,URL.openConnection函数会根据URL的类型,
// 返回不同的URLConnection子类的对象,这里URL是一个http,因此实际返回的是HttpURLConnection
HttpURLConnection connection = (HttpURLConnection) getUrl
.openConnection();
// 进行连接,但是实际上get request要在下一句的connection.getInputStream()函数中才会真正发到
// 服务器
connection.connect();
}
public static String readContentFromPost() throws IOException {
// Post请求的url,与get不同的是不需要带参数
URL postUrl = new URL(POST_URL);
// 打开连接
HttpURLConnection connection = (HttpURLConnection) postUrl
.openConnection();
// Output to the connection. Default is
// false, set to true because post
// method must write something to the
// connection
// 设置是否向connection输出,因为这个是post请求,参数要放在
// http正文内,因此需要设为true
connection.setDoOutput(true);
// Read from the connection. Default is true.
connection.setDoInput(true);
// Set the post method. Default is GET
connection.setRequestMethod("POST");
// Post cannot use caches
// Post 请求不能使用缓存
connection.setUseCaches(false);
// This method takes effects to
// every instances of this class.
// URLConnection.setFollowRedirects是static函数,作用于所有的URLConnection对象。
// connection.setFollowRedirects(true);
// This methods only
// takes effacts to this
// instance.
// URLConnection.setInstanceFollowRedirects是成员函数,仅作用于当前函数
connection.setInstanceFollowRedirects(true);
// Set the content type to urlencoded,
// because we will write
// some URL-encoded content to the
// connection. Settings above must be set before connect!
// 配置本次连接的Content-type,配置为application/x-www-form-urlencoded的
// 意思是正文是urlencoded编码过的form参数,下面我们可以看到我们对正文内容使用URLEncoder.encode
// 进行编码
connection.setRequestProperty("Content-Type",
"application/x-www-form-urlencoded");
// 连接,从postUrl.openConnection()至此的配置必须要在connect之前完成,
// 要注意的是connection.getOutputStream会隐含的进行connect。
connection.connect();
DataOutputStream out = new DataOutputStream(
connection.getOutputStream());
// The URL-encoded contend
// 正文,正文内容其实跟get的URL中'?'后的参数字符串一致
// String content =
// "[email protected]" +
// "&activatecode=" + URLEncoder.encode("久酷博客", "utf-8");
// DataOutputStream.writeBytes将字符串中的16位的unicode字符以8位的字符形式写道流里面
// out.writeBytes(content);
out.flush();
out.close(); // flush and close
BufferedReader reader = new BufferedReader(new InputStreamReader(
connection.getInputStream(), "utf-8"));// 设置编码,否则中文乱码
String line = "";
String lines = "";
while ((line = reader.readLine()) != null) {
// line = new String(line.getBytes(), "utf-8");
lines += line.trim();
}
reader.close();
connection.disconnect();
return lines;
}
/**
* 经纬度
*
* @param lng
* @param lat
* @return
*/
public static Map getAddressByLatlat(String lng, String lat) {
String str = "http://api.map.baidu.com/geocoder?output=json&location="
+ lat + "," + lng + "&key=37492c0ee6f924cb5e934fa08c6b167";
Map map = new HashMap();
try {
PostRequest.POST_URL = str;
String line = PostRequest.readContentFromPost();
JSONObject jsonObj = JSONObject.parseObject(line);
String result = jsonObj.getString("result");
JSONObject jsonObj2 = JSONObject.parseObject(result);
String cityCode = jsonObj2.getString("cityCode");
String formattedAddress = jsonObj2.getString("formatted_address");
JSONObject jsonObj3 = JSONObject.parseObject(jsonObj2
.getString("addressComponent"));
String city = jsonObj3.getString("city");
map.put("cityCode", cityCode);
map.put("formattedAddress", formattedAddress);
map.put("city", city);
} catch (IOException e) {
e.printStackTrace();
}
return map;
}
/**
* 城市
*
* @param city
* @return
*/
public static Map getAddressByCity(String city) {
String str = "http://api.map.baidu.com/geocoder/v2/?ak=E4805d16520de693a3fe707cdc962045&callback=renderOption&output=json&address="
+ city + "&city=" + city;
Map map = new HashMap();
try {
PostRequest.POST_URL = str;
String line = PostRequest.readContentFromPost();
JSONObject jsonObj = JSONObject.parseObject(line);
String result = jsonObj.getString("result");
JSONObject jsonObj2 = JSONObject.parseObject(result);
String cityCode = jsonObj2.getString("cityCode");
String formattedAddress = jsonObj2.getString("formatted_address");
map.put("cityCode", cityCode);
map.put("formattedAddress", formattedAddress);
map.put("city", city);
} catch (IOException e) {
e.printStackTrace();
}
return map;
}
/**
* 城市
*
* @param city
* @return
*/
public static Map getQQMessages(String access_token,
String openid) {
String qqUrl = "https://graph.qq.com/user/get_user_info?oauth_consumer_key=100330589&access_token="
+ access_token + "&openid=" + openid + "&format=json";
Map map = new HashMap();
try {
PostRequest.GET_URL = qqUrl;
String line = PostRequest.readContentFromGet();
JSONObject jsonObj = JSONObject.parseObject(line);
String nickname = jsonObj.getString("nickname");
String gender = jsonObj.getString("gender");
String url = jsonObj.getString("figureurl_qq_1");
map.put("nickname", nickname);
map.put("gender", gender);
map.put("url", url);
map.put("openid", openid);
} catch (IOException e) {
e.printStackTrace();
}
return map;
}
public static void main(String[] args) {
PostRequest.GET_URL="http://mc-storage.b0.upaiyun.com/song_lib/lrc/20140702/Y2014060133.txt";
String line;
try {
line = PostRequest.readContentFromGet();
System.out.println(line);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 用传统的URI类进行请求
* @param urlStr
*/
public static String post(String urlStr,String xmlInfo) {
String line = "";
try {
URL url = new URL(urlStr);
URLConnection con = url.openConnection();
con.setDoOutput(true);
con.setRequestProperty("Pragma:", "no-cache");
con.setRequestProperty("Cache-Control", "no-cache");
con.setRequestProperty("Content-Type", "text/xml");
OutputStreamWriter out = new OutputStreamWriter(con.getOutputStream());
// System.out.println("xmlInfo=" + xmlInfo);
out.write(new String(xmlInfo.getBytes("UTF-8")));
out.flush();
out.close();
BufferedReader br = new BufferedReader(new InputStreamReader(con
.getInputStream()));
for (line = br.readLine(); line != null; line = br.readLine()) {
line+=line;
}
} catch (Exception e) {
e.printStackTrace();
}
return line;
}
/**
* 发送https请求
* @param requestUrl 请求地址
* @param requestMethod 请求方式(GET、POST)
* @param outputStr 提交的数据
* @return 返回微信服务器响应的信息
*/
public static String httpsRequest(String requestUrl, String requestMethod, String outputStr) {
try {
// 创建SSLContext对象,并使用我们指定的信任管理器初始化
TrustManager[] tm = { new MyX509TrustManager() };
SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
sslContext.init(null, tm, new java.security.SecureRandom());
// 从上述SSLContext对象中得到SSLSocketFactory对象
SSLSocketFactory ssf = sslContext.getSocketFactory();
URL url = new URL(requestUrl);
HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
conn.setSSLSocketFactory(ssf);
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setUseCaches(false);
// 设置请求方式(GET/POST)
conn.setRequestMethod(requestMethod);
conn.setRequestProperty("content-type", "application/x-www-form-urlencoded");
// 当outputStr不为null时向输出流写数据
if (null != outputStr) {
OutputStream outputStream = conn.getOutputStream();
// 注意编码格式
outputStream.write(outputStr.getBytes("UTF-8"));
outputStream.close();
}
// 从输入流读取返回内容
InputStream inputStream = conn.getInputStream();
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
String str = null;
StringBuffer buffer = new StringBuffer();
while ((str = bufferedReader.readLine()) != null) {
buffer.append(str);
}
// 释放资源
bufferedReader.close();
inputStreamReader.close();
inputStream.close();
inputStream = null;
conn.disconnect();
return buffer.toString();
} catch (ConnectException ce) {
log.error("连接超时:{}", ce);
} catch (Exception e) {
log.error("https请求异常:{}", e);
}
return null;
}
/**
* 发送HttpPost请求
*
* @param strURL
* 服务地址
* @param params
* json字符串,例如: "{ \"id\":\"12345\" }" ;其中属性名必须带双引号
* @return 成功:返回json字符串
*/
public static String postByJson(String strURL, String params) {
System.out.println(strURL);
System.out.println(params);
try {
URL url = new URL(strURL);// 创建连接
HttpURLConnection connection = (HttpURLConnection) url
.openConnection();
connection.setDoOutput(true);
connection.setDoInput(true);
connection.setUseCaches(false);
connection.setInstanceFollowRedirects(true);
connection.setRequestMethod("POST"); // 设置请求方式
connection.setRequestProperty("Accept", "application/json"); // 设置接收数据的格式
connection.setRequestProperty("Content-Type", "application/json"); // 设置发送数据的格式
connection.connect();
OutputStreamWriter out = new OutputStreamWriter(
connection.getOutputStream(), "UTF-8"); // utf-8编码
out.append(params);
out.flush();
out.close();
// 读取响应
int length = (int) connection.getContentLength();// 获取长度
InputStream is = connection.getInputStream();
if (length != -1) {
byte[] data = new byte[length];
byte[] temp = new byte[512];
int readLen = 0;
int destPos = 0;
while ((readLen = is.read(temp)) > 0) {
System.arraycopy(temp, 0, data, destPos, readLen);
destPos += readLen;
}
String result = new String(data, "UTF-8"); // utf-8编码
System.out.println(result);
return result;
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return "error"; // 自定义错误信息
}
}
package com.naonao.cmall.utils;
import java.io.IOException;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;
import org.jdom.JDOMException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.naonao.cmall.utils.http.HttpUtil;
import com.naonao.cmall.utils.http.PostRequest;
public class WeiXinUtils {
private static final Logger log = LoggerFactory.getLogger(WeiXinUtils.class);
/** 微信开发平台应用appid */
public static final String APP_ID = "***";
/**
*
*/
//public static final String noncestr="***";
/** 微信开发平台应用appsecret */
public static final String APP_SECRET = "***";
/**
* 随机字符串
*/
public static final String nonceStr="***";
/** 商户号 */
public static final String MCH_ID = "***";
// 应用对应的密钥
public static final String APP_KEY = "***";
// 微信公众号api
public static final String REDIRECT_URI = "***"; // 授权回调
public static final String PAY_URI = "***";// 支付回调
public static final String SCOPE = "snsapi_userinfo";
public static String GetOpenIdRequest = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&grant_type=authorization_code";
public static String unifiedOrder = "https://api.mch.weixin.qq.com/pay/unifiedorder";
/**
* weixin地址封装
*
* @return
*/
public static String getCodeRequest(String url) {
String GetCodeRequest = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect";
String result = null;
GetCodeRequest = GetCodeRequest.replace("APPID", urlEnodeUTF8(APP_ID));
GetCodeRequest = GetCodeRequest.replace("SCOPE", SCOPE);
GetCodeRequest = GetCodeRequest.replace("REDIRECT_URI", urlEnodeUTF8(REDIRECT_URI));
GetCodeRequest = GetCodeRequest.replace("STATE", url);
result = GetCodeRequest;
log.info("================================");
log.info(url);
log.info(GetCodeRequest);
log.info("================================");
return result;
}
/**
* weixin地址封装
*
* @return
*/
public static String getOpenIdRequest() {
String result = null;
GetOpenIdRequest = GetOpenIdRequest.replace("APPID", urlEnodeUTF8(APP_ID));
GetOpenIdRequest = GetOpenIdRequest.replace("SECRET", urlEnodeUTF8(APP_SECRET));
result = GetOpenIdRequest;
return result;
}
/**
* 链接转码
*
* @param str
* @return
*/
public static String urlEnodeUTF8(String str) {
String result = str;
try {
result = URLEncoder.encode(str, "UTF-8");
} catch (Exception e) {
log.error("WeiXinUtils getCodeRequest urlEnodeUTF8:{}", str);
e.printStackTrace();
}
return result;
}
/**
* 通过code获取openId
*
* @param codeResult
* @return
*/
public static String getOpenId(String codeResult) {
String openid = "";
try {
String openIdUrl = WeiXinUtils.getOpenIdRequest();
PostRequest.GET_URL = openIdUrl + "&code=" + codeResult;
String s = PostRequest.readContentFromGet();
HashMap json = JsonUtil.stringToTObj(s, HashMap.class);
if (json != null && json.get("openid") != null) {
openid = json.get("openid").toString();
}
} catch (IOException e) {
e.printStackTrace();
}
return openid;
}
/**
* 微信支付
*
* @param opentId
* @param total_fee
* @param userIp
* @param notifyUrl
* @param body
* @param orderNumber
* @return
*/
public static String getPayOrderByWeiXin(String opentId, String total_fee, String userIp, String notifyUrl, String body, String orderNumber) {
SortedMap parameters = new TreeMap();
parameters.put("appid", APP_ID);
System.out.println("appid:"+APP_ID);
parameters.put("mch_id", MCH_ID);
System.out.println("mch_id:"+MCH_ID);
parameters.put("nonce_str", nonceStr);
System.out.println("nonce_str:"+"HZNAONAOCOM");
parameters.put("body", body);
System.out.println("body:"+body);
parameters.put("out_trade_no", orderNumber);
System.out.println("out_trade_no:"+orderNumber);
parameters.put("total_fee", total_fee.substring(0, total_fee.indexOf(".")));
System.out.println("total_fee="+total_fee.substring(0, total_fee.indexOf(".")));
parameters.put("spbill_create_ip", userIp);
System.out.println("spbill_create_ip="+userIp);
parameters.put("notify_url",notifyUrl );
System.out.println("notify_url="+notifyUrl);
parameters.put("trade_type", "JSAPI");
System.out.println("trade_type=JSAPI");
parameters.put("openid", opentId);
System.out.println("openid="+opentId);
String sign = Sign.createSign("UTF-8", parameters);
System.out.println("sign="+sign);
parameters.put("sign", sign);
String requestXML = Utils.getRequestXml(parameters);
System.out.println("requestXML="+requestXML);
String result = PostRequest.httpsRequest(unifiedOrder, "POST", requestXML);
System.out.println("prepay_id="+result);
return getPrepayId(result);
}
/*
* paySign
*/
public static String getPaySignByWeiXin(String timeStamp, String nonceStr, String _package) {
SortedMap parameters = new TreeMap();
parameters.put("appId", APP_ID);
System.out.println("appId="+APP_ID);
parameters.put("timeStamp", timeStamp);
System.out.println("timeStamp="+timeStamp);
parameters.put("nonceStr", nonceStr);
System.out.println("nonceStr="+nonceStr);
parameters.put("package", _package);
System.out.println("package="+_package);
parameters.put("signType", "MD5");
System.out.println("signType=MD5");
//parameters.put("key", APP_KEY);
String sign = Sign.paySign("UTF-8", parameters);
System.out.println("sign="+sign);
return sign;
}
private static String getPrepayId(String xml) {
String prepay_id = "";
try {
Map map = XMLUtil.doXMLParse(xml);
prepay_id = map.get("prepay_id").toString();
} catch (JDOMException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return prepay_id;
}
/**
* 微信下载文件
*
* @param name 本地文件名称
* @param media_id 微信图片ID
* @return
*/
public static String downloadFile(String name,String media_id) {
String downloadFile="http://file.api.weixin.qq.com/cgi-bin/media/get?access_token=ACCESS_TOKEN&media_id=MEDIA_ID";
String token=Sign.getToken();
downloadFile=downloadFile.replace("ACCESS_TOKEN", token);
downloadFile=downloadFile.replace("MEDIA_ID", media_id);
String path=Config.getMediaImgPath();
Date now = new Date();
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd");
path+=dateFormat.format(now)+"/"+name;
try {
HttpUtil.downloadFile(path, downloadFile);
} catch (IOException e) {
e.printStackTrace();
}
return path;
}
}
6.获取paysSign(签名的appId中的'I'大写,不然会报错,之前我这里卡了好长时间,getPaySignByWeiXin在WeiXinUtils方法里)
7.程序的入口
/**
* 微信支付
*/
public ModelAndView WeixinPay(String cmd, JSONObject request,HttpServletRequest httprequest, HttpServletResponse response) {
//"appId": "<%= appId %>", //公众号名称,由商户传入
//"timeStamp": "<%= timeStamp %>", //时间戳
//"nonceStr": "<%= nonceStr %>", //随机串
//"package": "<%= package %>", //扩展包
//"signType": "MD5", //微信签名方式:1.sha1
//"paySign": "<%= paySign %>" //微信签名
//String accessToken="";
//String ticket="";
String body="";
String num="";
Double sumPrice=0.0;
String userIp =Utils.getRemortIP(httprequest);
//if(userIp==""||userIp==null)
//userIp="127.0.0.1";
String timeStamp= Long.toString(new Date().getTime()/1000);
String nonceStr=WeiXinUtils.nonceStr; //"HZNAONAOCOM";
String openid =request.getString("openid");
String url = request.getString("url");
JSONArray ordernumlist = request.getJSONArray("ordernum");
if(StringUtils.isBlank(openid)||StringUtils.isBlank(url)||ordernumlist==null)
return writeNotParameters(cmd);
if(openid==""||openid==null)
openid="orLhutxu-XEXWPAB-1DewmJ89w8g";
if(url==""||url==null)
url="http://hznaonao.com/c_mall/pay.jsp";//调用JS接口页面的完整URL
//订单号
String[] numlist=new String[100];
for(int i=0;i ordergoods=orderGoodsService.findOrderGoodsByNumber(numlist[j]);
System.out.println(Double.parseDouble(order.getSumPrice()));
sumPrice=sumPrice+Double.parseDouble(order.getSumPrice());
for(int i=0;i
9.调起微信支付,把appId,timeStamp,nonceStr,package,signType,paySign返回给微信,就OK了,另外回调页面下次再贴代码。