支付系统设计四:支付核心设计03-快捷短信确认(失败转代扣)

news2024/12/24 9:19:32

文章目录

  • 前言
  • 一、快捷支付
    • 1. 执行流程
      • 1.1 发送短信
        • 1.1.1 发送短信(正常情况)
        • 1.1.2 发送短信(异常情况)
      • 1.2 短信确认
        • 1.2.1 短信确认(正常情况)
        • 1.2.2 短信确认(异常情况)
    • 2. 短信确认流程分析
      • 2.1 Service层执行
      • 2.2 快捷支付确认
        • 2.2.1 快捷支付确认命令链
        • 2.2.2 流程分析
        • 2.2.3 详解
      • 2.3 代扣
        • 2.3.1 代扣命令链
        • 2.3.2 流程分析
        • 2.3.3 详解
  • 总结


前言

在上篇文章中《支付系统设计四:支付核心设计03-快捷发送短信(失败转代扣)》主要讲解了,在快捷支付发送验证码环节,如果发送验证码失败,或者没有业务线没有接入快捷通道,为了不中断支付,系统内部转化支付方式(快捷–>代扣),本来由支付渠道发送短信,转为短信中心发送验证短信,本篇将讲解验证短信环节。


一、快捷支付

1. 执行流程

1.1 发送短信

1.1.1 发送短信(正常情况)

在这里插入图片描述

1.1.2 发送短信(异常情况)

在这里插入图片描述
在请求支付路由系统获取可用的快捷支付渠道(从支付路由系统获取支持此笔快捷支付交易的支付渠道的交易类型配置相关信息)时,如果失败了,则指定短信发送渠道(短信中心),再次请求支付路由系统,获取到配置的短信中心发送短信交易类型的配置信息,然后请求支付路由系统,支付路由系统组装请求短信中心完成短信的发送。

1.2 短信确认

1.2.1 短信确认(正常情况)

在这里插入图片描述

1.2.2 短信确认(异常情况)

在这里插入图片描述
支付核心系统首先请求支付网关系统完成短信验证码的核验,通过后请求支付路由系统获取代扣渠道,获取成功则请求支付网关系统发起代扣请求,支付网关组装请求支付渠道的报文,请求支付渠道,完成代扣。

2. 短信确认流程分析

2.1 Service层执行

@Override
public PayCoreResult confirmPay(final QuickPayConfirmRequest request) {
	return serviceTemplate.execute(new ServiceCallback<AggregateBase, PayCoreResult>() {
		@Override
		public AbstractActivePayDomain beforeProcess() throws PayCoreException {
			request.check();
			QuickPayDomain confirmDomain = quickPayDomainRepository.findByActivePayOrderNo(request.getOrgPayOrderNo(), GwTransEnum.QUICK_PAY_SEND_MSG.getCode());
			AssertUtils.isTrue(confirmDomain.getActivePayOrder().getBizStatus().equals(BizStatus.DOING.code()), SystemErrorCode.BIZ_CHECK_ERROR, "支付订单已完成");
			AssertUtils.isNotNull(confirmDomain.getCardPayDetail(), SystemErrorCode.DATA_NOT_EXIST, "快捷支付详单不存在");
			AssertUtils.isTrue(StringUtils.equals(confirmDomain.getCardPayDetail().getProcessStatus(), ProcessStatus.GW_SUCCESS.code()), SystemErrorCode.BIZ_CHECK_ERROR, "未成功发送短信");
			return new QuickPayConfirmDomain(confirmDomain, request.getSmsVerifyCode());
		}

		@Override
		public void execute(AggregateBase domain) throws PayCoreException {
			QuickPayConfirmDomain confirmDomain = (QuickPayConfirmDomain) domain;
			//CardPayOrder判断银行卡订单类型选择执行:快捷支付确认命令链/银行卡代扣命令链
			CardPayOrder cardPayOrder = confirmDomain.getCardPayOrder();
			if (QuickPayTypeEnum.QUICK_PAY.getCode().equals(cardPayOrder.getPayType())) {
				//快捷确认支付命令链
				cardQuickPayConfirmCommandChain.execute(confirmDomain);
			} else {
				//转系统验证短信,执行代扣命令链
				cardDeductReceiptCommandChain.execute(confirmDomain);
			}
		}

		@Override
		public PayCoreResult resultProcess(AggregateBase domain) {
			QuickPayConfirmDomain confirmDomain = (QuickPayConfirmDomain) domain;
			ActivePayOrder activePayOrder = confirmDomain.getActivePayOrder();
			//返回结果处理
			String bizOrderNo = StringUtils.isNotBlank(activePayOrder.getBizOrderNo()) ? activePayOrder.getBizOrderNo() : activePayOrder.getOutBizNo();
			return new PayCoreResult(new QuickConfrimResultVo(
					bizOrderNo,
					activePayOrder.getPayOrderNo(),
					activePayOrder.getOutBizNo(),
					activePayOrder.getBizStatus(),
					confirmDomain.getVerifyStatus(),
					activePayOrder.getRespCode(),
					activePayOrder.getRespMsg()));
		}
	});
}

