<正则吃饺子> :关于微信支付的简单总结说明(二)

关于微信退款

一、官方文档

申请退款:https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=9_4&index=6

二、退款流程图

注意:微信退款时候,需要证书服务,这里可以参见官方文档中的说明,包括证书的具体下载,解析等。(后面我也补充个证书解析的文件,方便理解)

一个百度文库的文档https://wenku.baidu.com/view/754c78e93186bceb19e8bbcc.html

三、项目中使用的代码

拿来作个参考吧,方便记忆和理解

/**
     * 微信支付申请退款
     *
     * @param weChatPayRefund
     * @return
     */
    public boolean weChatPayRefundRequest(WeChatPayRefund weChatPayRefund, String source) {
        try {
            if (null == weChatPayRefund) {
                throw new ArgumentException("参数异常");
            }
            if (Strings.isNullOrEmpty(weChatPayRefund.getRefund_fee())) {
                throw new ArgumentException("退款金额为空");
            }
            if (Strings.isNullOrEmpty(weChatPayRefund.getOut_trade_no())) {
                throw new ArgumentException("原交易编号为空");
            }

            //退款金额,微信金额单位为分,系统为元,做换算
            int refundFee = new BigDecimal(weChatPayRefund.getRefund_fee())
                    .multiply(new BigDecimal(100)).intValue();
            weChatPayRefund.setRefund_fee(String.valueOf(refundFee));
            //订单总金额单位为分
            int totalFee = new BigDecimal(weChatPayRefund.getTotal_fee())
                    .multiply(new BigDecimal(100)).intValue();
            weChatPayRefund.setTotal_fee(String.valueOf(totalFee));
            //生成随机流水号
            String timeStr = System.currentTimeMillis() + "";
            weChatPayRefund.setOut_refund_no("TK" + timeStr);
            //退款单号为UUID
            weChatPayRefund.setNonce_str(UUIDUtil.randrom());
            //生成退款参数XML
            String xml = this.createRefundXml(weChatPayRefund, source);
            String refundURL = "https://api.mch.weixin.qq.com/secapi/pay/refund";
            ClientCustomSSL clientCustomSSL = new ClientCustomSSL();
            String result = "";
            if ("01".equals(source)) {
                result = clientCustomSSL.doRefund(refundURL, xml, weChatPkcs12, "B2B");
            } else if ("02".equals(source)) {
                result = clientCustomSSL.doRefund(refundURL, xml, b2cWeChatPkcs12, "B2C");
            } else if ("03".equals(source)) {
                result = clientCustomSSL.doRefund(refundURL, xml, b2cWeChatPkcs12_new, "B2C_NEW");
            }
            //请求返回结果
            result = result.replaceAll("\n", "").replaceAll("\r", "").replaceAll("\t", "");
            Document doc = DocumentHelper.parseText(result);
            
            Map<String, Object> resultMap = XmlMapHandle.Dom2Map(doc);
            String applyId = weChatPayRefund.getApplyId();
            StringHashMapper stringHashMapper = new StringHashMapper(WeChatPayRefund.class);
            WeChatPayRefund weChatPay = (WeChatPayRefund) stringHashMapper.fromHash(resultMap);
            ConvenienceRefund refund = createRefundInfo(weChatPayRefund);
        //根据返回结果,处理一些自己的业务
if (weChatPay.getReturn_code().equalsIgnoreCase("SUCCESS") && weChatPay.getResult_code().equalsIgnoreCase("SUCCESS")) { weChatPay.setApplyId(applyId); refund.setRefundStatus("1"); this.rechargeOrderWriteDao.saveRefundInfo(refund);//保存退款信息 int updateFlag = rechargeOrderWriteDao.updateOrderPayStatus(RedisType.PAY_STATUS2.getIndex(), weChatPayRefund.getOut_trade_no()); if (updateFlag >= 1) { //退款成功 //订单日志保存 ConvenienceOrderLog orderLog = new ConvenienceOrderLog(); orderLog.setOrderId(String.valueOf(weChatPayRefund.getOut_trade_no())); orderLog.setStatusCode(50); orderLog.setStatusName("退款成功"); this.saveConvenienceOrderLog(orderLog); return true; } else { //退款失败 return false; } } else { refund.setRefundStatus("0"); this.rechargeOrderWriteDao.saveRefundInfo(refund); ConvenienceOrderLog orderLog = new ConvenienceOrderLog(); orderLog.setOrderId(String.valueOf(weChatPayRefund.getOut_trade_no())); orderLog.setStatusCode(99); orderLog.setStatusName("退款失败"); throw new BusinessException("退款失败:" + weChatPayRefund.getReturn_msg()); } } catch (Exception e) { throw new BusinessException("退款失败:请联系管理员"); } } /** * 根据订单来源生成退款参数XML * * @param weChatPayRefund * @param source * @return */ public String createRefundXml(WeChatPayRefund weChatPayRefund, String source) { String appId = ""; String mchId = ""; String key = ""; if ("01".equals(source)) { appId = weChatPayRefund.getB2b_appid_new(); mchId = weChatPayRefund.getB2b_mch_id_new(); key = weChatPayRefund.getB2b_appKey_new(); } else if ("02".equals(source)) { appId = weChatPayRefund.getB2c_appid(); mchId = weChatPayRefund.getB2c_mch_id(); key = weChatPayRefund.getB2c_appKey(); } else if ("03".equals(source)) { appId = weChatPayRefund.getB2c_appid_new(); mchId = weChatPayRefund.getB2c_mch_id_new(); key = weChatPayRefund.getB2c_appKey_new(); } //生成退款签名 SortedMap<String, String> packageParams = new TreeMap<String, String>(); packageParams.put("appid", appId); packageParams.put("mch_id", mchId); packageParams.put("nonce_str", weChatPayRefund.getNonce_str()); packageParams.put("out_trade_no", weChatPayRefund.getOut_trade_no()); packageParams.put("out_refund_no", weChatPayRefund.getOut_refund_no()); packageParams.put("total_fee", weChatPayRefund.getTotal_fee()); packageParams.put("refund_fee", weChatPayRefund.getRefund_fee()); packageParams.put("op_user_id", mchId); RequestHandler reqHandler = new RequestHandler(null, null); reqHandler.init(appId, "", key); String sign = reqHandler.createSign(packageParams); String xml = org.apache.commons.lang3.StringUtils.join("<xml>", "<appid>", appId, "</appid>", "<mch_id>", mchId, "</mch_id>", "<nonce_str>", weChatPayRefund.getNonce_str(), "</nonce_str>", "<sign><![CDATA[", sign, "]]></sign>", "<out_trade_no>", weChatPayRefund.getOut_trade_no(), "</out_trade_no>", "<out_refund_no>" + weChatPayRefund.getOut_refund_no(), "</out_refund_no>", "<total_fee>", weChatPayRefund.getTotal_fee(), "</total_fee>", "<refund_fee>" + weChatPayRefund.getRefund_fee(), "</refund_fee>", "<op_user_id>" + mchId, "</op_user_id>", "</xml>"); return xml; }

四、引申与其他

(待续..)

 

posted @ 2017-08-19 17:23  正则吃饺子  阅读(640)  评论(0编辑  收藏  举报