文章目录

  • 前言
  • 一、背景
    • 1. 应用架构
    • 2. 分层支撑机制
  • 二、银行卡快捷支付
    • 1. 用户操作流程
    • 2. 系统执行流程--正常
      • 2.1 发送短信
      • 2.2 短信确认
    • 3. 系统执行流程--异常
      • 3.1 异常环节
        • 3.1.1 路由失败
        • 3.1.2 调用支付渠道失败
      • 3.2 异常处理
        • 3.2.1 路由失败
        • 3.2.2 调用支付渠道失败
    • 4. 流程解析
      • 4.1 核心代码实现
        • 4.1.1 Service实现
        • 4.1.2 类图
        • 4.1.3 快捷支付发送领域模型:QuickPayDomain
        • 4.1.4 主动支付领域模型:AbstractActivePayDomain
        • 4.1.5 聚合基类:AggregateBase
        • 4.1.6 标记领域模型:Domain
        • 4.1.7 快捷支付预支付命令链:CardQuickPaySendCommandChain
        • 4.1.8 快捷支付预支付指令:XxxCommand
      • 4.2 涉及表结构
  • 总结

前言

本篇将讲解银行卡快捷支付的实现,正常银行卡快捷支付流程过于简单,没什么好讲的,本篇将讲解如何在银行卡快捷失败后,可以顺滑的不中断内部进行支付方式转换(快捷–>代扣),以提高用户体验和支付成功率,如果觉得失败就失败,没必要想办法提高用户体验和支付成功率,那本篇请忽略,因为在你眼里这些设计都是没必要的。

同时本篇设计实现也可以当做将代扣包装为快捷对外提供。

本篇先讲解银行卡快捷发送短信环节流程实现。

一种实现,仅做参考。


一、背景

1. 应用架构

2. 分层支撑机制


本篇主要是讲解在基于paygw系统(见《渠道网关设计》)提供原子化的支付接口的基础上paycore系统进行产品的封装,如对银行卡快捷支付进行包装,在银行卡快捷支付环节失败后不中断平滑的转换为代扣。

二、银行卡快捷支付

1. 用户操作流程

用户在商城选购商品后,点击支付,进入到收银台页面,展示支付方式,选择银行卡支付,进入已绑定银行卡列表页面,选择已绑定银行卡,点击立即支付,弹出密码框/短信验证码框,本篇将讲解我们点击获取验证码--->输入验证码完成支付这个流程设计,主要是讲解内部支付方式的转换设计,如果有更好的设计实现方案,欢迎交流。

2. 系统执行流程–正常

2.1 发送短信

2.2 短信确认


如上两步为正常银行卡快捷支付流程部分系统的交互流程图。

3. 系统执行流程–异常

首先我们看下在发短信流程中的异常环节:

3.1 异常环节

3.1.1 路由失败

首先是路由失败,失败原因比较多,在路由的时候需要判断限额之类的,如果支付额度超限制等,或者压根就没有接入支持此银行卡快捷支付对应的支付渠道。那么支付路由返回无可用的支付渠道,即没有能够支持此快捷支付的支付渠道。

3.1.2 调用支付渠道失败

网络异常导致的调用支付渠道发送短信失败,或者支付渠道内部处理失败,由于是无资金变动类请求,可以当做失败处理。

3.2 异常处理

3.2.1 路由失败

路由返回无可用通道,则将Detail单状态置为失败,当做渠道发短信失败。

3.2.2 调用支付渠道失败

渠道发短信失败,将Detail单状态置为失败,生成交易类型为“代扣支付”的Detail,将Order交易类型也置为“代扣支付”,并指定短信通道为“短信中心”再次请求路由系统 ,获取到通道信息。如果获取成功,请求支付网关通过短信中心完成短信发送。

4. 流程解析

总体执行流程如下:

部分代码实现见下:

4.1 核心代码实现

4.1.1 Service实现

