日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

Java开发微信支付流程及容易入坑的点

發布時間:2023/12/3 java 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java开发微信支付流程及容易入坑的点 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

本人琢磨微信支付好幾天了,終于完成了,下面是開發微信支付的流程:

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&toemail=jiucool@gmail.com" +

  • // "&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了,另外回調頁面下次再貼代碼。

    總結

    以上是生活随笔為你收集整理的Java开发微信支付流程及容易入坑的点的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。