/**
* @param request
* @param orderId 订单id
* @param orderNum 订单号
* @param refundNum 退款流水号
* @param orderMoney 订单金额
* @param refundMoney 退款金额
* @param refundCase 退款原因
* @return
*/
public JSONObject refundByOrderId(HttpServletRequest request, String orderId, String orderNum, String refundNum, double orderMoney, double refundMoney, String refundCase) {
JSONObject jsonObject = new JSONObject();
try {
//创建退款数据报包
SortedMap<Object, Object> packageParams = new TreeMap<Object, Object>();
//获取商户号的一些参数信息(这里是自己封装的 获取商户号的一些配置)
PluginConfig pluginConfig = weixinPublicPaymentPlugin.getPluginConfig();
//获取订单
Order order=orderService.find(Long.parseLong(orderId));
//封装所有参数
//appid==公众账号ID==同下单
packageParams.put("appid", pluginConfig.getAttribute("appId"));
//mch_id==商户号==同下单
packageParams.put("mch_id", pluginConfig.getAttribute("mchId"));
//nonce_str==32位随机字符串==生成方法同下单
packageParams.put("nonce_str", WXPayUtil.generateNonceStr()); // 随机字符串(32位以内)
//sign_type==签名类型==同下单
packageParams.put("sign_type", "MD5");//paySign加密
//out_trade_no== 商户订单号 == 用户下单单号
//退款订单号
packageParams.put("out_trade_no", orderNum);
//out_refund_no==商户退款单号== 退款流水号 (为了简单,我这里是:时间戳后8位+5位随机数)
packageParams.put("out_refund_no", refundNum);
//total_fee==订单金额==该退款订单的总价格 (官方规定 单位:分,且为整数)
packageParams.put("total_fee", (int) (orderMoney * 100));
//refund_fee==退款金额==需要退款的金额 (官方规定 单位:分,且为整数)
packageParams.put("refund_fee", (int) (refundMoney * 100));
//退款原因
packageParams.put("refund_desc", refundCase);
//获取sign
String sign = PayCommonUtil.createSign("UTF-8", packageParams, pluginConfig.getAttribute("apiKey"));//最后这个是自己在微信商户设置的32位密钥
//sign==签名==签名方法同同下单
packageParams.put("sign", sign);
//退款回调接口 ( 非必要 )
//packageParams.put("notify_url", notifyUrl+"/apiRefund/backRefund" );
//所有参数赋值并签名后转化为xml封装好请求
String requestXML = PayCommonUtil.getRequestXml(packageParams);
//System.err.println("requestXML:" + requestXML);
logger.info("退款人ID:"+order.getMember().getId());
logger.info("退款请求参数:"+requestXML);
StringEntity stringEntity = new StringEntity(requestXML, "UTF-8");
HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/secapi/pay/refund");
// 得指明使用UTF-8编码,否则到API服务器XML的中文不能被成功识别
httpPost.addHeader("Content-Type", "text/xml");
httpPost.setEntity(stringEntity);
// 初始化证书,得到一个 HttpClient (加载含有证书的http请求)
HttpResponse response = initCert(request).execute(httpPost);
HttpEntity entity = response.getEntity();
//得到返回结果的XML
String resXml = EntityUtils.toString(entity, "UTF-8");
logger.info("退款微信返回参数:"+resXml);
//将XML转换成 Map 集合
Map map = XMLUtil.doXMLParse(resXml);
//回调结果
String returnCode = (String) map.get("return_code");
String returnMsg = (String) map.get("return_msg");//返回信息
String resultCode = (String) map.get("result_code");//返回结果码
String errCodeDes = (String) map.get("err_code_des");//返回结果码
String transaction_id = (String) map.get("transaction_id");//微信订单号
//返回结果成功
if ("SUCCESS".equals(returnCode) && "OK".equals(returnMsg)) {
if ("FAIL".equals(resultCode)) {
//退款失败的逻辑
return jsonObject;
} else {
//退款成功的逻辑
return jsonObject;
}
} else {
//返回结果失败的逻辑
return jsonObject;
}
} catch (Exception e) {
//返回结果失败
jsonObject.put("status", HttpStatus.BAD_REQUEST);
jsonObject.put("Msg", e.getMessage());
return jsonObject;
}
}
//商户Id
@Value("${payConfig.mchId}")
private String key;
//商户证书路径
@Value("${payConfig.payConfigPath}")
private String payConfigPath;
/**
* 加载证书
*/
private CloseableHttpClient initCert(HttpServletRequest request) throws Exception {
// System.err.println("key:"+key);
// System.err.println("payConfigPath:"+payConfigPath);
// 商户证书的路径
String path = request.getServletContext().getRealPath(payConfigPath);// 证书文件路径
// System.err.println("path:"+path);
// 指定读取证书格式为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
return HttpClients.custom().setSSLSocketFactory(sslsf).build();
}
微信小程序之退款
最新推荐文章于 2023-10-31 16:27:32 发布