微信退款实现

/***
     * 申请退款完整业务流程逻辑
     * 
     * @param transaction_id
     *            微信订单号(优先使用)
     * @param out_trade_no
     *            商户订单号
     * @param total_fee
     *            订单总金额
     * @param refund_fee
     *            退款金额
     * @return 退款结果(xml格式)
     * @throws Exception 
     */
    public static String Run(String transaction_id, String out_trade_no,
            String total_fee, String refund_fee)
            throws Exception {
        Log.info("Refund is processing...");

        WxPayData data = new WxPayData();
        if (transaction_id != null && !transaction_id.isEmpty())// 微信订单号存在的条件下,则已微信订单号为准
        {
            data.SetValue("transaction_id", transaction_id);
        } else// 微信订单号不存在,才根据商户订单号去退款
        {
            data.SetValue("out_trade_no", out_trade_no);
        }

        data.SetValue("total_fee", Integer.parseInt(total_fee));// 订单总金额
        data.SetValue("refund_fee", Integer.parseInt(refund_fee));// 退款金额
        data.SetValue("out_refund_no", WxPayApi.GenerateOutTradeNo());// 随机生成商户退款单号
        data.SetValue("op_user_id", WxPayConfig.MCHID);// 操作员,默认为商户号

        WxPayData result = WxPayApi.Refund(data, 0);// 提交退款申请给API,接收返回数据

        Log.info("Refund process complete, result : " + result.ToXml());
        return result.ToPrintStr();
    }

/**
     * 
     * 申请退款
     * 
     * @param WxPayData
     *            inputObj 提交给申请退款API的参数
     * @param int timeOut 超时时间
     * @return 成功时返回接口调用结果,其他抛异常
     * @throws Exception 
     */
    public static WxPayData Refund(WxPayData inputObj, int timeOut)
            throws Exception {
        timeOut = (timeOut == 0 ? 6 : timeOut);
        String url = "https://api.mch.weixin.qq.com/secapi/pay/refund";
        // 检测必填参数
        if (!inputObj.IsSet("out_trade_no")
                && !inputObj.IsSet("transaction_id")) {
            throw new WxPayException(
                    "退款申请接口中,out_trade_no、transaction_id至少填一个!");
        } else if (!inputObj.IsSet("out_refund_no")) {
            throw new WxPayException("退款申请接口中,缺少必填参数out_refund_no!");
        } else if (!inputObj.IsSet("total_fee")) {
            throw new WxPayException("退款申请接口中,缺少必填参数total_fee!");
        } else if (!inputObj.IsSet("refund_fee")) {
            throw new WxPayException("退款申请接口中,缺少必填参数refund_fee!");
        } else if (!inputObj.IsSet("op_user_id")) {
            throw new WxPayException("退款申请接口中,缺少必填参数op_user_id!");
        }

        inputObj.SetValue("appid", WxPayConfig.APPID);// 公众账号ID
        inputObj.SetValue("mch_id", WxPayConfig.MCHID);// 商户号
        inputObj.SetValue("nonce_str",
                UUID.randomUUID().toString().replaceAll("-", ""));// 随机字符串
        inputObj.SetValue("sign", inputObj.MakeSign("MD5"));// 签名

        String xml = inputObj.ToXml();
        long start = System.currentTimeMillis();

        Log.debug("Refund request : " + xml);
        String response = HttpService.doRefund(xml, url);// 调用HTTP通信接口提交数据到API
        Log.debug("Refund response : " + response);

        long end = System.currentTimeMillis();
        int timeCost = (int) ((end - start));// 获得接口耗时

        // 将xml格式的结果转换为对象以返回
        WxPayData result = new WxPayData();
        result.FromXml(response);

        ReportCostTime(url, timeCost, result);// 测速上报

        return result;
    }


//根据商户证书和秘钥(及商户MCHID)实现发送信息给微信服务端实现退款

 public static String doRefund(String xml,String url) throws Exception {
        /**
         * 注意PKCS12证书 是从微信商户平台-》账户设置-》 API安全 中下载的
         */
        KeyStore keyStore  = KeyStore.getInstance("PKCS12");
        FileInputStream instream = new FileInputStream(new File(WxPayConfig.SSLCERT_PATH));//PKCS12文件在服务器磁盘中的目录
        try {
            keyStore.load(instream, WxPayConfig.SSLCERT_PASSWORD.toCharArray());//这里写密码..默认是你的MCHID
        } finally {
            instream.close();
        }
        SSLContext sslcontext = SSLContexts.custom()
                .loadKeyMaterial(keyStore, WxPayConfig.SSLCERT_PASSWORD.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 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(xml, "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();
        }
    }

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值