您的位置:首页 > 移动开发 > 微信开发

微信服务号开发----公众号支付退款

2017-01-10 20:54 344 查看
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<String, String> packageParams = new TreeMap<String, String>();
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 = "<xml>" +
"<appid>" + appid + "</appid>" +
"<mch_id>"+ mch_id + "</mch_id>" +
"<nonce_str>" + nonce_str+ "</nonce_str>" +
"<sign><![CDATA[" + sign + "]]></sign>"+
"<out_trade_no>" + out_trade_no + "</out_trade_no>"+
"<out_refund_no>" + out_refund_no + "</out_refund_no>"+
"<total_fee>" + total_fee + "</total_fee>"+
"<refund_fee>" + refund_fee + "</refund_fee>"+
"<op_user_id>" + op_user_id + "</op_user_id>" +
"</xml>";

/*<xml>
<appid>wx2421b1c4370ec43b</appid>
<mch_id>10000100</mch_id>
<nonce_str>6cefdb308e1e2e8aabd48cf79e546a02</nonce_str>
<op_user_id>10000100</op_user_id>
<out_refund_no>1415701182</out_refund_no>
<out_trade_no>1415757673</out_trade_no>
<refund_fee>1</refund_fee>
<total_fee>1</total_fee>
<transaction_id></transaction_id>
<sign>FE56DD4AA85C0EECA82C35595A69E153</sign>
</xml>*/
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<String, String> packageParams = new TreeMap<String, String>();
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 = "<xml>" +
"<appid>" + appid + "</appid>" +
"<mch_id>"+ mch_id + "</mch_id>" +
"<nonce_str>" + nonce_str+ "</nonce_str>" +
"<sign><![CDATA[" + sign + "]]></sign>"+
"<transaction_id>" + transaction_id + "</transaction_id>"+
"</xml>";

/*<xml>
<appid>wx2421b1c4370ec43b</appid>
<mch_id>10000100</mch_id>
<nonce_str>0b9f35f484df17a732e537c37708d1d0</nonce_str>
<out_refund_no></out_refund_no>
<out_trade_no>1415757673</out_trade_no>
<refund_id></refund_id>
<transaction_id></transaction_id>
<sign>66FFB727015F450D167EF38CCC549521</sign>
</xml>*/

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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息