1. 程式人生 > >微信支付APP端以及服務端(JavaEE)可以直接使用

微信支付APP端以及服務端(JavaEE)可以直接使用

最近在整合微信支付,不得不說微信文件就是坑,說的不明不白,還是支付寶簡單,

流程:

1、客戶端提交訂單——》到(自己平臺的)伺服器,引數與服務端協商

2、服務端拿到請求訂單資訊——》參考微信統一下單介面——》把必須傳的引數進行加密轉XML傳到微信伺服器

3、如果簽名正確,微信服務端會返回成功資訊 ——》XML格式——》解析XML——》

拿到預支付交易會話標識(prepay_id)這個是關鍵

4、拿到交易會話ID後,進行二次簽名 把下表資料按照第一次簽名規範進行簽名——》傳到客戶端


5、(注意)二次簽名的隨機字串(noncestr)不要再次生成新的字串,一定要是第一次簽名傳

微信伺服器那個保持一至。(這點微信文件沒有找到)

6、二次簽名的資料就可以傳到客戶端——》客戶端呼叫拿到資料就可以呼叫微信支付了

7、一定要是正式打包的apk才會有效果,否則不能調起微信支付,

8、微信開發平臺設定好包名,以及應用簽名就可以了





直接上程式碼


上面是調起微信支付關鍵程式碼,當然呼叫微信支付前一定要先註冊到微信 建議放到onCreate中

再說下服務端 簡單寫的測試下,直接複製就能用,

/**
 * Servlet implementation class PayHttpServlet
 */
