java 微信退款次数上限 java微信退款开发_apache

一、申请退款内容

1.证书使用

申请退款是需要证书的。

证书名字:证书使用中,说明了Java使用的是第一种:pkcs12格式的apiclient_cert.p12。

下载证书:微信商户平台-->账户设置-->API安全-->证书下载,操作参考。

调用实例:各版本的调用实例请参考微信支付提供的Demo外链(点击会下载cert文件)。

Demo:下载的cert文件夹里有Java版代码使用Demo。

2.实现途经选择

代码工具与方式----用的

入手----申请退款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微信扫码支付

二、代码步骤

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 m = new TreeMap();
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 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 urlAPI地址
* @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();
}
}