1. 程式人生 > 實用技巧 >微信申請退款API~~開發

微信申請退款API~~開發

近日,在開發“微信申請退款”的功能。之前有過微信開發的經驗,但是第一次接觸“微信退款“這一塊的業務,查詢了很多的部落格資料以及走了很多的彎路。也發現“微信退款”分享的部落格並不多。特地寫了該部落格,希望對你們有幫助。個人淺薄的見解

程式碼下載地址如下:
連結:https://pan.baidu.com/s/1h6_ZSz5RbFARlY9yxkvj5w
提取碼:weft
有任何關於微信開發的問題可以相互交流, 推薦QQ:2172931891 , 另外有微商城、微分銷、微信小遊戲等系統原始碼,有需要可以聯絡免費提供。



一、微信退款Api


https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_4

二、開發準備
(1)證書的準備:java開發需要用到:apiclient_cert.p12證書的,在微信公眾號上下載–注意PKCS12證書 是從微信商戶平臺-》賬戶設定-》 API安全 中下載的 。

【何時用到證書?】與支付不一樣,企業支付功能在傳送post請求的時候,需要載入自己的一個證書之後,帶著證書去請求退款才可以。這裡使用到證書–很多人不知道證書在哪裡使用
(2)瞭解好數字簽名 — 簡單來解釋,就是對自己要傳送的資料進行加密處理、換句話說假如說你要傳遞A/B/C,就對這三者進行加密。初開發者的誤區:不知道該加密什麼資料、觀看網上的部落格胡亂進行簽名,導致簽名錯誤


【溫馨提示:】數字簽名是一般開發人員容易遇到的錯誤,記住“你沒遇到數字簽名錯誤,都不好意思說自己做過微信退款支付訂單查詢等功能”。
耐心解決就行
(3)熟悉 從xml–》map,以及map—》xml。因為微信只接受xml資料,java寫一個xml不簡單,但是寫map集合非常簡單。而且返回的資料是xml格式。需要轉化成開發熟知的map集合
不懂的可以看以下這篇部落格
http://blog.csdn.net/xiaozhegaa/article/details/79127283

三、退款API截圖解釋
~~ 介面說明 + 是否需要證書

數字簽名說明 – 記住一句話:對要傳遞的資料進行加密,你要傳遞什麼就要簽名什麼


第一次開發遇到的坑就是:不瞭解數字簽名、花費了自己很長的時間,特地出來強調一下
證書說明

四、開發步驟如下
1.拼湊所需要傳遞的引數 map集合
2.根據要傳遞的引數生成自己的簽名
3.把簽名放到map集合中【因為簽名也要傳遞過去】
4.將當前的map結合轉化成xml格式
5.傳送請求到微信退款Api。傳送請求是一個方法來的
6.解析返回的xml資料===》map集合
7.根據map中的result_code/return_code來判斷是否成功與失敗

不得不再囉嗦一下。下面設計到簽名、mapToXml轉化、xmlToMap轉化、傳送請求到API。這些方法都可以在下面網址看到。這裡我Xml轉化成Map。我是習慣用一個Bean接收,也有範例的程式碼,大家模仿能力要強一點。這次貼出來給大家看看吧
http://blog.csdn.net/xiaozhegaa/article/details/79127283