@WebServlet("/PayHttpServlet")
public class PayHttpServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

	private String urlWx = "https://api.mch.weixin.qq.com/pay/unifiedorder";

	private String postType = "POST";

	private String result;

	private int price100 = -1;

	/**
	 * @see HttpServlet#HttpServlet()
	 */
	public PayHttpServlet() {
		super();
		// TODO Auto-generated constructor stub
	}

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		// TODO Auto-generated method stub
		// response.getWriter().append("Served at: ").append(request.getContextPath());
		doPost(request, response);
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		// TODO Auto-generated method stub
		// 設定編碼
		response.setContentType("text/html;charset=utf-8");
		request.setCharacterEncoding("utf-8");
		String price = request.getParameter("price");

		if (price == null || "".equals(price)) {
			// 返回客戶端資料
			System.out.print("引數有誤,金額不能為0");
			return;
		} else {
			price100 = new BigDecimal(price).multiply(new BigDecimal(100)).intValue();
			doconfig(request, response);
		}

	}

	private void doconfig(HttpServletRequest request, HttpServletResponse response) {
		// TODO Auto-generated method stub
		Map<String, Object> resultMap = new HashMap<String, Object>();
		SortedMap<String, Object> map = new TreeMap<>();
		map.put("appid", PayCommonUtil.APPID);
		map.put("mch_id", PayCommonUtil.MCH_ID);
		map.put("nonce_str", PayCommonUtil.getRandomString(30));
		// map.put("sign", value);
		map.put("trade_type", "APP");
		map.put("body", "APP測試支付");
		map.put("out_trade_no", PayCommonUtil.getRandomString(15));
		map.put("total_fee", String.valueOf(price100));
		map.put("spbill_create_ip", "113.113.157.124");//ip地址
		map.put("notify_url", "http://www.baidu.com");//非同步通知地址
		// 簽名
		String singA = PayCommonUtil.createSign("utf-8", map);
		map.put("sign", singA);
		// 請求封裝
		String urlData = PayCommonUtil.getRequestXml(map);
		System.out.println("xml=" + "\n" + urlData);
		// 呼叫下單介面,得到prepay_id預支付碼,重新簽名返回給app
		String result = PayCommonUtil.httpsRequest(urlWx, postType, urlData);
		// System.out.println("xml="+urlData);
		System.out.println("resultXML=" + "\n" + result);
		// 得到資料返回給app
		try {
			Map<String, Object> map2 = PayCommonUtil.doXMLParse(result);

			SortedMap<String, Object> mapApp = new TreeMap<>();
			mapApp.put("appid", PayCommonUtil.APPID);
			mapApp.put("partnerid", PayCommonUtil.MCH_ID);
			mapApp.put("prepayid", map2.get("prepay_id"));
			mapApp.put("package", "Sign=WXPay");
			mapApp.put("noncestr", map.get("nonce_str"));
			System.out.println("nonce_str=="+map.get("nonce_str"));
			// 時間戳
			mapApp.put("timestamp",
					String.valueOf(Long.parseLong(String.valueOf(System.currentTimeMillis()).substring(0, 10))));
			String signAPP = PayCommonUtil.createSign("utf-8", mapApp);
			mapApp.put("sign", signAPP);
			mapApp.put("status", "1");

			try {
				String object = new Gson().toJson(mapApp);
				JSONObject object2 = new JSONObject(object);
				System.out.println("json=" + "\n" + object2);
				// 返回客戶端資料
				PrintWriter out = response.getWriter();
				out.write(object2.toString());

				out.flush();
				out.close();
			} catch (JSONException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

			System.out.println("mapApp" + "\n" + mapApp);

		} catch (JDOMException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

}
public class PayCommonUtil {
	// 微信引數配置
	public static String API_KEY = "";
	public static String APPID = "";
	public static String MCH_ID = "";

	// 隨機字串生成
	public static String getRandomString(int length) { // length表示生成字串的長度
		String base = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
		Random random = new Random();
		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < length; i++) {
			int number = random.nextInt(base.length());
			sb.append(base.charAt(number));
		}
		return sb.toString();
	}

	// 請求xml組裝
	public static String getRequestXml(SortedMap<String, 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 key = (String) entry.getKey();
			String value = (String) entry.getValue();
			if ("attach".equalsIgnoreCase(key) || "body".equalsIgnoreCase(key) || "sign".equalsIgnoreCase(key)) {
				sb.append("<" + key + ">" + "<![CDATA[" + value + "]]></" + key + ">");
			} else {
				sb.append("<" + key + ">" + value + "</" + key + ">");
			}
		}
		sb.append("</xml>");
		return sb.toString();
	}

	/**
	 * 所有引數除sign外,按照ASCII碼排序,
	 */
	public static String buildASCiiParams(Map<String, Object> params) {
		StringBuffer stringBuffer = new StringBuffer();// 存放資料
		// 按照ASCII碼進行排序
		Map<String, Object> sortMap = new TreeMap<String, Object>(params);
		// 便利字典,拼接"key=value&key=value"
		for (Map.Entry<String, Object> m : sortMap.entrySet()) {
			if (stringBuffer.length() > 0) {
				stringBuffer.append("&");
			}
			stringBuffer.append(m.getKey()).append("=").append(m.getValue());
		}
		return stringBuffer.toString();
	}

	// 生成簽名
	public static String createSign(String characterEncoding, SortedMap<String, 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=" + API_KEY);
		String sign = MD5Utils.MD5Encode(sb.toString(), characterEncoding).toUpperCase();
		return sign;
	}

	// 請求方法
	public static String httpsRequest(String requestUrl, String requestMethod, String outputStr) {
		try {

			URL url = new URL(requestUrl);
			HttpURLConnection conn = (HttpURLConnection) url.openConnection();

			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 = (OutputStream) conn.getOutputStream();
				// 注意編碼格式
				outputStream.write(outputStr.getBytes("UTF-8"));
				outputStream.close();
			}
			// 從輸入流讀取返回內容
			InputStream 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) {
			System.out.println("連線超時:{}" + ce);
		} catch (Exception e) {
			System.out.println("https請求異常:{}" + e);
		}
		return null;
	}

	// xml解析
	public static Map doXMLParse(String strxml) throws JDOMException, IOException {
		strxml = strxml.replaceFirst("encoding=\".*\"", "encoding=\"UTF-8\"");

		if (null == strxml || "".equals(strxml)) {
			return null;
		}

		Map m = new HashMap();

		InputStream in = new ByteArrayInputStream(strxml.getBytes("UTF-8"));
		SAXBuilder builder = new SAXBuilder();
		Document doc = builder.build(in);
		Element root = doc.getRootElement();
		List list = root.getChildren();
		Iterator it = list.iterator();
		while (it.hasNext()) {
			Element e = (Element) it.next();
			String k = e.getName();
			String v = "";
			List children = e.getChildren();
			if (children.isEmpty()) {
				v = e.getTextNormalize();
			} else {
				v = getChildrenText(children);
			}

			m.put(k, v);
		}

		// 關閉流
		in.close();

		return m;
	}

	public static String getChildrenText(List children) {
		StringBuffer sb = new StringBuffer();
		if (!children.isEmpty()) {
			Iterator it = children.iterator();
			while (it.hasNext()) {
				Element e = (Element) it.next();
				String name = e.getName();
				String value = e.getTextNormalize();
				List list = e.getChildren();
				sb.append("<" + name + ">");
				if (!list.isEmpty()) {
					sb.append(getChildrenText(list));
				}
				sb.append(value);
				sb.append("</" + name + ">");
			}
		}

		return sb.toString();
	}

}


