微信退款

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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值