public static String refund(PintuanOrderService orderServices,
Order order) {
// XML文件处理类 处理与微信服务器交互传递的xml格式的字符串
XMLOperation operationService = new XMLOperation();
// 退款的URL
String refundUrl = "https://api.mch.weixin.qq.com/secapi/pay/refund";
// 封装请求退款的参数
Map map = new HashMap();
//appid
map.put("appid", appid);
//商户号
map.put("mch_id", mchID);
//随机字符串
map.put("nonce_str","ddasdwfsfdsgfs");
//调用微信支付的时候向微信服务器发送的商户订单号
map.put("out_trade_no", payId());
//交易流水号 每次不同
map.put("out_refund_no", System.currentTimeMillis());
//调用微信支付的时候付出的总额
BigDecimal decimal = order.getTotal.multiply(
BigDecimal.valueOf(100));
map.put("total_fee", decimal.intValue());
//本次退款金额
BigDecimal decimal2 = order.getMoney.multiply(
BigDecimal.valueOf(100));
map.put("refund_fee", decimal2.intValue());
//币种
map.put("refund_fee_type", "CNY");
//操作号为商户号
map.put("op_user_id", mchID);
//生成签名
String sign = CreateSign(map);
map.put("sign", sign);
try {
//生成发送给微信服务器的xml格式的数据
String xmlString = operationService.createXMLString(map);
//发送请求 获取返回值
String xmlResult = ClientCustomSSL.refund(xmlString);
//解析返回值
Map<String, String> parseXML = operationService
.parseXMLString(xmlResult);
// 处理结果
if (("SUCCESS").equals(parseXMLString.get("return_code"))) {
//成功转化为json数据返回
return new JacksonMapper().writeValueAsString(parseXMLString);
} else {
//失败日志
logger.info("订单号为:" + order.getOrderId()
+ "退款失败,获取失败相关数据:" + parseXMLString);
}
} catch (Exception e) {
//异常
logger.info("异常:" + e);
}
//请求微信服务器失败 返回0
return "0";
}
///XMLOperation 类 隐私信息已删除
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.apache.log4j.Logger;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
public class XMLOperationService {
private Document document;
private DocumentBuilder documentBuilder;
public static Logger logger = Logger.getLogger(XMLOperationService.class);
{
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
try {
documentBuilder = factory.newDocumentBuilder();
document = documentBuilder.newDocument();
} catch (ParserConfigurationException e) {
logger.info(e);
}
}
/**
* 微信支付:发送的XML数据
*
* @param data
* 封装需要发送的数据 在data中设置map的数据
* @return 返回生成的XML字符串
* @throws Exception
*/
public String createXMLString(Map map) throws Exception {
Element root = document.createElement("xml");
document.appendChild(root);
Set<Entry> entrySet = map.entrySet();
SortedMap maps = new TreeMap();
for (Entry entry : entrySet) {
maps.put(entry.getKey(), entry.getValue());
}
Set<Entry> set = maps.entrySet();
for (Entry entry : set) {
String key = (String)entry.getKey();
if ("sign".equals(key)) {
logger.info("循环到sign 跳过");
continue;
}
Element element = document.createElement(key);
element.appendChild(document.createTextNode(entry.getValue()+""));
root.appendChild(element);
}
Element element = document.createElement("sign");
element.appendChild(document.createTextNode(map.get("sign")+""));
root.appendChild(element);
TransformerFactory factory = TransformerFactory.newInstance();
Transformer transformer = factory.newTransformer();
DOMSource domSource = new DOMSource(document);
ByteArrayOutputStream out = new ByteArrayOutputStream();
transformer.transform(domSource, new StreamResult(out));
String str1 = out.toString();
// 去除版本编码等信息
return str1.substring(str1.indexOf(">") + 1);
}
/**
* 微信支付:解析返回的XML文件
*
* @param str
* 输入微信返回的xml数据
* @return
*/
public Map<String, String> parseXMLString(String str) {
try {
str = str.replaceAll("\n", "");
Map<String, String> map = new HashMap<String, String>();
document = documentBuilder.parse(new InputSource(
new ByteArrayInputStream(str.getBytes("UTF-8"))));
Element root = document.getDocumentElement();
NodeList nodes = root.getChildNodes();
for (int i = 0; i < nodes.getLength(); i++) {
Node item = nodes.item(i);
String key = item.getNodeName();
String value = item.getTextContent();
map.put(key, value);
}
return map;
} catch (Exception e) {
logger.info(e);
}
return null;
}
}
/生成签名
public static String CreateSign(Map map) {
SortedMap maps = new TreeMap();
Set<Entry> set = map.entrySet();
for (Entry entry : set) {
maps.put(entry.getKey(), entry.getValue());
}
Set<Entry> entrySet = maps.entrySet();
String str = "";
for (Entry object : entrySet) {
str+=object.getKey()+"="+object.getValue()+"&";
}
str += "key=" + "支付秘钥";
String sign = MD5(str).toUpperCase();
return sign;
}
MD5加密
public static String MD5(String input) {
try {
// 获得MD5摘要算法的 MessageDigest 对象
MessageDigest mdInst = MessageDigest.getInstance("MD5");
// 使用指定的字节更新摘要
mdInst.update(input.getBytes());
// 获得密文
byte[] md = mdInst.digest();
// 把密文转换成十六进制的字符串形式
StringBuffer hexString = new StringBuffer();
// 字节数组转换为 十六进制 数
for (int i = 0; i < md.length; i++) {
String shaHex = Integer.toHexString(md[i] & 0xFF);
if (shaHex.length() < 2) {
hexString.append(0);
}
hexString.append(shaHex);
}
return hexString.toString();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return "";
}
/发起退款请求的类 已删除相关隐私
public class ClientCustomSSL {
public static Logger logger = Logger.getLogger(ClientCustomSSL.class);
public static String mchid = "商户号";
public static String refund(String xml) throws Exception {
//返回结果
String result = "";
KeyStore keyStore = KeyStore.getInstance("PKCS12");
//退款操作的证书读取
FileInputStream instream = new FileInputStream(new File(
"证书地址"));
try {
keyStore.load(instream, mchid.toCharArray());
} finally {
instream.close();
}
//解密
SSLContext sslcontext = SSLContexts.custom()
.loadKeyMaterial(keyStore, mchid.toCharArray())
.build();
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
sslcontext, new String[] { "TLSv1" }, null,
SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
CloseableHttpClient httpclient = HttpClients.custom()
.setSSLSocketFactory(sslsf).build();
try {
//向微信服务器发送退款请求的httpPost
HttpPost httpPost = new HttpPost(
"https://api.mch.weixin.qq.com/secapi/pay/refund");
//设置提交的正文类型的格式
StringEntity postEntity = new StringEntity(xml, "UTF-8");
httpPost.addHeader("Content-Type", "text/xml");
//提交的参数赋值 由调用端传递xml形式的字符串
httpPost.setEntity(postEntity);
//发送请求
CloseableHttpResponse response = httpclient.execute(httpPost);
try {
//返回微信服务器的请求结果
HttpEntity entity = response.getEntity();
result = EntityUtils.toString(entity, "UTF-8");
} finally {
response.close();
}
} finally {
httpclient.close();
}
return result;
}
}
//以上为申请微信退款/
//以下为查看退款状态/
/**
* 查询订单的退款状态
*
* @param order_id
*/
@RequestMapping("/s/s/s/s/s")
@ResponseBody
public String refoundCheck(
@PathVariable("") Long order_id) {
// XML文件处理类
XMLOperation operationService = new XMLOperation();
// 订单信息获取
Order order = orderService.findOneOrder(order_id);
// 退款的URL
String refundCheckUrl = "https://api.mch.weixin.qq.com/pay/refundquery";
// 封装请求退款的参数
Map map = new HashMap();
//appid
map.put("appid", "");
//商户号
map.put("mch_id", "mchID");
//随机字符串
map.put("nonce_str", "fkdoapfds");
//调用微信支付的时候的商户订单号
map.put("out_trade_no", "");
String sign = CreateSign(map);
map.put("sign", sign);
try {
String xmlString = operationService.createXMLString(map);
// 发起退款请求
HttpsSend httpsPost = new HttpsSend();
String xmlResult = httpsPost.sendPost(
refundCheckUrl , xmlString);
Map<String, String> parseXMLString = operationService
.parseXMLString(xmlResult);
// 处理结果
if (("SUCCESS").equals(parseXMLString.get("return_code"))) {
//
// 返回退款状态的字符串
return new JacksonMapper().writeValueAsString(parseXMLString);
} else {
logger.info("订单号为:" + order.getOrderId()
+ "订单退款未成功,获取相关数据:" + parseXMLString);
}
} catch (Exception e) {
logger.info("异常:" + e);
}
return "0";
}
//基本逻辑如上
转载于:https://my.oschina.net/u/2405524/blog/621670