相關推薦

通過生成支付二維碼來實現支付的解決方案 - EasyWechat版

ppi ppk 一個 segment url out -s easy 記得 上一篇我們講了在微信瀏覽器內實現微信支付的功能,它特別適合於一些基於微信公眾號的h5站點等,支付流程也相當流暢,但是... 還有一種情況,比如現在北哥兄弟連PC版,是生成了一個二維碼,這個二維碼

商城---傻瓜式教你支付收貨地址介面開發PHP

微信中比較好用的介面功能裡,微信收貨地址介面應該算一個,它本身提供了地址的新增刪除使用,可以使微商城省去收貨地址開發的步驟。微支付這個步驟並不難,本身有提供demo給你,稍微改改就能用,看一下概念也清晰了。收貨地址卻沒有。 此文章是以PHP來實現。 在做之前先確定自己有微信公眾平臺的賬號,並

支付APP以及服務JavaEE可以直接使用

最近在整合微信支付,不得不說微信文件就是坑,說的不明不白,還是支付寶簡單,流程:1、客戶端提交訂單——》到(自己平臺的)伺服器,引數與服務端協商2、服務端拿到請求訂單資訊——》參考微信統一下單介面——》把必須傳的引數進行加密轉XML傳到微信伺服器3、如果簽名正確,微信服務端會

php 版本 支付 APP 服務開發

我們通過 微信支付的文件知道 第一步 服務端需要呼叫統一下單介面生成預付單,其中主要的引數就是 prepay_id 這樣 app 通過 prepay_id 就可以發起支付請求了。 我們可以參考 微信支付的 官方SDK(就是個坑) 統一下單介面就是 呼叫函式

asp小程序獲取用戶頭像和名-asp寫的服務

詳細信息 openid total ont login urlencode hat console storage //index.js//獲取應用實例var app = getApp()Page({ data: { paydata: { title: "支付測試"

公眾號開發-實現服務回覆訊息為空

