微信小程序之退款

/**
 * @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();
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值