1. 程式人生 > >java版app微信支付服務端程式碼【手機app微信支付】

java版app微信支付服務端程式碼【手機app微信支付】

老早就像做支付模組的東西,因為覺得很高大上,很早就開始把微信支付模組的重心簽名給做好了,一直就缺個商家的key,現在有幸來電商公司,哈哈,果然一切很順利,能夠很給力地App端提供支援;

個人覺得核心部分的程式碼:

簽名:

//引數:開始生成簽名
		SortedMap<Object,Object> parameters = new TreeMap<Object,Object>();
		parameters.put("appid", appid);
		parameters.put("mch_id", mch_id);
		parameters.put("nonce_str", nonce_str);
		parameters.put("body", body);
		parameters.put("nonce_str", nonce_str);
		parameters.put("detail", detail);
		parameters.put("attach", attach);
		parameters.put("out_trade_no", out_trade_no);
		parameters.put("total_fee", total_fee);
		parameters.put("time_start", time_start);
		parameters.put("time_expire", time_expire);
		parameters.put("notify_url", notify_url);
		parameters.put("trade_type", trade_type);
		parameters.put("spbill_create_ip", spbill_create_ip);

/**
	 * 微信支付簽名演算法sign
	 * @param characterEncoding
	 * @param parameters
	 * @return
	 */
	@SuppressWarnings("rawtypes")
	public static String createSign(String characterEncoding,SortedMap<Object,Object> parameters){
		StringBuffer sb = new StringBuffer();
		Set es = parameters.entrySet();//所有參與傳參的引數按照accsii排序(升序)
		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=" + Key);
		System.out.println("字串拼接後是:"+sb.toString());
		String sign = MD5Util.MD5Encode(sb.toString(), characterEncoding).toUpperCase();
		return sign;
	}

將一坨引數包裝成XML格式丟給微信:
/**
	 * 構造xml引數
	 * @param xml
	 * @return
	 */
	public static String xmlInfo(Unifiedorder unifiedorder){
		//構造xml引數的時候,至少有10個必傳引數
		/*
		 * <xml>
			   <appid>wx2421b1c4370ec43b</appid>
			   <attach>支付測試</attach>
			   <body>JSAPI支付測試</body>
			   <mch_id>10000100</mch_id>
			   <nonce_str>1add1a30ac87aa2db72f57a2375d8fec</nonce_str>
			   <notify_url>http://wxpay.weixin.qq.com/pub_v2/pay/notify.v2.php</notify_url>
			   <openid>oUpF8uMuAJO_M2pxb1Q9zNjWeS6o</openid>
			   <out_trade_no>1415659990</out_trade_no>
			   <spbill_create_ip>14.23.150.211</spbill_create_ip>
			   <total_fee>1</total_fee>
			   <trade_type>JSAPI</trade_type>
			   <sign>0CB01533B8C1EF103065174F50BCA001</sign>
			</xml>
		 */

		if(unifiedorder!=null){
			StringBuffer bf = new StringBuffer();
			bf.append("<xml>");

			bf.append("<appid><![CDATA[");
			bf.append(unifiedorder.getAppid());
			bf.append("]]></appid>");

			bf.append("<mch_id><![CDATA[");
			bf.append(unifiedorder.getMch_id());
			bf.append("]]></mch_id>");

			bf.append("<nonce_str><![CDATA[");
			bf.append(unifiedorder.getNonce_str());
			bf.append("]]></nonce_str>");

			bf.append("<sign><![CDATA[");
			bf.append(unifiedorder.getSign());
			bf.append("]]></sign>");

			bf.append("<body><![CDATA[");
			bf.append(unifiedorder.getBody());
			bf.append("]]></body>");

			bf.append("<detail><![CDATA[");
			bf.append(unifiedorder.getDetail());
			bf.append("]]></detail>");

			bf.append("<attach><![CDATA[");
			bf.append(unifiedorder.getAttach());
			bf.append("]]></attach>");

			bf.append("<out_trade_no><![CDATA[");
			bf.append(unifiedorder.getOut_trade_no());
			bf.append("]]></out_trade_no>");

			bf.append("<total_fee><![CDATA[");
			bf.append(unifiedorder.getTotal_fee());
			bf.append("]]></total_fee>");

			bf.append("<spbill_create_ip><![CDATA[");
			bf.append(unifiedorder.getSpbill_create_ip());
			bf.append("]]></spbill_create_ip>");

			bf.append("<time_start><![CDATA[");
			bf.append(unifiedorder.getTime_start());
			bf.append("]]></time_start>");

			bf.append("<time_expire><![CDATA[");
			bf.append(unifiedorder.getTime_expire());
			bf.append("]]></time_expire>");

			bf.append("<notify_url><![CDATA[");
			bf.append(unifiedorder.getNotify_url());
			bf.append("]]></notify_url>");

			bf.append("<trade_type><![CDATA[");
			bf.append(unifiedorder.getTrade_type());
			bf.append("]]></trade_type>");


			bf.append("</xml>");
			return bf.toString();
		}

		return "";
	}