/** 
	* 解析退款申請 
	* 解析的時候自動去掉CDMA 
	* @param xml 
	*/ 
	@SuppressWarnings("unchecked") 
	public static RefundResult getUnifiedorderResult(String xml){ 
				RefundResult unifieorderResult = new RefundResult(); 
			try { 
					StringReader read = new StringReader(xml); 
					// 建立新的輸入源SAX 解析器將使用 InputSource 物件來確定如何讀取 XML 輸入 
					InputSource source = new InputSource(read); 
					// 建立一個新的SAXBuilder 
					SAXBuilder sb = new SAXBuilder(); 
					// 通過輸入源構造一個Document 
					Document doc; 
					doc = (Document) sb.build(source); 
				
					Element root = doc.getRootElement();// 指向根節點 
					List<Element> list = root.getChildren(); 
				
					if(list!=null&&list.size()>0){ 
					for (Element element : list) { 
						System.out.println("key是:"+element.getName()+",值是:"+element.getText()); 
						if("return_code".equals(element.getName())){ 
								unifieorderResult.setResult_code(element.getText()); 
							} 
					
						if("return_msg".equals(element.getName())){ 
							unifieorderResult.setReturn_msg(element.getText()); 
							} 
					
						if("result_code".equals(element.getName())){ 
							unifieorderResult.setResult_code(element.getText()); 
							} 
						
						
						if("out_refund_no".equals(element.getName())){ 
							unifieorderResult.setOut_refund_no(element.getText()); 
							} 
						
						if("refund_id".equals(element.getName())){ 
							unifieorderResult.setRefund_id(element.getText()); 
							} 
						
						if("refund_fee".equals(element.getName())){ 
							unifieorderResult.setRefund_fee(element.getText()); 
							} 
						
						if("coupon_refund_fee".equals(element.getName())){ 
							unifieorderResult.setCoupon_refund_fee(element.getText()); 
							} 
						
						if("total_fee".equals(element.getName())){ 
							unifieorderResult.setTotal_fee(element.getText()); 
							} 
						
						if("cash_fee".equals(element.getName())){ 
							unifieorderResult.setCash_fee(element.getText()); 
							} 
						if("err_code_des".equals(element.getName())){ 
							unifieorderResult.setErr_code_des(element.getText()); 
							} 
						}
					}
				

			} catch (JDOMException e) { 
			e.printStackTrace(); 
			} catch (IOException e) { 
			e.printStackTrace(); 
			}catch (Exception e) { 
			e.printStackTrace(); 
			} 
				
			return unifieorderResult; 
		} 

@Test
	public void test2(){
		SortedMap<Object, Object> packageParams = new TreeMap<Object, Object>(); 
		
		packageParams.put("appid", wxconfig.AppID);
		packageParams.put("mch_id", wxconfig.mch_id);
		
		String s = UUID.randomUUID().toString().replace("-", "");
		packageParams.put("nonce_str",s);
		
		String s1 = UUID.randomUUID().toString().replace("-", "");
		packageParams.put("out_refund_no",s1);
		packageParams.put("out_trade_no","ozb5fjjxbwag1akdy0vm108makqhsdmx");
	
		packageParams.put("refund_fee","100");
		packageParams.put("total_fee","100");
		
		packageParams.put("op_user_id",wxconfig.mch_id);
		
		String sign  = WeixinPayBack.createSign("utf-8",packageParams);
		
		packageParams.put("sign", sign);
		
		String reuqestXml = WXPayUtil.getRequestXml(packageParams);
		 
		System.out.println("-----------------"); 
		System.out.println(reuqestXml);
		System.out.println("-----------------"); 
		//傳送請求到後臺了
		String wxUrl = WeixinPayBack.getRefundURL; 
		try {
			String weixinPost = ClientCustomSSL.doRefund(wxUrl, reuqestXml).toString();
			System.out.println(weixinPost);
			
			RefundResult refundResult = WeixinPayBack.getUnifiedorderResult(weixinPost);  
			    
		    String result =null;
		    if("SUCCESS".equalsIgnoreCase(refundResult.getResult_code())){ 
		    	result = "200"; 
		    	System.out.println("==========處理退款成功=========="); 
	    	}else{ 
	    		result = refundResult.getReturn_msg(); 
	    	} 
		    
		    System.out.println(result);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}  
		
		
		
	}


五、結果演示

自此,我們就學會了“微信申請退款”的開發,希望對你們有幫助
具體的、在呼叫改方法自己加上自己的業務邏輯就行了。希望對大家有幫助

//TODO 9.0 操作支付表,把當前的支付的狀態變成 退款狀態   state 1 ---> 2
//TODO 10 操作預約表,可以把當前的預約狀態取消  已支付--->退款
//TODO 11 操作使用者表,如果是充值退款的話,把使用者的現金 - 當前退款的money
//TODO 12其他等等的操作,生成記錄單號之類的