说到支付网关,首先看一下网关的定义,网关的作用是实现网络之间的通讯链接,包含两个基本功能:网间连接和协议转换。 同理,商户业务系统中的支付板块实现的就是商户业务系统与银行支付系统之间的链接,所起到的作用是类似的,可以被看作为一个网关。
因此,本文要讲的支付网关设计,其实就是商户业务系统的支付板块设计,下文特指58集团支付网关的设计,但本文重在“网关”,不在“支付”。也所以,支付网关业务特性要求的功能方面就不再展开了,只介绍支付网关在通用网关设计要求上的功能部分,包括统一接口、渠道路由、安全校验、权限校验、IP白名单、流量削锋、服务探活、监控报警、负载均衡等。
初期,58支付系统为58集团各个业务线提供收银台与充值页(支付paycenter系统)的收款功能,58财务系统(apply系统)同样为各个业务线提供了打款功能,根据用户及业务要求,需要提供多家银行收付款支持。初期为了快速迭代,通过分别直接对接第三方支付的系统接口来完成功能开发。这时可以理解为第三方支付系统就是58支付体系的网关。

后期,随着公司业务发展及商务合作,58支付系统及58财务系统需要对接多家第三方支付服务,这时候需要解决的问题是如何简单方便接入多家第三方支付服务,另外对58支付体系的需求也发生了变化,支付网关的位置也需要进一步前移,对58支付体系提出了更高的要求。这时我们决定搭建自己的支付网关,并针对常规业务及需求抽象出通用的功能模块。

1)统一接口
2)渠道路由
3)安全校验
4)权限校验
5)IP表名单
6)流量削峰
7)监控报警
8)服务探活
9)负载均衡
不同的第三方支付服务,它们针对基础的收付款功能接口,各自有自己的接口参数及返回值格式要求。网关需要提供统一通用的接口,规定其参数及返回值,为上层业务屏蔽第三方支付服务接口的复杂性,这就要求支付网关需要具有接口适配能力。
下图以连连收款与易宝收款为例,展现“统一接口”设计架构与处理流程。

注:以上设计使用到适配器模式实现。
接着上一部分,网关该如何选择或路由到对应的第三方支付渠道,例如是通过微信或是支付宝,或是其他第三方支付渠道,网关提供多种策略,下面简单介绍两种。
1)渠道id策略路由:网关接入方通过显示传递渠道id方式,例如收银台默认选择微信收款,则显示传递给网关对应的微信渠道id,则网关通过渠道配置信息,选择微信渠道进行收款。
2)费率计算策略路由:如上层业务未传递渠道id,则网关会根据判断,选择费率计算策略,例如第三方支付服务A每一笔收款都将收取1元手续费;第三方支付服务B单笔收款收取0.1%元手续费,则在单笔收款金额低于1000元时,走渠道B更为划算,反之则走渠道A更为划算。
下图以连连收款与易宝收款为例,展现“渠道路由”设计架构与处理流程。

注:以上设计使用到策略模式实现。
如何判断网关调用方是否拥有网关的接入权限,我们采用校验参数签名的方式。
1)网关的接入方将被分配到一个接入id(parterId)及接入秘钥(secretKey)。
2)调用方调用网关接口时除了传递必要参数,仍将传递接入id,及参数签名sign值;为了安全强度还将加入当前时间戳now作为签名参数并作为参数并一同传递,用于控制安全访问的时间范围。
3)网关接到调用请求时将校验参数签名的合法性。
下图以收款为例,展现“安全校验”设计处理流程。

注:以上设计使用到请求拦截器及参数签名校验方式进行实现。
如何判断网关调用方是否拥调用网关某一功能接口的权限。
1)网关的接入方将被分配到一个接入id(parterId),调用网关某一个功能接口时将作为参数进行传递。
2)网关接到调用请求时将根据权限配置,判断对应的接入id是否拥有当前接口的访问权限。
下图以收款为例,展现“权限校验”设计处理流程。

注:以上设计使用到请求拦截器实现。
如何判断调用方请求是否来源于某一安全ip或网段。
下图以收款为例,展现“IP白名单”设计的处理流程。

某些第三方支付服务接口对于一定时间内接口访问次数存在一定限制,所以在流量高峰时,需要针对网关接口的请求进行流量削锋。
1)根据redis zset数据结构实现时间窗口算法逻辑,记录一定时间窗口内网关访问某第三方支付服务特定接口的访问次数。
2)与该接口的单位时间内限流值配置进行比较,需要限流则放入将调用请求信息放入redis队列中。
3)异步补偿模块在流量低峰时,拉取redis队列中的请求信息,完成接口调用;再通过消息模块,异步通知网关的接入方调用结果。

注:通过redis zset实现的时间窗口算法,此处不再展开,可自行查阅网上资料。
网关的异常根据分类可分为业务异常及系统异常,可以采用AOP实现异常的统一捕获并进行细化分类,通过按照不同的分类作为不同属性,上报wmonitor实现网关的监控报警。

第三方支付服务接口的可用性,即包括其自身可用性,往往也包括网络是否可达的问题。第三方支付服务不会主动通知网关其当前可用性信息,所以需要网关实现探活模块,主动进行心跳检测。
1)通过一定时间间隔窗口访问各个第三方支付服务查询接口,封装探活模块。
2)当发现某个第三方支付服务不可用时,异常属性上报WMonitor,进行报警;并将该服务接口标识为不可用状态,作为支付网关的渠道路由功能的前置判断依据。