2.2 快捷支付确认

2.2.1 快捷支付确认命令链

/**
 * @author kkk
 * @description 快捷支付确认命令链
 */
@Component
public class CardQuickPayConfirmCommandChain extends CommandChain {

    @Autowired
    public CardQuickPayConfirmCommandChain(UniqueCheckCommand uniqueCheckCommand,
                                           CouponLockCommand couponLockCommand,
                                           CardQuickPayConfirmCommand cardQuickPayConfirmCommand,
                                           CouponModifyCommand couponModifyCommand,
                                           PayResultNotifyBizCommand notifyBizCommand) {

        // 1.添加幂等性验证指令
        addCommand(uniqueCheckCommand);

        // 2.锁定优惠券
        addCommand(couponLockCommand);

        // 3.发起快捷支付确认:同步返回结果
        addCommand(cardQuickPayConfirmCommand);

        // 4.解锁优惠券
        addCommand(couponModifyCommand);

        // 5.通知账务
        addCommand(notifyBizCommand);
    }
}

2.2.2 流程分析

在这里插入图片描述

2.2.3 详解

待补充…

2.3 代扣

2.3.1 代扣命令链

/**
 * @author kkk
 * @description 银行卡快捷转代扣命令链
 */
@Component
public class CardDeductReceiptCommandChain extends CommandChain {

    /**
     * 构造函数将具体命令加入命令顺序列表
     */
    @Autowired
    public CardDeductReceiptCommandChain(UniqueCheckCommand uniqueCheckCommand,
                                         QuickPaySmsVerifyCommand quickPaySmsVerifyCommand,
                                         CouponLockCommand couponLockCommand,
                                         CardDeductReceiptCommand cardDeductReceiptCommand,
                                         CouponModifyCommand couponModifyCommand,
                                         PayResultNotifyBizCommand notifyBizCommand){

        // 1.添加幂等性验证指令
        addCommand(uniqueCheckCommand);

        //2.验证码校验
        addCommand(quickPaySmsVerifyCommand);

        //3.锁定优惠券
        addCommand(couponLockCommand);

        //4.发起代扣:同步返回结果
        addCommand(cardDeductReceiptCommand);

        //5.解锁优惠券
        addCommand(couponModifyCommand);

        //6.通知账务入账
        addCommand(notifyBizCommand);
    }
}

2.3.2 流程分析

在这里插入图片描述

2.3.3 详解

待补充…


总结

整体脉络还是比较简单的,处理一些细节上还是有很多地方需要注意的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/603231.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Nacos 详解

Nacos是阿里的一个开源产品&#xff0c;是针对微服务架构中的服务发现、配置管理、服务治理的综合型解决方案。 1.1 什么是配置 应用程序在启动和运行的时候往往需要读取一些配置信息&#xff0c;配置基本上伴随着应用程序的整个生命周期&#xff0c;比如&#xff1a;数 据库…

