1、微信支付开发文档
https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=7_1
下载地址
http://download.csdn.net/detail/u014520797/9734108
2、微信申请退款需要双向证书,PKCS12证书 是从 https://pay.weixin.qq.com/index.php/core/home/login?return_url=%2F
微信商户平台-》账户设置-》 API安全 中下载的
下载之后存放在本地一个英文命名的文件夹下,解压。
3、证书解压之后是
4、代码
package com.kp.wxpay;
import java.util.SortedMap;
import java.util.TreeMap;
/**
* @author: py
* @version:2017年1月10日 上午11:17:59
* @Desc 微信退款 申请以及退款
* //api地址:http://mch.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_4
*/
public class WXPayRefundUtil {
String appid = ""; //微信公众号apid
String appsecret = " "; //微信公众号appsecret
public static String mch_id = " "; //微信商户id
String op_user_id = " ";//操作员帐号, 默认为商户号
String partnerkey = " ";//商户平台上的那个KEY
/**
* @date 2017年1月10日上午10:36:50 void
* @Des:退款
*/
public void wechatRefund() {
// 商户系统内部的退款单号,商户系统内部唯一,同一退款单号多次请求只退一笔
String out_refund_no = " ";
String out_trade_no = "256165";// 商户侧传给微信的订单号
String total_fee = "1";// 总金额
String refund_fee = "1";// 退款金额
String nonce_str = "20bdx4b25826b";// 随机字符串
SortedMap packageParams = new TreeMap();
packageParams.put("appid", appid);
packageParams.put("mch_id", mch_id);
packageParams.put("nonce_str", nonce_str);
packageParams.put("out_trade_no", out_trade_no);
packageParams.put("out_refund_no", out_refund_no);
packageParams.put("total_fee", total_fee);
packageParams.put("refund_fee", refund_fee);
packageParams.put("op_user_id", op_user_id);
RequestHandler reqHandler = new RequestHandler(
null, null);
reqHandler.init(appid, appsecret, partnerkey);
String sign = reqHandler.createSign(packageParams);
String xml = "" +
"" + appid + " " +
""+ mch_id + " " +
"" + nonce_str+ " " +
" "+
"" + out_trade_no + " "+
"" + out_refund_no + " "+
"" + total_fee + " "+
"" + refund_fee + " "+
"" + op_user_id + " " +
" ";
/*
wx2421b1c4370ec43b
10000100
6cefdb308e1e2e8aabd48cf79e546a02
10000100
1415701182
1415757673
1
1
FE56DD4AA85C0EECA82C35595A69E153
*/
String createOrderURL = "https://api.mch.weixin.qq.com/secapi/pay/refund";
try {
String s= ClientCustomSSL.doRefund(createOrderURL, xml);
System.out.println("s:"+s);
//改变支付数据库中的是否退款
//新增退款数据库数据
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* @date 2017年1月10日上午10:37:47 void
* @Des:退款查询
*/
public void querywechatRefund() {
// 商户系统内部的退款单号,商户系统内部唯一,同一退款单号多次请求只退一笔
String transaction_id = "656565";
String nonce_str = "5616556165";// 随机字符串
SortedMap packageParams = new TreeMap();
packageParams.put("appid", appid);
packageParams.put("mch_id", mch_id);
packageParams.put("nonce_str", nonce_str);
packageParams.put("transaction_id", transaction_id);
RequestHandler reqHandler = new RequestHandler(
null, null);
reqHandler.init(appid, appsecret, partnerkey);
String sign = reqHandler.createSign(packageParams);
String xml = "" +
"" + appid + " " +
""+ mch_id + " " +
"" + nonce_str+ " " +
" "+
"" + transaction_id + " "+
" ";
/*
wx2421b1c4370ec43b
10000100
0b9f35f484df17a732e537c37708d1d0
1415757673
66FFB727015F450D167EF38CCC549521
*/
String createOrderURL = "https://api.mch.weixin.qq.com/pay/refundquery";
try {
String s= ClientCustomSSL.doRefund(createOrderURL, xml);
System.out.println("s:"+s);
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
WXPayRefundUtil refund=new WXPayRefundUtil();
// refund.wechatRefund();//申请退款
refund.querywechatRefund();//查询退款
}
}
5、这个类中需要填写双向证书解压的路径
package com.kp.wxpay;
import java.io.File;
import java.io.FileInputStream;
import java.security.KeyStore;
import javax.net.ssl.SSLContext;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
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 ClientCustomSSL {
public static String doRefund(String url,String data) throws Exception {
/**
* 注意PKCS12证书 是从微信商户平台-》账户设置-》 API安全 中下载的
*/
KeyStore keyStore = KeyStore.getInstance("PKCS12");
FileInputStream instream = new FileInputStream(new File("E:/bmjcompany/wxpaycert/cert/apiclient_cert.p12"));//P12文件目录
try {
/**
* 此处要改
* */
keyStore.load(instream, WXPayRefundUtil.mch_id.toCharArray());//这里写密码..默认是你的MCHID
} finally {
instream.close();
}
// Trust own CA and all self-signed certs
/**
* 此处要改
* */
SSLContext sslcontext = SSLContexts.custom()
.loadKeyMaterial(keyStore, WXPayRefundUtil.mch_id.toCharArray())//这里也是写密码的
.build();
// Allow TLSv1 protocol only
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
sslcontext,
new String[] { "TLSv1" },
null,
SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
CloseableHttpClient httpclient = HttpClients.custom()
.setSSLSocketFactory(sslsf)
.build();
try {
HttpPost httpost = new HttpPost(url); // 设置响应头信息
httpost.addHeader("Connection", "keep-alive");
httpost.addHeader("Accept", "*/*");
httpost.addHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
httpost.addHeader("Host", "api.mch.weixin.qq.com");
httpost.addHeader("X-Requested-With", "XMLHttpRequest");
httpost.addHeader("Cache-Control", "max-age=0");
httpost.addHeader("User-Agent", "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0) ");
httpost.setEntity(new StringEntity(data, "UTF-8"));
CloseableHttpResponse response = httpclient.execute(httpost);
try {
HttpEntity entity = response.getEntity();
String jsonStr = EntityUtils.toString(response.getEntity(), "UTF-8");
EntityUtils.consume(entity);
return jsonStr;
} finally {
response.close();
}
} finally {
httpclient.close();
}
}
}
6、源码地址
http://download.csdn.net/detail/u014520797/9734118