Java微信支付申請退款

1、申請退款內容

1.證書使用

  • 申請退款是須要證書的
  • 證書名字證書使用中,說明了Java使用的是第一種:pkcs12格式的apiclient_cert.p12
  • 下載證書微信商戶平臺-->帳戶設置-->API安全-->證書下載,操做參考
  • 調用實例:各版本的調用實例請參考微信支付提供的Demo外鏈(點擊會下載cert文件)。
  • Demo:下載的cert文件夾裏有Java版代碼使用Demo

2.實現途經選擇

  • 代碼工具與方式----用的eclipse的插件版:STS,用servlet簡單實現。
  • 入手----申請退款API,有必填參數說明,有xml舉例舉例
  • debug調試----用已經支付過的肯定訂單號來測試,查看返回的xml內容

3.申請退款流程

  • 拼成xml:將參數拼成xml字符串
  • 提交到URL:POST方式提交給微信申請退款API的URL
  • 解析微信返回的xml:成功或者失敗及具體信息,裏面有說明
  • ④json格式:也能夠拼成json格式,方便傳遞數據。

4.用到資料

  • jar包:Demo外鏈中Java版的lib文件夾裏,commons-logging-1.1.3,httpclient-4.3.4,httpcore-4.3.2。
  • 其餘內容和代碼:請閱讀個人Java微信掃碼支付

2、代碼步驟

1.申請退款的Servlet

  • servlet寫的:參數賦值-->拼接參數-->參數提交-->參數返回並解析
public class RefundServlet extends HttpServlet {
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		String appid = PayConfigUtil.APP_ID; // appid
		String mch_id = PayConfigUtil.MCH_ID; // 商業號
		String key = PayConfigUtil.API_KEY; // key

		String currTime = PayCommonUtil.getCurrTime();
		String strRandom = PayCommonUtil.buildRandom(4) + "";
		String nonce_str = currTime + strRandom;//currTime + strRandom; // 隨機字符串
		String out_trade_no = "520520";//申請退款的商戶訂單號

		String out_refund_no = out_trade_no + "1314";
		String total_fee = "1";
		String refund_fee = total_fee;
		String op_user_id = mch_id; // 操做員默認爲商戶號

		SortedMap<String, String> m = new TreeMap<String, String>();
		m.put("appid", appid);
		m.put("mch_id", mch_id);
		m.put("nonce_str", nonce_str);
		m.put("out_trade_no", out_trade_no);
		m.put("out_refund_no", out_refund_no);
		m.put("total_fee", total_fee);
		m.put("refund_fee", refund_fee);
		m.put("op_user_id", op_user_id);
		//簽名算法
		String sign = PayCommonUtil.createSign("UTF-8", m, key);
		m.put("sign", sign);
		//將集合轉換成xml
		String requestXML = PayCommonUtil.getRequestXml(m);
		//帶證書的post
		String resXml = CertHttpUtil.postData(PayConfigUtil.REFUND_API, requestXML);
		//解析xml爲集合,請打斷點查看resXml詳細信息
		Map<String, String> map = XMLUtil.doXMLParse(resXml);
		//查看申請退款狀態
		PrintWriter out = response.getWriter();
		out.print(map.get("result_code"));
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doGet(request, response);
	}

}

2.帶證書的POST提交

  • 要先調用證書,而後post提交,證書使用基本上是httpclient內容(網上抄來的,具體還沒研究)
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.security.KeyStore;

import javax.net.ssl.SSLContext;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLContexts;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

public class CertHttpUtil {

	private static int socketTimeout = 10000;// 鏈接超時時間,默認10秒
	private static int connectTimeout = 30000;// 傳輸超時時間,默認30秒
	private static RequestConfig requestConfig;// 請求器的配置
	private static CloseableHttpClient httpClient;// HTTP請求器

	/**
	 * 經過Https往API post xml數據
	 * @param url	API地址
	 * @param xmlObj	要提交的XML數據對象
	 * @return
	 */
	public static String postData(String url, String xmlObj) {
		// 加載證書
		try {
			initCert();
		} catch (Exception e) {
			e.printStackTrace();
		}
		String result = null;
		HttpPost httpPost = new HttpPost(url);
		// 得指明使用UTF-8編碼,不然到API服務器XML的中文不能被成功識別
		StringEntity postEntity = new StringEntity(xmlObj, "UTF-8");
		httpPost.addHeader("Content-Type", "text/xml");
		httpPost.setEntity(postEntity);
		// 根據默認超時限制初始化requestConfig
		requestConfig = RequestConfig.custom()
				.setSocketTimeout(socketTimeout)
				.setConnectTimeout(connectTimeout)
				.build();
		// 設置請求器的配置
		httpPost.setConfig(requestConfig);
		try {
			HttpResponse response = null;
			try {
				response = httpClient.execute(httpPost);
			}  catch (IOException e) {
				e.printStackTrace();
			}
			HttpEntity entity = response.getEntity();
			try {
				result = EntityUtils.toString(entity, "UTF-8");
			}  catch (IOException e) {
				e.printStackTrace();
			}
		} finally {
			httpPost.abort();
		}
		return result;
	}

	/**
	 * 加載證書
	 * 
	 */
	private static void initCert() throws Exception {
		// 證書密碼,默認爲商戶ID
		String key = PayConfigUtil.MCH_ID;
		// 證書的路徑
		String path = PayConfigUtil.CertPath;
		// 指定讀取證書格式爲PKCS12
		KeyStore keyStore = KeyStore.getInstance("PKCS12");
		// 讀取本機存放的PKCS12證書文件
		FileInputStream instream = new FileInputStream(new File(path));
		try {
			// 指定PKCS12的密碼(商戶ID)
			keyStore.load(instream, key.toCharArray());
		} finally {
			instream.close();
		}
		SSLContext sslcontext = SSLContexts
				.custom()
				.loadKeyMaterial(keyStore, key.toCharArray())
				.build();
		// 指定TLS版本
		SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
				sslcontext, new String[] { "TLSv1" }, null,
				SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
		// 設置httpclient的SSLSocketFactory
		httpClient = HttpClients
				.custom()
				.setSSLSocketFactory(sslsf)
				.build();
	}
}
相關文章
相關標籤/搜索