istio证书异常

istio有时会出现证书异常的问题&#xff0c;例如证书校验失败&#xff0c;证书过期等&#xff0c;此时需要我们手动处理istio证书问题。 一、我的istio版本 client version: 1.3.3 control plane version: 1.3.3二、开始处理 1、先查询istio的密钥istio-ca-secret&#xff1a…

飞桨 GPU 训练

飞桨官网介绍使用流程 paddle —— 飞桨的深度学习核心框架本地 padddlepaddle 的安装和卸载安装查看当前安装的版本卸载 启动 GPU 训练指定 GPU 飞桨创建项目PaddlePaddle 2.1.2 下的对比修改为 paddlepaddle2.4.0 CUDA 飞桨 飞桨官网&#xff1a;https://www.paddlepaddle.o…

编程最重要的技术之一 — 调试(以C语言代码为例)

编程最重要的技术之一 — 调试&#xff08;以C语言代码为例&#xff09; 前言1. 什么是bug?2. 调试是什么&#xff1f;有多重要&#xff1f;2.1 调试是什么&#xff1f;2.2 调试的基本步骤2.3 Debug和Release的介绍 3. Windows环境调试介绍3.1 调试环境准备3.2 学会快捷键3.3 …

Unity - 记录解决 部分手机设备上 浮点精度 不足 导致 UV 采样断层严重的 BUG

文章目录 环境目的问题解决Project 环境 Unity : 2020.3.37f1 Pipeline : BRP 目的 备忘&#xff0c;便于日后索引 问题 正常手机显卡芯片的浮点解析进度上的效果&#xff08;其实不用手机上&#xff0c;PC 上将 uv * scale 一个巨大的值也会出现的&#xff09; 异常手机显…

MySql Order by 字段出现重复导致 limit 分页后的数据错乱

问题描述 select * from standard_process order by event_time desc 此条sql查询的结果如下&#xff1a; 共有28条数据&#xff0c;确实是按照event_time排序的。 但是加了limit以后就出现问题了&#xff0c;原本以为是截取的前10条&#xff0c;结果出现了数据错乱的情况。 …

安装VTK8.2.0-win 实际操作

Windows下安装VTK8.2.0 1、依赖 VS2017 Qt5 cmake 2、前期准备 2.1、访问vtk官方下载VTK8.2.0源码 VTK源码下载地址&#xff1a;https://vtk.org/download/ 2.2、配置环境变量 配置CMAKE_PREFIX_PATH&#xff0c;值为Qt的bin路径 2.3、新建2个文件夹一个用于存放cmake编…

Fourier分析入门——第14章——Fourier光学

目录 第14章 Fourier光学 14.1 引言 14.2 物理光学和图像形成(Physical optics and images formation) 14.3 Fourier光学域(The Fourier optics domain) 14.4 图像形成的线性系统描述(Linear Systems Description of Image Formation) 第14章 Fourier光学 14.1 引言 Four…

操作系统-进程和线程-进程和线程

目录 一、进程的概念、组成、特征 二、进程的状态与转换、组织 2.1进程状态 2.2进程转换关系 2.3进程的组织 链接方式 索引方式 三、进程控制 3.1进程的创建 3.2进程的终止 3.3进程的阻塞和唤醒 3.4进程的切换 ​编辑 四、进程通信 4.1共享存储 4.2消息传递 直接通信…

C++算法刷题--2023/6/2

源代码&#xff08;C&#xff09;&#xff1a; #include<iostream> using namespace std; struct Road{char way[100]{}; }; int main(){int t;cin>>t;struct Road *p new Road[t];int right0,left0;for(int i0;i<t;i){cin>>p[i].way;} for(int i0;i&…

力扣刷题【第一期】

