真香!一行代码搞定微信支付回调

本文介绍了微信支付在交易成功后对商户系统的异步回调通知机制,强调了可能存在的重复通知问题以及如何处理。文章还讨论了在处理回调时的重试策略,包括使用Spring Retry库进行重试配置,并展示了代码示例。同时指出在面对程序崩溃或集群扩展时,简单的重试可能不足,建议采用延迟队列或手动补偿方式增强系统可靠性。

前言

微信支付成功之后,会对商户系统发送异步回调请求,来通知商户支付成功。

需要注意的是:

  • 同样的通知可能会多次发送给商户系统,商户系统必须能够正确处理重复的通知

  • 后台通知交互时,如果微信收到商户的应答不符合规范或超时,微信会判定本次通知失败,重新发送通知,直到成功为止

  • 在订单状态不明或者没有收到微信支付结果通知的情况下,建议商户主动调用微信支付【查询订单API】确认订单状态。

集成

在调用外部服务进行操作时,常常因为网络抖动、服务方进行限流等因素造成查询失败。为了克服这些问题,引入了重试机制。

在通知一直不成功的情况下,微信总共会发起多次通知,通知频率为15s/15s/30s/3m/10m/20m/30m/30m/30m/60m/3h/3h/3h/6h/6h - 总计 24h4m),但微信不保证通知最终一定能成功

重试原则
  • 查询可以进行重试

  • 写操作要慎重,除非业务方支持重入

配置文件 pom.xml 引入:

<dependency>
    <groupId>org.springframework.retry</groupId>
    <artifactId>spring-retry</artifactId>
    <version>1.2.5.RELEASE</version>
</dependency>

启动类新增注解 @EnableRetry:

@EnableRetry
@EnableAsync
@EnableCaching
@EnableScheduling
@SpringBootApplication
public class Application extends SpringBootServletInitializer {

    private static final Logger logger = LoggerFactory.getLogger(Application.class);

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
        logger.info("PayCloud 支付分账系统");
    }

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(Application.class);
    }
}

回调商家客户端:

@Async
@Override
@Transactional(rollbackFor=Exception.class)
@Retryable(value= {Exception.class},maxAttempts = 10,backoff = @Backoff(delay = 2000L,multiplier = 2))
public void notifyApp(Map<String,Object> params) throws Exception {
    Date date = new Date();
    SimpleDateFormat format = new SimpleDateFormat("HH:mm:ss");
    String str = format.format(date);
    System.out.println("现在时间:" + str);
    /**
     * 处理业务逻辑
     */
    throw new Exception("应用回调异常");
}

打印时间如下:

现在时间:21:36:40
现在时间:21:36:42
现在时间:21:36:46
现在时间:21:36:54
现在时间:21:37:10
现在时间:21:37:40
现在时间:21:38:10
现在时间:21:38:40
现在时间:21:39:10
现在时间:21:39:40

需要注意的是,最后几次重试间隔定格在了30s,原因是参数中有个maxdelay属性,默认是30s。时间间隔是取{delay,maxDelay}的最小值。如果想继续递增执行,需要将 maxDelay 设置为理想的数值。

说明

参数 @Retryable 说明

  • value:抛出指定异常才会重试

  • include:和value一样,默认为空,当exclude也为空时,默认所以异常

  • exclude:指定不处理的异常

  • maxAttempts:最大重试次数,默认3次

  • backoff:重试等待策略,默认使用@Backoff,@Backoff的value默认为1000L,我们设置为2000L;multiplier(指定延迟倍数)默认为0,表示固定暂停1秒后进行重试,如果把multiplier设置为2,则第一次重试为2秒,第二次为4秒,第三次为8秒。

小结

总的来说,这玩意还是比较不错的,但是如果遇到程序崩溃或者集群扩展那问题就来了,显然是不能满足我们实际的业务需求。后期可以使用高可用的延迟队列或者手动补偿的方式来解决!

源码

支付服务:支付宝,微信,银联详细代码案例

https://gitee.com/52itstyle/spring-boot-pay

演示

后台:https://pay.cloudbed.vip

账号:pay 密码:123456

END -

1.3 万亿条数据查询,如何做到毫秒级响应?

分享六个经典的 SpringBoot 开源项目

一套通用的后台管理系统,赚钱就靠它了!

SpringBoot 开发案例之接入腾讯云短信

推荐一款基于 Java 的身份证号码识别系统

分享一个支付大屏实时监控数据平台

推荐一款清爽的实时监控大屏附安装教程

微信支付收银台功能上线了

支付宝支付新版 SDK 上线,让支付触手可及

太厉害了!我用 Nginx 提升系统10倍性能

牛逼,CTO点名要搞个灰度发布系统

微信支付分账,就是这么简单!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值