/*** 银行卡快捷-预支付(发送短信)*/
@Override
public PayCoreResult<BaseResultVo> prePaySend(final QuickPaySendRequest request) {return serviceTemplate.execute(new ServiceCallback<AggregateBase, PayCoreResult>() {@Overridepublic AbstractActivePayDomain beforeProcess() throws PayCoreException {//参数校验request.check();//创建领域模型return quickPayDomainFactory.createDomain(request);}@Overridepublic void execute(AggregateBase domain) throws PayCoreException {//业务流程处理QuickPayDomain quickPayDomain = (QuickPayDomain) domain;quickPaySendCommandChain.execute(quickPayDomain);}@Overridepublic PayCoreResult resultProcess(AggregateBase domain) {//返回结果处理ActivePayOrder activePayOrder = ((AbstractActivePayDomain) domain).getActivePayOrder();String bizOrderNo = StringUtils.isNotBlank(activePayOrder.getBizOrderNo()) ? activePayOrder.getBizOrderNo() : activePayOrder.getOutBizNo();return new PayCoreResult(new BaseResultVo(bizOrderNo,activePayOrder.getPayOrderNo(),activePayOrder.getOutBizNo(),activePayOrder.getBizStatus(),activePayOrder.getRespCode(),activePayOrder.getRespMsg()));}});
}

4.1.2 类图

4.1.3 快捷支付发送领域模型:QuickPayDomain

/*** @author kkk* @description 快捷支付发送领域模型*/
public class QuickPayDomain extends AbstractActivePayDomain implements RouteDomain<ActivePayOrder, CardPayDetail, QuickPaySendRequestBody> {/** 状态*/private String verifyStatus;/**  银行卡子单*/protected CardPayOrder cardPayOrder;/**  银行卡支付明细*/protected CardPayDetail cardPayDetail;//... ...
}

4.1.4 主动支付领域模型:AbstractActivePayDomain

/*** @author kkk* @description 主动支付领域模型*/
public abstract class AbstractActivePayDomain extends AggregateBase{/**  主单*/protected ActivePayOrder activePayOrder;/**  账务明细*/protected CcsDetail cssDetail;/**  优惠券子单*/protected CouponPayOrder couponPayOrder;/**  优惠券明细*/protected CouponPayDetail couponPayDetail;//... ...}

4.1.5 聚合基类:AggregateBase

/*** @author kkk* @description 聚合基类*/
public abstract class AggregateBase implements Domain {/** 交易类型 */protected String transType;/** 是否移除幂等性校验key */private boolean removeUnique = false;/** 是否外部生成渠道请求流水标识 */private boolean outInstReq = false;/*** 聚合自我检查*/public abstract void selfCheck();/*** 获取唯一性判断标识*/public abstract String getUniqueKey();/*** 获取业务订单号*/public abstract String getBizOrderNo();/*** 是否需要异常幂等性校验缓存key*/public boolean isRemoveUniqueK(){return removeUnique;}/*** 是否需要异步MQ通知*/public abstract boolean isNeedNotify();//... ...
}  

4.1.6 标记领域模型:Domain

/*** @author kkk* @description 语法堂,标记领域模型*/
public interface Domain {}

4.1.7 快捷支付预支付命令链:CardQuickPaySendCommandChain

/*** @author kkk* @description 快捷支付预支付命令链*/
@Component
public class CardQuickPaySendCommandChain extends CommandChain {/*** 构造函数将具体命令加入命令顺序列表*/@Autowiredpublic CardQuickPaySendCommandChain(UniqueCheckCommand uniqueCheckCommand,RepeatPayCheckCommand repeatPayCheckCommand,CardQuickPaySaveCommand cardQuickPaySaveCommand,CardQuickPaySendCommand cardQuickPaySendCommand,QuickPaySmsCommand quickPaySmsCommand){// 1.添加幂等性验证指令addCommand(uniqueCheckCommand);// 2.订单重复支付校验addCommand(repeatPayCheckCommand);// 3.添加保存数据库命令(收单)addCommand(cardQuickPaySaveCommand);// 4.添加快捷支付发送指令addCommand(cardQuickPaySendCommand);// 渠道发短信失败,指定sms发短信addCommand(quickPaySmsCommand);}
}

4.1.8 快捷支付预支付指令:XxxCommand

4.2 涉及表结构

涉及到的表结构核心字段如下:

发送短信环节只涉及到active_pay_order、card_pay_order、card_pay_detail、coupon_pay_order(使用优惠券)
、ccs_detail(失败情况下)


总结

本篇主要简略分析了银行卡快捷支付的整体流程,以及在发送短信环节出现问题,如何不中断的将支付方式进行转换,以提高用户支付体验以及成功率。下篇再继续分析,短信确认环节执行流程。

支付系统设计四:支付核心设计03-快捷发送短信(失败转代扣)相关推荐

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

    文章目录 前言 一.快捷支付 1. 执行流程 1.1 发送短信 1.1.1 发送短信(正常情况) 1.1.2 发送短信(异常情况) 1.2 短信确认 1.2.1 短信确认(正常情况) 1.2.2 短信 ...

  2. 【支付系统学习笔记】-二支付系统设计(支付网关设计)

    前言: 本文属于学习笔记,首先感谢原作者:凤凰牌老熊,博客链接:http://blog.lixf.cn/ 一 概述 在支付系统中,支付网关和支付渠道的对接是最核心的功能.其中支付网关是对外提供服务的接 ...

  3. 【支付系统学习笔记】-二支付系统设计(支付产品设计)

    本文属于学习笔记,首先感谢原作者:凤凰牌老熊,博客链接:http://blog.lixf.cn/ 支付产品模块是按照支付场景来为业务方提供支付服务.这个模块一般位于支付网关之后,支付渠道之前. 它根据 ...

  4. 短信系统WEB网页短信平台设计-移讯云短信系统

    短信系统WEB网页短信平台设计-移讯云短信系统 本系统支持smpp 开发语音:短信平台由c#源代码开发 短信平台服务器配置: 服务器需要 windows 2003以上的服务器 ,iis ,.net4. ...

  5. 快捷指令批量发送短信

    1.通过iphone快捷指令,使用json文本批量发送短信 2.实现方式如下 访问list里面name的方式如下: 通过object.index.key访问数组list里面的name,phone值.然 ...

  6. 支付系统设计四:轮询扣款设计04-整体设计

    文章目录 前言 一.背景 二.PayCore系统设计 1.应用架构 2.相关表 2.1 Order表 2.2 Detail表 3. 原代扣流程 三.轮询扣款改造 1. 改造后的整体流程概览 2. 改造 ...

  7. 支付系统设计四:轮询扣款设计04-详解

    文章目录 前言 一.相关表改造 1. payCore支付核心 2. payRouter支付路由系统 2.1 增加轮询规则表 2.2 后台配置页面 二.执行逻辑调整 1. payCore支付核心 1.1 ...

  8. 【支付系统学习笔记】-二支付系统设计(支付路由设计)

    前言:   本文属于学习笔记,首先感谢原作者:凤凰牌老熊,博客链接:http://blog.lixf.cn/ 作者上来回顾了支付流程, 一 设计目标 支付路由在支付系统中的核心作用,除了本职工作路由外 ...

  9. 三方支付四方支付聚合支付系统 集成 支付宝分账 代付 多商户 短信邮件 谷歌令牌验证

    三方 四方支付聚合系统 集成 支付宝分账 短信 邮件 谷歌令牌多种验证 1.系统为成熟运营版,完美对接邮件系统2.短信系统为阿里和短信宝,可多通道切换 3.增加安全机制集成了谷歌令牌 4.成熟的商户, ...

最新文章

  1. 华为汪涛:无线网络未来十年十大趋势
  2. 记录某项目中的踩坑与解决(持续更新)
  3. 确定第十五届安徽赛区国赛奖项数量
  4. 通过城市联动实时将地址显示到text中
  5. linux程序已经在后台运行冻结了_Linux 让程序在后台执行
  6. 技术博客么?开始每天一更
  7. 【OpenCV】OpenCV函数精讲之 -- createTrackbar()函数、getTrackbarPos()函数
  8. python如何制作一个工程软件_如何利用python制作一个解压缩软件-Go语言中文社区...
  9. PHP连接mysql8.0出错“SQLSTATE[HY000] [2054] The server requested authentication method unknow........
  10. 零售券商之王:零佣金的罗宾侠的400亿美金
  11. linux命令与示例 week 3
  12. SCSA网络安全------数据传输安全-------广域网加速解决方案
  13. 计算机基础考试题库(含答案)
  14. 2022低压电工判断题及在线模拟考试
  15. 104.网络安全渗透测试—[权限提升篇2]—[Linux之SUID提权]
  16. 这一刻我學會了堅強、給我一雙翅膀,我会向天空去翱翔。
  17. NumPy 数组的维度变换
  18. android 5.1 flash,Flash Player for Android 4.0 and 5.1 以上版本(提供下載)
  19. linux mysql命令行导入_在linux中导入sql文件的方法分享(使用命令行转移mysql数据库)...
  20. Android Studio中的button修改不了背景颜色

热门文章

  1. 误用箭头函数导致 jQuery中serializeArray()取不到值
  2. java assert false_深入剖析Java中的断言assert
  3. C / C++ 内存管理
  4. slambook2(ch11)—— Ubuntu18.04安装DBoW3 + 例程演示
  5. Circular dependency between the following tasks.
  6. 全球及中国平面散热管行业产销状况及供需前景预测报告(2022-2027年)
  7. LC秋季赛的败犬总结--未知数解方程模拟
  8. opencv 实线PS色阶调整
  9. C#EventHandler用法
  10. 手机html不显示图片,手机相册不显示图片怎么解决 五种情况【图文】