首页 > 其他分享 >微信支付发起退款时,异常解决

微信支付发起退款时,异常解决

时间:2024-08-29 18:47:18浏览次数:8  
标签:refund 发起 微信 cashierPayment new 退款

保证自身服务代码正常情况下

微信发起退款的异常分两种

第一种是业务异常:账户余额不足 等退款失败|或者超额退款失败

第二种是网络异常:创建微信Config时会执行一次微信校验;会调用api.mch.weixin.qq.com 校验 | 还有真实发起退款可能也会因为api.mch.weixin.qq.com的DNS解析出错导致连接失败

代码如下

  /**
     * 当交易发生之后一段时间内,由于买家或者卖家的原因需要退款时,卖家可以通过退款接口将支付款退还给买家,
     * <p>
     * 微信支付将在收到退款请求并且验证成功之后,按照退款规则将支付款按原路退到买家帐号上。
     *
     * @param cashierPayment cashierPayment
     * @return Refund
     */
    @SuppressWarnings("unchecked,deprecation,unused")
    public Refund refundOrderV3(CashierPayment cashierPayment, CashierPayment originalOrder) {
        Refund refund = null;
        try {
            Config wxConfig = wxConfigService.getWxConfig(cashierPayment.getPayChannelId(), new PayChannel());
            String wxCallBackUrl = wxConfigService.getWxCallBackUrl(true, originalOrder.getMerchantId());
            RefundService service = new RefundService.Builder().config(wxConfig).build();
            CreateRequest request = new CreateRequest();
            // 退款收银台订单号
            request.setOutRefundNo(cashierPayment.getPaymentNo());
            // 微信支付订单号(原支付渠道流水号)
            request.setTransactionId(cashierPayment.getChannelFlowNo());
            // 使用可用余额退款 ===== request.setFundsAccount(ReqFundsAccount.AVAILABLE);
            request.setNotifyUrl(wxCallBackUrl);
            // 退款金额
            AmountReq amountReq = new AmountReq();
            // 原始订单金额
            amountReq.setTotal(originalOrder.getAmount());
            // 退款订单金额
            amountReq.setRefund(cashierPayment.getRefundAmount());
            amountReq.setCurrency(StringUtils.isEmpty(cashierPayment.getCurrencyType()) ? "CNY" : cashierPayment.getCurrencyType());
            request.setAmount(amountReq);
            // 发起退款
            refund = service.create(request);
        } catch (ServiceException e) {
            // 捕捉-微信退款下单时返回的状态码是发送HTTP请求成功,服务返回异常。例如返回状态码小于200或大于等于300。
            String errorCode = e.getErrorCode();
            // 判断由定时任务调度过来的|跳过本地环境---直接操作微信环境---引起本地和微信订单不同步操作
            String message = e.getErrorMessage();
            if (errorCode.equals("INVALID_REQUEST") && message.equals("订单已全额退款")) {
                log.info("订单已全额退款" + cashierPayment.getPaymentNo());
                throw new BusinessException(Status.SUCCESS.name());
            }
            log.error("发起退款失败,错误码:{}", errorCode, e);
            throw new BusinessException(errorCode);
        } catch (Exception e) {
            if (e instanceof BusinessException) {
                log.error(e.getMessage(), e);
                throw e;
            }
            // 防止网络连接不上---标记失败放入重试队列
            log.error(cashierPayment.getPaymentNo() + "发起退款失败:{}", e.getMessage(), e);
            throw new BusinessException("HTTP_TIME_OUT");
        }
        log.debug("退款处理--微信结果:{}", refund.toString());
        if (refund.getStatus() == Status.SUCCESS ||
                refund.getStatus() == Status.PROCESSING) {
            log.info("发起退款成功:" + cashierPayment.getPaymentNo());
            return refund;
        } else {
            log.error("发起退款失败:{}", refund.getStatus());
            throw new BusinessException("发起退款失败");
        }

核心1-业务错误:根据微信侧的ServiceException异常获取错误码;可以在不同类型错误时做出对应处理

比如 errorCode.equals("INVALID_REQUEST") && message.equals("订单已全额退款") 这种就是已经退款完了,还发起的可以做幂等或者别的操作

比如 NOT_ENOUGH 错误码,代表余额不足,无法发起退款。。可以提醒管理员需要往微信里面充钱了,或者建议微信账户始终保留部分余额。。防止结算后账户没钱用于客户退款

比如 USER_ACCOUNT_ABNORMAL 等等......

核心2-网络错误:

可以捕捉异常:判断是否是网络错误类型 api.mch.weixin.qq.com: Name or service not known等 ,如果是就记录退款订单信息,

然后由定时任务调度退款异常订单,判断是否是网络错误等需要重新发起退款的订单,执行微信退款调用重放。。。

还可以把错误订单信息发送时,通过短信推送到管理员手里,做一次手动补偿重发退款的事件

基本就大概率解决退款问题了

退款微信通知回调你的接口时;

建议做成同步接口,保证你的业务处理成功才给微信返回成功,否则就返回给微信失败。不要自己去维护微信推送给你成功,你业务处理失败场景,减少服务的压力和性能开销。。。。

标签:refund,发起,微信,cashierPayment,new,退款
From: https://www.cnblogs.com/gtnotgod/p/18387411

相关文章

  • 微信私域&SEO运营神器,9款RPA机器人上线
    上一期我们分享了7款抖音RPA机器人,很多爪爪们都开始用了起来......
  • 基于STM32设计的智能饮水机_升级版(微信小程序)(213)
    文章目录一、前言1.1项目介绍【1】项目功能介绍【2】设计实现的功能【3】项目硬件模块组成1.2设计思路【1】整体设计思路【2】ESP8266工作模式配置1.3项目开发背景【1】选题的意义【2】可行性分析【3】参考文献【4】摘要【5】选题背景【6......
  • 微信开发者工具启用Mock模拟网络请求
    当开发微信小程序在后端接口还没开发好的情况下,想要进行接口调试怎么办?微信开发者工具提供了Mock功能,方便开发者模拟网络请求提前调试。1、在调试器中选Mock2、启用Mock3、新建规则API接口选择request(网络请求)类型参数规则匹配,填写正确的url正则匹配规则(包含参数)模......
  • NETCORE下用SKIT类库发送微信模板消息
    NETCORE下用SKIT类库发送微信模板消息 //测试发送模板消息-微信公众号//https://developers.weixin.qq.com/doc/offiaccount/Message_Management/Template_Message_Interface.html#5publicasyncTask<IActionResult>Ceshi(intid,stringopenid)......
  • 超实用技巧!微信小程序圆码转换方形黑白二维码
    如今二维码在各行各业都被广泛应用,好多平台为了方便分享,都能把个人账号主页、发布的视频/文章、上架的商品等生成二维码,微信小程序自然也不例外。有些朋友因为二维码的应用场景比较复杂,就想把小程序的圆形二维码变成常规的方形二维码,这该咋整呢?其实很简单!我们把圆码变成二......
  • 微信小程序 BLE 基础业务接口封装
    写在前面:本文所述未必符合当前最新情形(包括蓝牙技术发展、微信小程序接口迭代等)。微信小程序为蓝牙操作提供了很多接口,但在实际开发过程中,会发现隐藏了不少坑。目前主流蓝牙应用都是基于低功耗蓝牙(BLE)的,本文介绍相关的几个基础接口,并对其进行封装,便于业务层调用。蓝牙发展在开......
  • 微信小程序for循环怎么用
    微信for简单使用: <view>    <ul>        <li wx:for="{{xiaoke}}" wx:key="index">            <a href="{{item.path}}">{{item.name}}</a>        </li>    </ul></view>其中"xiao......
  • [开题]flask框架信息安全知识学习微信小程序10fhc(程序+论文+python)
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容研究背景在数字化时代,信息安全已成为社会经济发展的重要基石。随着移动互联网的普及,微信小程序作为一种轻量级的应用形态,迅速渗透到人们的日常生活......
  • 微信小程序考勤签到管理系统(源码+lw+部署文档+讲解等)
    文章目录前言......
  • 基于微信小程序的智能停车管理系统(源码+lw+部署文档+讲解等)
    文章目录前言......