浅析微信支付:申请退款、退款回调接口、查询退款

本文详述微信支付退款流程,包括申请退款接口的调用、退款回调接口的解密处理和查询退款的方法。强调退款异常处理、AES解密问题及退款通知的并发控制。同时提供了解决JCE加密限制的方案,并提示关注退款错误码以确保数据同步。
摘要由CSDN通过智能技术生成

本文是【浅析微信支付】系列文章的第八篇,主要讲解商户如何处理微信申请退款、退款回调、查询退款接口,其中有一些坑的地方,会着重强调。


浅析微信支付系列已经更新七篇了哟~,没有看过的朋友们可以看一下哦。

浅析微信支付:查询订单和关闭订单

浅析微信支付:支付结果通知

浅析微信支付:统一下单接口

在实际场景中,申请退款和退款回调接口是比较常用到的微信支付接口,这里我们会讲原路返回方式的退款,还有的是使用直接为用户付款到零钱现金红包等方式来退款,此种情况主要会出现在客服退款时,不是全部退款的情况,也有的会出现在使用了微信代金券-单品券的时候,因为单品券不能部分退款,所以只能走企业付款用户的方式,以下我们主要讲原路返回退款。

PS:原路返回的意思就是,从你支付时的关联支付单中扣款,微信会记录相关数据,可以在客户端通知中展示。

1、申请退款接口

以下为微信官方的申请退款文档:

https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_4
1.1. 应用场景

当交易发生之后一段时间内,由于买家或者卖家的原因需要退款时,卖家可以通过退款接口将支付款退还给买家,微信支付将在收到退款请求并且验证成功之后,按照退款规则将支付款按原路退到买家帐号上。

注意:
1、交易时间超过一年的订单无法提交退款
2、微信支付退款支持单笔交易分多次退款,多次退款需要提交原支付订单的商户订单号和设置不同的退款单号。申请退款总金额不能超过订单金额。 一笔退款失败后重新提交,请不要更换退款单号,请使用原商户退款单号
3、请求频率限制:150qps,即每秒钟正常的申请退款请求次数不超过150次
错误或无效请求频率限制:6qps,即每秒钟异常或错误的退款申请请求不超过6次
4、每个支付订单的部分退款次数不能超过50次

PS:以上限制一般情况下不会出现,但我们也必须写入系统异常场景处理中,请求频率可以使用队列或增加延迟等方式来处理,部分退款此时不要超过微信的限制。

1.2. 接口链接
https://api.mch.weixin.qq.com/secapi/pay/refund
1.3. 是否需要证书

请求需要双向证书。

PS:关于微信证书,可以在 [商户平台-账户中心-API安全] 去下载,此证书很多支付接口均需要使用,请将证书地址配置为常量,具体实现可以参考作者github源码。

1.4. 调用接口

先看源码,如下:

/**
 * [微信退款接口] - 保存调用的相关记录
 * @param refundPayment 退款订单的支付记录
 * @param tradePayment 历史付款单
 * @return map
 * @throws Exception e
 *
 * @author yclimb
 * @date 2018/6/21
 */
public Map<String,String> saveWxPayRefund(Payment refundPayment, Payment tradePayment) throws Exception {
    if (refundPayment == null || tradePayment == null) {
        return null;
    }

    // 微信订单号/商户订单号,必须传入其中一个,此处默认传入商户订单号
    // 微信订单号,微信生成的订单号,在支付通知中有返回
    // String transaction_id = null;
    // 商户订单号,商户系统内部订单号,要求32个字符内,只能是数字、大小写字母_-|*@ ,且在同一个商户号下唯一。
    String out_trade_no = tradePayment.getFlowNumer();
    // 商户退款单号,商户系统内部的退款单号,商户系统内部唯一,只能是数字、大小写字母_-|*@ ,同一退款单号多次请求只退一笔。
    String out_refund_no = refundPayment.getFlowNumer();
    // 订单总金额,传入参数单位为:元
    String total_fee = String.valueOf(tradePayment.getAmount());
    // 退款总金额,订单总金额,传入参数单位为:元
    String refund_fee = String.valueOf(refundPayment.getAmount());
    // 退款原因,若商户传入,会在下发给用户的退款消息中体现退款原因
    String refund_desc = refundPayment.getBody();

    // 微信支付对象
    WXPay wxPay = new WXPay(WXPayConfigImpl.getInstance());

    // 微信退款接口
    Map<String, String> resultMap = wxPay.refund(refundUrl, null, out_trade_no, out_refund_no, total_fee, refund_fee, refund_desc);
    logger.info("saveWxPayRefund:resultMap:" + resultMap.toString());

    // 记录付款流水


    // 下单失败,进行处理
    if (WXPayConstants.FAIL.equals(resultMap.get(WXPayConstants.RETURN_CODE)) ||
            WXPayConstants.FAIL.equals(resultMap.get(WXPayConstants.RESULT_CODE))) {

        // 处理结果返回,无需继续执行
        resultMap.put(WXPayConstants.RESULT_CODE, WXPayConstants.FAIL);
        resultMap.put(WXPayConstants.ERR_CODE_DES, resultMap.get(WXPayConstants.RET
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值