微信退款java(以上线)
//退款反复主要是证书路径问题,我证书放在web下面的book文件其他都直接使用sdk传参即可
里面一些接口功能可以删除,那是我的业务逻辑
//action
public String Refund() throws ParseException {
// 动态获取证书路径
String path=getSession().getServletContext().getRealPath("/book/apiclient_cert.p12");
//path=path+"/book/apiclient_cert.p12";
//WechatConstant wechat=new WechatConstant();
WechatConstant.setCertpath(path);;
Integer oid = getOrderBean().getOid();
List<Order> master = orderService.orderid(getOrderBean(), oid);
//List<OrderItem> itemlist = orderService.findorderid(getOrderBean(), oid);// 根据订单id查询出订单的商品
// String proname = master.get(0).getProname();
// String proname=itemlist.get(0).getGoodsName();//商品名称
String status = master.get(0).getPayStatus();// 订单状态
BigDecimal price = master.get(0).getSumPrice();// 商品价格
String price1 = valueOf(price);
System.out.println(price1);
double price2 = Double.parseDouble(price1);
String proname1 = "yfk";
Date edate = master.get(0).getEdate();
Calendar calendar = new GregorianCalendar();// 取预订时间的前一天
calendar.setTime(edate);
calendar.add(Calendar.DATE, -1);// 获取昨天的时间
calendar.add(Calendar.HOUR, 17);// 获取下午17点时间
Date dateto = calendar.getTime();
System.out.println(dateto);
Date mytodate = new Date();// 获取当前时间
// 判断如果该订单使用状态为待使用和预订时间的前一天大于当前new的时间则执行退款流程
if (status.equals(proname1) && dateto.getTime() > mytodate.getTime()) {
// 准备退款需要的参数 退款主要代码
String proorder = master.get(0).getProorder();// 商户订单号是支付成功返回的
double toprice = price2 * 100;// 乘100
DecimalFormat decimalFormat = new DecimalFormat("###################.###########");
String Strprice = decimalFormat.format(toprice);
String us = RandomStringUtils.randomAlphanumeric(15);
String appid = WechatConstant.APPID; // 微信公众号的appid
String mch_id = WechatConstant.MCH_ID; // 商户号
String nonce_str = WXPayUtil.generateNonceStr(); // 生成随机数
String out_trade_no = proorder; // 商户订单号
String out_refund_no = us;// 商户退款单号
String total_fee = Strprice;// 订单金额
String refund_fee = Strprice;// 退款金额
// 2.0 生成map集合,把退款的参数传入map集合
SortedMap<String, String> packageParams = new TreeMap<String, String>();
packageParams.put("appid", 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);
try {
// 3.0 利用上面的参数,先去生成自己的签名 WXPayUtil是微信api的工具
String sign = WXPayUtil.generateSignature(packageParams, WechatConstant.MCH_KEY);
// 4.0 将签名再放回map中,它也是一个参数
packageParams.put("sign", sign);
// 5.0将当前的map结合转化成xml格式
String xml = WXPayUtil.mapToXml(packageParams);
// 6.0获取需要发送的url地址
String wxUrl = "https://api.mch.weixin.qq.com/secapi/pay/refund"; // 获取退款的api接口
System.out.println("发送前的xml为:" + xml);
// 7,向微信发送请求转账请求WechatConstant.CERTPATH
System.out.println("打印路径");
System.out.println(WechatConstant.getCertpath());
//System.out.println(wechat.getCertpath());
String returnXml = CertHttpUtil.postData(wxUrl, xml, WechatConstant.MCH_ID,WechatConstant.getCertpath());
System.out.println("返回的returnXml为:" + returnXml);
// 8,将微信返回的xml结果转成map格式
Map<String, String> returnMap = WXPayUtil.xmlToMap(returnXml);
if (returnMap.get("return_code").equals("SUCCESS")) {
// 修改订单状态*/
String isusername = "ytk";
String isname = "yqx";
orderService.toupdate(isusername, oid, isname);
// 退款成功
//System.out.println("returnMap为:" + returnMap);
Map<String, Object> jsonMap = new HashMap<String, Object>();
jsonMap.put("statusCode", 200);
jsonMap.put("list", 1);
// 返回的格式必须bjui规定的格式:{"statusCode" : 200,"message" : "处理成功!"}
String json = JsonUtil.convert2JSONString(jsonMap);
// 返回结果给客户端,供json使用,需要用到response中的writer
printlnToClient(json);
}
return returnXml;
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return "error";
} else {
// 退款失败发送消息给前端
System.out.print("不符合退款要求");
Map<String, Object> jsonMap = new HashMap<String, Object>();
jsonMap.put("statusCode", 200);
jsonMap.put("list", 2);
// 返回的格式必须bjui规定的格式:{"statusCode" : 200,"message" : "处理成功!"}
String json = JsonUtil.convert2JSONString(jsonMap);
// 返回结果给客户端,供json使用,需要用到response中的writer
printlnToClient(json);
}
return "error";
}
//加载证书的工具类
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数据对象
* @param mchId 商户ID
* @param certPath 证书位置
* @return
*/
public static String postData(String url, String xmlObj, String mchId, String certPath) {
// 加载证书
try {
initCert(certPath);
} 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;
}
/* public static void main(String[] args) {
FileInputStream instream = null;
try {
instream = new FileInputStream(new File(WechatConstant.CERTPATH));
String key = WechatConstant.MCH_ID;
KeyStore keyStore = KeyStore.getInstance("PKCS12");
// 指定PKCS12的密码(商户ID)
keyStore.load(instream, key.toCharArray());
System.out.println(keyStore);
}catch (Exception e) {
// TODO: handle exception
}
}*/
/**
* 加载证书
*
* @param mchId 商户ID
* @param certPath 证书位置
* @throws Exception
*/
private static void initCert(String file) throws Exception {
// 证书密码,默认为商户ID
String key = WechatConstant.MCH_ID;
// 证书的路径
//String path = WechatConstant.CERTPATH;
//WechatConstant mychat=new WechatConstant();
String path = WechatConstant.getCertpath();
// 指定读取证书格式为PKCS12
KeyStore keyStore = KeyStore.getInstance("PKCS12");
// 读取本机存放的PKCS12证书文件
FileInputStream instream = new FileInputStream(new File(path));
try {
System.out.println(instream);
// 指定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();
}
}