微信側提供的被動回覆使用者訊息文件: 如果你回覆 的是一個物件格式,content為“”,這時微信側會顯示: 如果你對使用者輸入的某些資訊不進行回覆,那麼你應該這樣做: private void noReply(HttpServletResponse respo

支付-App支付服務端詳解

微信App支付服務端詳解 引言 主要實現app支付統一下單、非同步通知、調起支付介面、支付訂單查詢、申請退款、查詢退款功能;封裝了https對發起退款的證書校驗、簽名、xml解析等。 支付流程 具體支付流程參考“微信APP”文件,文件地址 AP

小程式正式上線,服務請求必須HTTPS

1月9日凌晨微信小程式正式上線,首批上線的小程式有三百多家,使用者需要將微信更新至iOS6.5.3版本或Android6.5.3版本進行體驗。 微信小程式自9月份首次開啟內測就開始在圈內刷屏了,不需要下載安裝,“用完即走”的理念,使其被譽為“APP殺手”。微信龐大社交

公眾號開發---支付之H5頁面WAP接入

更新:2015年12月3日微信提供 Wap 支付, 開發者文件:【微信支付】開發者文件 1.前言 公司是通過支付寶和微信支付那塊內容獲取收入,app端已經接入成功,現在要做WAP端。需要頁面和後臺介面一起來實現。 2.介面接入 因為微信支付版本更新了,網上

用nodejs快速實現小程式的websocket服務

摘要: 微信小程式服務端使用websocket方式。socket.io已作為nodejs體系中被廣泛應用的websocket解決方案,卻因socket.io對websocket做了高階封裝,不能相容微信小程式所採用的websocket標準協議無法直接使用,此外微

公眾號項目服務測試實踐

mage 測試 微信開發 account count width con bubuko https 最近接觸微信公眾號項目的服務端測試,對具體的測試準備和流程做一下梳理和總結。 1、測試前的準備 1.1 下載微信開發者工具 https://developers.wei

支付app的各種坑

.info info nbsp clas fff style 輔助 font list android: 簽名要一致,要導出singed包 要記得重啟手機 如果別人的都可以支付,我的不可以,就要退出微信賬號,重新登陸微信賬號一下(不僅僅是退出微信應用)。 ios:

Java 關於生成WebService客戶以及服務存在賬號密碼登入如何通過程式碼模擬登入解決方案

首先,這篇文章主要是用來做一個記錄,方便以後使用,所以不會有太多關於webService以及wsdl的一些原理上的講解,主要是為了解決實際問題,即:如何生成webService客戶端去呼叫服務端,以及當服務端需要進行賬號密碼登入時,我們該如何模擬登入,來繼續呼叫裡面的介面。 主

全面詳細的支付思路流程以及專案程式碼分享

之前一直沒有接觸微信支付這方面的業務,現在因專案需要,需要用到此功能,開始各種百度,稍微瞭解了一下,微信支付分為: 支付寶支付、APP支付、掃碼支付,但是對於H5支付和支付寶支付現在還是沒有徹底搞明白他兩的區別,希望大佬們可以稍微提點一二,小弟先在此謝過! 大體思路如下: 1】.獲取co

支付獲取prepay_id以及回撥地址

/** * 微信獲取prepay_id 同時下單 * * @return * @throws Exception */ @RequestMapping(value = "/getPrepayId", method = RequestMethod.G

(Web、觸屏)支付功能呼叫以及QQ回撥地址配置、以及遇到的一些坑

/** * (觸屏版)跳轉游記支付二維碼頁 (介面返回表單如下) * <form id="lolapaysubmit" name="lolapaysubmit" action="https://wx.tenpay.com/cgi-bin/mmpayweb-bin/c

關於支付方面問題,以及支付返回-1的問題。千萬不要慌不要慌!

1.關於微信支付返回-1的問題從微信的官方文件來看,支付返回-1的都是ERR_COMM,也就是普通的,常見的錯誤。普通我倒是沒覺得,常見我倒是常常見。所有人都知道微信支付返回-1無非就是那幾個常見的錯誤,什麼sing錯誤,APP_ID錯誤什麼什麼的,但是很多情況都會返回-1,

支付----APP安卓,IOS調起支付所需引數,c#後臺介面

#region 微信APP支付介面 /// <summary> /// 微信APP支付介面 /// </summary> /// <param name="out_trade_no

手把手實現網頁授權和支付,附源代碼VUE and thinkPHP

nec ble 名單 ret 一次 hash 掃一掃 網頁 ada wechat github 手把手實現微信網頁授權和微信支付,附源代碼(VUE and thinkPHP) 概述 公眾號開發是痛苦的,痛苦在好多問題開發者文檔是沒有提到的,是需要你猜的. 在開發過程中翻

EXCHANGE客戶訪問服務CAS中的身份驗證方式

傳輸 郵箱服務器角色 找到 輸入 驗證 管理器 orm 虛擬 code 在部署完畢exchange後系統會自動建立IIS服務來響應相應的請求。客戶端訪問服務器(以下簡稱CAS)實質上是一臺IIS服務器,在服務器中部署一套名為“Default web site”的站點來完成O