关于负载均衡,支付网关不需要保证对第三方支付服务的调用请求进行负载均衡控制,而是由第三方支付服务接口自身保证其可靠性及健壮性。但是支付网关依然针对特殊业务场景做了一些调用请求的均衡工作,例如支付网关通过轮询方式调用招行3台前置机,方案也相对简单,此处不表。
支付网关除了上面介绍的一些通用网关的要求功能外,还有着支付体系要求的秘钥服务、通知、配置、开放平台、预算、推荐等基础功能。
以下是支付网关的功能架构图

我有一个模型:classItem项目有一个属性“商店”基于存储的值,我希望Item对象对特定方法具有不同的行为。Rails中是否有针对此的通用设计模式?如果方法中没有大的if-else语句,这是如何干净利落地完成的? 最佳答案 通常通过Single-TableInheritance. 关于ruby-on-rails-Rails-子类化模型的设计模式是什么?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.co
我将应用程序升级到Rails4,一切正常。我可以登录并转到我的编辑页面。也更新了观点。使用标准View时,用户会更新。但是当我添加例如字段:name时,它不会在表单中更新。使用devise3.1.1和gem'protected_attributes'我需要在设备或数据库上运行某种更新命令吗?我也搜索过这个地方,找到了许多不同的解决方案,但没有一个会更新我的用户字段。我没有添加任何自定义字段。 最佳答案 如果您想允许额外的参数,您可以在ApplicationController中使用beforefilter,因为Rails4将参数
目录前言滤波电路科普主要分类实际情况单位的概念常用评价参数函数型滤波器简单分析滤波电路构成低通滤波器RC低通滤波器RL低通滤波器高通滤波器RC高通滤波器RL高通滤波器部分摘自《LC滤波器设计与制作》,侵权删。前言最近需要学习放大电路和滤波电路,但是由于只在之前做音乐频谱分析仪的时候简单了解过一点点运放,所以也是相当从零开始学习了。滤波电路科普主要分类滤波器:主要是从不同频率的成分中提取出特定频率的信号。有源滤波器:由RC元件与运算放大器组成的滤波器。可滤除某一次或多次谐波,最普通易于采用的无源滤波器结构是将电感与电容串联,可对主要次谐波(3、5、7)构成低阻抗旁路。无源滤波器:无源滤波器,又称
项目介绍随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱小学生兴趣延时班预约小程序的设计与开发被用户普遍使用,为方便用户能够可以随时进行小学生兴趣延时班预约小程序的设计与开发的数据信息管理,特开发了小程序的设计与开发的管理系统。小学生兴趣延时班预约小程序的设计与开发的开发利用现有的成熟技术参考,以源代码为模板,分析功能调整与小学生兴趣延时班预约小程序的设计与开发的实际需求相结合,讨论了小学生兴趣延时班预约小程序的设计与开发的使用。开发环境开发说明:前端使用微信微信小程序开发工具:后端使用ssm:VU
我在我的项目中有一个用户和一个管理员角色。我使用Devise创建了身份验证。在我的管理员角色中,我没有任何确认。在我的用户模型中,我有以下内容:devise:database_authenticatable,:confirmable,:recoverable,:rememberable,:trackable,:validatable,:timeoutable,:registerable#Setupaccessible(orprotected)attributesforyourmodelattr_accessible:email,:username,:prename,:surname,:
我需要使用ActiveMerchant库在我们的一个Rails应用程序中设置支付解决方案。尽管这个问题非常主观,但人们对主要网关(BrainTree、Authorize.net等)的体验如何?它必须:处理定期付款。有能力记入个人帐户。能够取消付款。有办法存储用户的付款详细信息(例如Authotize.netsCIM)。干杯 最佳答案 ActiveMerchant很棒,但在过去一年左右的时间里,我在使用它时发现了一些问题。首先,虽然某些网关可能会得到“支持”——但并非所有功能都包含在内。查看功能矩阵以确保完全支持您选择的网关-http
我正在尝试创建密码规则来设计可恢复的密码更改。我通过passwords_controller.rb做了一个父类(superclass),但我需要在应用规则之前检查用户角色,但我所拥有的只是reset_password_token。 最佳答案 假设您的模型是用户:User.with_reset_password_token(your_token_here)Source 关于ruby-on-rails-设计通过reset_password_token获取用户,我们在StackOverflow
我已经使用Apartment设置了一个Rails5应用程序(1.2.0)和Devise(4.2.0)。由于某些DDNS问题,应用只能在app.myapp.com下访问(请注意子域app)。myapp.com重定向到app.myapp.com。我的用例是每个注册该应用的用户(租户)都应该通过他们的子域(例如tenant.myapp.com)访问他们的特定数据。用户不应限定在其子域内。基本上应该可以从任何子域登录。重定向到租户的正确子域由ApplicationController处理。根据Devise标准,登录页面位于app.myapp.com/users/sign_in。这就是问题开始的
我在关注RyanbatesRailsCast的devise和omniauth(第235集-devise-and-omniauth-revised)。当我尝试使用Twitter登录时,标题中不断出现错误。defself.new_with_session(params,session)ifsession["devise.user_attributes"]new(session["devise.user_attributes"],without_protection:true)do|user|user.attributes=paramsuser.valid?end完整跟踪:C:/Ruby20
我为Devise用户和管理员提供了不同的模型。我也在使用Basecamp风格的子域。除了我需要能够以用户或管理员身份进行身份验证的一些Controller和操作外,一切都运行良好。目前我有authenticate_user!在我的application_controller.rb中设置,对于那些只有管理员才能访问的Controller和操作,我使用skip_before_filter跳过它。不幸的是,我不能简单地指定每个Controller的身份验证要求,因为我仍然需要一些Controller和操作才能被用户或管理员访问。我尝试了一些方法都无济于事。看来,如果我移动authentica