//構造xml引數
		String xmlInfo = HttpXmlUtils.xmlInfo(unifiedorder);
		
		String wxUrl = "https://api.mch.weixin.qq.com/pay/unifiedorder";
		
		String method = "POST";
		
		String weixinPost = HttpXmlUtils.httpsRequest(wxUrl, method, xmlInfo).toString();
因為body部分是商品的名稱什麼的,設計到中文,這個過程可能毀在統一下單的時候提醒:body不是UTF-8編碼(我擦,我就在這裡折騰了半天的http://blog.csdn.net/xb12369/article/details/50512633

然後開始統一下單得到預支付ID,包裝好給app端,app端處理好後再由微信開始回撥,回撥就會跳轉到你的回撥地址上,微信說建議校驗下簽名,照做就是的!

/**
	 * 微信支付回撥
	 * @param request
	 * @param resposne
	 */
	@RequestMapping(value="/notifyUrlWeixin")
	public void notifyWeixinPayment(HttpServletRequest request,HttpServletResponse response){
		try{
			BufferedReader reader = request.getReader();

			String line = "";
			StringBuffer inputString = new StringBuffer();

			try{
				PrintWriter writer = response.getWriter();

				while ((line = reader.readLine()) != null) {
					inputString.append(line);
				}

				if(reader!=null){
					reader.close();
				}

				System.out.println("----[微信回撥]接收到的報文---"+inputString.toString());

				if(!StringUtils.isEmpty(inputString.toString())){
					WXPayResult wxPayResult = JdomParseXmlUtils.getWXPayResult(inputString.toString());

					if("SUCCESS".equalsIgnoreCase(wxPayResult.getReturn_code())){
						SortedMap<Object,Object> parameters = new TreeMap<Object,Object>();
						parameters.put("appid", wxPayResult.getAppid());
						parameters.put("attach", wxPayResult.getAttach());
						parameters.put("bank_type", wxPayResult.getBank_type());
						parameters.put("cash_fee", wxPayResult.getCash_fee());
						parameters.put("fee_type", wxPayResult.getFee_type());
						parameters.put("is_subscribe", wxPayResult.getIs_subscribe());
						parameters.put("mch_id", wxPayResult.getMch_id());
						parameters.put("nonce_str", wxPayResult.getNonce_str());
						parameters.put("openid", wxPayResult.getOpenid());
						parameters.put("out_trade_no", wxPayResult.getOut_trade_no());
						parameters.put("result_code", wxPayResult.getResult_code());
						parameters.put("return_code", wxPayResult.getReturn_code());
						parameters.put("time_end", wxPayResult.getTime_end());
						parameters.put("total_fee", wxPayResult.getTotal_fee());
						parameters.put("trade_type", wxPayResult.getTrade_type());
						parameters.put("transaction_id", wxPayResult.getTransaction_id());

						//反校驗簽名
						String sign = WXSignUtils.createSign("UTF-8", parameters);

						if(sign.equals(wxPayResult.getSign())){
							//修改訂單的狀態
							orderService.alipayNotifyPayment(wxPayResult.getOut_trade_no(), wxPayResult.getTransaction_id(),2);
							
							writer.write(HttpXmlUtils.backWeixin("SUCCESS","OK"));
						}else{
							writer.write(HttpXmlUtils.backWeixin("FAIL","簽名失敗"));
						}
					}else{
						writer.write(HttpXmlUtils.backWeixin("FAIL",wxPayResult.getReturn_msg()));
						
						System.out.println("---------微信支付返回Fail----------"+wxPayResult.getReturn_msg());
					}

					if(writer!=null){
						writer.close();
					}
				}else{
					writer.write(HttpXmlUtils.backWeixin("FAIL","未獲取到微信返回的結果"));
				}
			}catch(Exception e){
				e.printStackTrace();
			}
		}catch(Exception ex){
			ex.printStackTrace();
		}
	}


到這裡差不多這個流程就算完了!!!!

注:1、修改資原始檔中的  resources/sys.properties

#weixin apy
appid=你們的appid
mch_id=你們的mch_id
notify_url=你們的回撥地址

2、key   weixin/Utils/WXSignUtils.java

//http://mch.weixin.qq.com/wiki/doc/api/index.php?chapter=4_3
//商戶Key:改成公司申請的即可
//32位密碼設定地址:http://www.sexauth.com/  jdex1hvufnm1sdcb0e81t36k0d0f15nc
private static String Key = "你們的Key";

好了後新建一個Test的專案就可以直接運行了


有人問我appid是啥,我。。。。。我說什麼好呢?我是說還是不說呢?

o(︶︿︶)o 唉,說了沒意思,這是最最基礎的,不說有別扭,想想,還是貼出來咯~~

師傅領進門,修行個人吶