本人琢磨微信支付好几天了,终于完成了,下面是开发微信支付的流程:
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<Object, Object> parameters = new TreeMap<Object, Object>();
-
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);
-
}
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<String, Object> 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<String, Object> 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<String, String> sign(String url, String chatSet) {
-
Map<String, String> ret = new HashMap<String, String>();
-
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<Object, Object> 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<Object, Object> 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<Object, Object> parameters) {
-
StringBuffer sb = new StringBuffer();
-
sb.append("<xml>");
-
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 + ">" + "<![CDATA[" + v + "]]></" + k + ">");
-
} else {
-
sb.append("<" + k + ">" + v + "</" + k + ">");
-
}
-
}
-
sb.append("</xml>");
-
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<String> 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<String> 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 =
-
// "key=j0r53nmbbd78x7m1pqml06u2&type=1&[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<String, String> getAddressByLatlat(String lng, String lat) {
-
String str = "http://api.map.baidu.com/geocoder?output=json&location="
-
+ lat + "," + lng + "&key=37492c0ee6f924cb5e934fa08c6b167";
-
Map<String, String> map = new HashMap<String, String>();
-
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<String, String> getAddressByCity(String city) {
-
String str = "http://api.map.baidu.com/geocoder/v2/?ak=E4805d16520de693a3fe707cdc962045&callback=renderOption&output=json&address="
-
+ city + "&city=" + city;
-
Map<String, String> map = new HashMap<String, String>();
-
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<String, String> 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<String, String> map = new HashMap<String, String>();
-
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\" }" ;其中属性名必须带双引号<br/>
-
* @return 成功:返回json字符串<br/>
-
*/
-
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<String, Object> 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<Object, Object> parameters = new TreeMap<Object, Object>();
-
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<Object, Object> parameters = new TreeMap<Object, Object>();
-
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方法里)
String paySign=WeiXinUtils.getPaySignByWeiXin(timeStamp, nonceStr, "prepay_id="+getPrepayId);
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<ordernumlist.size();i++){
-
Object obj=ordernumlist.get(i);
-
//JSONObject obj = ordernumlist.getJSONObject(i);
-
//String ordernum=obj.getString("ordernum");
-
numlist[i]=obj.toString();
-
num=num+obj;
-
}
-
for(int j=0;j<numlist.length;j++){
-
if(numlist[j]==null)
-
break;
-
TOrder order=orderService.findOrderByNumber(numlist[j]);
-
List<TOrderGoods> ordergoods=orderGoodsService.findOrderGoodsByNumber(numlist[j]);
-
System.out.println(Double.parseDouble(order.getSumPrice()));
-
sumPrice=sumPrice+Double.parseDouble(order.getSumPrice());
-
for(int i=0;i<ordergoods.size();i++){
-
body=body+","+ordergoods.get(i).getGoodsName();
-
}
-
}
-
String getPrepayId = WeiXinUtils.getPayOrderByWeiXin(openid,String.valueOf(sumPrice*100),userIp,url,body,num+timeStamp);
-
System.out.println(getPrepayId);
-
String paySign=WeiXinUtils.getPaySignByWeiXin(timeStamp, nonceStr, "prepay_id="+getPrepayId);
-
System.out.println(paySign);
-
WeiXinVO v =new WeiXinVO();
-
v.setAppId(WeiXinUtils.APP_ID);
-
v.setTimeStamp(timeStamp);
-
v.setNonceStr(nonceStr);
-
v.set_package("prepay_id="+getPrepayId);
-
v.setSignType("MD5");
-
v.setPaySign(paySign);
-
v.setUrl(url);
-
System.out.println("appId="+WeiXinUtils.APP_ID);
-
System.out.println("timeStamp="+timeStamp);
-
System.out.println("nonceStr="+nonceStr);
-
System.out.println("package=prepay_id="+getPrepayId);
-
System.out.println("signType=MD5");
-
System.out.println("paySign="+paySign);
-
return writeJson(cmd, SUCCESS_CODE, "查询成功", v);
-
}
8.注意paySign签名的timeStamp、nonceStr与最后发送给微信的timeStamp、nonceStr要一致,MD5加密的sign要转化成大写。
9.调起微信支付,把appId,timeStamp,nonceStr,package,signType,paySign返回给微信,就OK了,另外回调页面下次再贴代码。