文章目录 1.爬楼梯2.求两数的和&#xff08;283&#xff09;3.移动零&#xff08;283&#xff09;3.1 题目描述3.2 算法描述3.3具体实现 4.合并有序连表&#xff08;21&#xff09;4.1 题目描述4.2 算法思想4.3 代码实现 5.删除连表中重复的值&#xff08;83&#xff09;5.1 题…

CodeEditor之sublimetext:sublimetext的简介、安装、使用方法之详细攻略

CodeEditor之sublimetext&#xff1a;sublimetext的简介、安装、使用方法之详细攻略 目录 sublimetext的简介 sublimetext的安装 1、安装教程如下所示 sublimetext的使用方法 sublimetext的简介 Sublime Text 是一个文本编辑器&#xff08;收费软件&#xff0c;可以无限期试…

javascript基础十五:说说new操作符具体都干了什么?

一、是什么 在JavaScript中&#xff0c;new操作符用于创建一个给定构造函数的实例对象 举个粟子 function Parent (name,age){this.name name;this.age age; } undefined Parent.prototype.sayName function(){console.log(this.name) } ƒ (){console.log(this.name) } c…

佛朗斯冲击港交所IPO:叉车租赁的未来是数字化?

佛朗斯“三战”IPO。 图源&#xff1a;佛朗斯 近日&#xff0c;广州佛朗斯股份有限公司&#xff08;下文简称为“佛朗斯”&#xff09;正式向港交所递交招股书&#xff0c;拟于港交所主板挂牌上市。 值得注意的是&#xff0c;这并不是佛朗斯首次冲击IPO。2019年6月和2020年7月…

操作系统-计算机系统概述-特性发展分类分层结构

目录 一、定义 1.1特征 二、操作系统的分类和发展 2.1手工操作阶段 2.2批处理阶段 2.2.1单道批处理系统 2.2.2多道批处理系统 2.3分时操作系统 2.4实时操作系统 2.5 网络操作系统 2.6分布式操作系统 2.7 个人计算机操作系统 三、操作系统的运行与机制 内核态和用…

【Python】函数 ⑤ ( 函数说明文档 | 函数说明文档内容建议 | 代码示例 )

文章目录 一、函数说明文档1、函数说明文档简介2、函数说明文档内容建议2、代码示例 - 函数说明文档 一、函数说明文档 1、函数说明文档简介 函数说明文档 就是 通过 注释 对 函数的作用进行解释说明 ; 函数说明文档 用法 : 在 函数定义 后 , 函数体的第一行位置 , 输入六个双…

Linux:Linux基础网络设置

ifconfig ifconfig #查看网卡信息 inet---网络接口的ip地址 netmask---子网掩码 broadcast---广播地址 ether----物理地址&#xff08;mac地址&#xff09; hostname hostname #查看主机名 hostnamectl set-hostname 自定义主机名 route route # 查看网卡网关 destination-…

华为OD机试真题B卷 Java 实现【检查是否存在满足条件的数字组合】,附详细解题思路

一、题目描述 给定一个正整数数组&#xff0c;检查数组中是否存在满足规则的数字组合 规则&#xff1a;A B 2C 二、输入描述 第一行输出数组的元素个数。 接下来一行输出所有数组元素&#xff0c;用空格隔开。 三、输出描述 如果存在满足要求的数&#xff0c;在同一行…

Ubuntu使用ssh连接两个主机

前提&#xff1a;两者连接同一个WiFi&#xff08;局域网&#xff09; ssh安装&#xff1a; sudo apt-get install openssh-client sudo apt-get install openssh-server 首先在两个主机分别终端输入&#xff1a;ifconfig 查询两者的ip 用户名是前面的那个&#xff1a; …

【算法系列 | 1】深入解析排序算法之冒泡排序

序言 你只管努力&#xff0c;其他交给时间&#xff0c;时间会证明一切。 文章标记颜色说明&#xff1a; 黄色&#xff1a;重要标题红色&#xff1a;用来标记结论绿色&#xff1a;用来标记一级论点蓝色&#xff1a;用来标记二级论点 决定开一个算法专栏&#xff0c;希望能帮助大…