松果健康问诊开放接入设计方案

背景

如果松果对每个合作方都单独去做接入适配,那么工作量一定很大,最后适配服务也一定非常杂乱或庞大,所以我们还是希望平台侧能出接入规范,统一交互流程,让各个个合作方自行接入,我们只需要很少的人力来支持合作方接入时的调试。

目前松果已经适配了好大夫的定向问诊和义诊,微医的非定向问诊和义诊,这两个合作方都是在线医疗行业比较头部的流量,其系统设考虑比较完备,也经受过考验,是比较稳定的;因此我们的设计和接入规范将参考这两家的接口文档和交互流程来制定。

主要模块

Generated

资源隔离

合作方资源隔离

目前线上已接入好大夫和微医,我们使用了共享数据库,共享数据表的资源隔离方式,隔离度算是很低的,我们只能通过partnerId来区分各个合作方的资源。但是这个做对资源的浪费是最低的,但是在技术上复杂度比较高。考虑到目前好大夫和微医已稳定在目前的系统中运行,初步计划开放平台也基于这样的资源隔离方式来做。

测试/线上资源隔离

开放接口给第三方接入,那需要给第三方提供测试环境和线上环境,并保证两套资源完全隔离。目前觉得比较合适的方案:所有存储或mq都新建test实例,服务独立部署open-test集群。为了区分测试和线上环境,入口也需要区分,需要小程序单独开发一个测试环境白名单的功能。

测试、预览环境

首先接入方没法在外网使用松果的灰度环境的,所以开放给接入方的测试和预览环境都部署在松果线上,只是资源是完全隔离的。接入方调试过程中,如果发现测试环境有问题,松果侧的修复流程应是:灰度上开发自测ok,然后上到线上的测试环境(open-test)和开放预览环境(ppe),最后三方或自己测试、预览通过后再合入master上到线上环境。

测试环境

测试环境在我们线上表现出来是独立发布的测试集群。各个接入方公用一个测试集群,如果多个接入方同时提出变更,我们就串行提交合入(现在估计这种情况很少,毕竟接入方就那么几家)

Generated

测试环境数据流

用户命中测试环境白名单后,所有请求都是使用测试域名调用,松果侧对所有测试域名在tlb上都将流量转到测试集群,松果侧adaptation测试集群请求到接入方的哪个环境由接入方自己配置,ms上配置所有test集群的流量都知道test集群。

支付的流程:test集群支付直接设置为已支付;测试用户小程序不发起真正支付请求支付流程由松果保证,接入方不需要关心。

待解决

Q:这里sungofaas函数没有测试环境部署的概念,部署都是他们平台做的,所有只能新增一个sungofaas测试函数来消费测试Mq(维护麻烦)

A:接入事件中心

预览环境

测试环境测试ok后,如果有变更先上线到预览环境。

预览环境直接走ppe环境,各个接入方单公用一个开放预览环境。api接入层发现ppe订单后需要记下来,callback收到回调,需要查是否是ppe订单,如果是ppe的订单就将回调请求重定向到ppe环境(再header加上ppe环境的env)。

待解决

Q:sungofaas不支持mesh,不支持路由到下游的ppe环境,34双月支持(已支持rpc的出流量)

Q:sungofaas不支持ppe部署和消费,需要新建topic。(测试环境,已新建了topic,这里再建一个有维护起来很麻烦)

解决办法:

放弃sungofaas?使用eventbus(EventBus可以一个handler中消费来自不同topic的消息,ppe泳道 )

A:事件中心 主端事件中心文档索引 (支持ppe,做了一些通用业务处理)

开放配置平台

松果健康会调用第三方的接口,各个接入方的域名都不相同,因此需要提供统一平台给接入方配置一些独有的参数。初步看需要的功能有:

接入方openApi接口线上域名配置;接入方openApi接口测试域名配置;

接入方ppe环境白名单配置;

test用户白名单。

后台管理平台

各个合作方的接入管理直接在mis平台上做。主要功能有:

各个接入就app_key和secret_key的生成和查看,以及secret_key的更新。

各个接入方分诊流量的配置。

各个接入方的订单状态监控。

各个接入方的订单评价和医生信息等查询。

分流策略

对于非定向问诊,需要提供分流策略,尽量选择能及时响应的合作方创建订单。松果维护各个合作方当前订单的积压量、实际平均接单时间。我们会根据当前各个合作方订单积压量来决定订单分诊给谁,如果积压量都相同,就根据平均接单时间来派发。

由于大部分时间积压量都是0,所以关键在于平均接单时间,而某个合作方的平均接单时间一定是最快的,这样大部分情况下订单都会走到这个合作方去,其他合作方很难分到订单,因此我们还会加一个参数:各个合作方最低接单比例,该参数由pm配置。在积压量相同时,我们会参考前24小时的订单量,在设置过最低接单比例的合作方达到最低接诊比例前,我们会随机给这些合作方派发订单,在达到最低接诊比例后,就开始按照平均接单时间来派发订单。

这里松果需要合作提供查询订单积压状态,松果会定期拉取最新的状态。

交互时序图

Generated

业务展示状态流转

Generated

红色是异常状态,需要报警并人工介入(不会展示给前端)

绿色是订单最终的正常状态

黄色是订单中间状态

分账状态不展示给前端

创建订单

先在松果侧创建订单,此时订单是“未支付”状态。松果侧在创建订单时会先去第三方创建患者信息。

未支付

用户支付成功后,订单变为“已支付待服务”状态。

如果用户不支付,或者一直不能成功支付,30分钟后松果会将该订单取消,订单变为“已取消”状态。

已支付待服务

支付后松果才会去第三方发起订单创建请求,如果创建失败会向财经发起退款并将订单设置为“拒绝服务退款中”状态;如果是超时失败会进行异步重试。

在第三方创建订单成功后,松果会给第三方同步订单已支付,如果同步失败(订单价格不对等),会发起取消订单,第三方应同步返回成功或失败,松果收到订单已结束回调后将订单设置为“拒绝服务退款中”状态,并向财经发起退款请求;如果订单同步或取消订单请求超时失败会进行异步重试。

创建订单并支付同步成功后,医生在指定时间内接单,第三方会发起订单已开始的回调,松果收到订单开始回调后会将该订单设置为“服务中”的状态。

对于定向问诊,医生收到该订单后发现订单不是自己擅长范围,在开始服务前可以拒绝订单,此时需要第三方返回订单结束和订单已退款的回调,松果收到这两回调后会将订单设置为“拒绝服务退款中”状态,并向财经发起退款请求。

超时仍没有医生接单(非定向2小时,定向无),松果会主动发起订单取消,此时第三方应该响应订单取消,并返回订单已退款的回调,松果收到回调后会将订单设置为“拒绝服务退款中”状态,并向财经发起退款请求。如果同一时间第三方医生刚好接单了,订单会变成“服务中”的状态。

医生接单前用户还可以主动发起取消订单,松果会主动发起订单取消,此时第三方应该同步响应订单取消,松果收到响应后将订单设置为“退款审核中‘”状态。

拒绝服务退款中

松果收到财经退款成功回调后,会将订单设置为“已拒绝已退款”状态

如果超过一定时间松果仍没有收到退款成功的回调,松果会主动查单,发现退款还是没有成功,进行报警人工处理。

服务中

医患正常交流消耗完所有时间或者次数、或者医患沟通后同意医生关闭订单,第三方应发起订单已结束的回调,松果将订单设置为“正常结束”状态。

订单服务中,医生发现相关问题不是自己专业领域可以取消订单,第三方应发起订单已结束和订单已退款的回调,松果收到这两回调后会将订单设置为“拒绝服务退款中”,并向财经请求退款。

退款审核中'

服务开始前,用户取消订单的退款审核中,并没有真正的审核,只是等待第三方订单已结束和已退款的回调,松果收到这两回调后会订单设置为“审核通过退款中”的状态,并向财经发起退款请求。

如果同一时间第三方医生刚好接单了,订单会变成“服务中”的状态。

退款审核中

松果收到第三方客诉结束回调和订单已退款的回调后会将订单设置为“审核通过退款中”,并向财经发起退款请求。

如果松果只收到客诉已结束回调,并且不同意退款,松果将订单设置为“退款被驳回”状态。

审核通过退款中

松果收到财经退款后,会将订单设置为“退款完成”状态。

如果超过一定时间松果仍没有收到退款成功的回调,松果会主动查单,发现退款还是没有成功,进行报警人工处理。

服务结束

服务接受后用户可以发起客诉并申请退款,松果在客诉发送成功后会将订单设置为“退款审核中”的状态。

服务正常结束14天后,松果会自动触发分账,分账成功后会同步给第三方,如果同步失败需要告警并人工介入处理。分账后还提供查询订单接口,方便第三方对账。

服务分账后用户不可再发起客诉。

订单状态流转

Generated

订单初始化

订单创建后, 订单状态是“初始化”状态,支付状态是“未支付”。

订单超过30分钟未支付,松果会直接取消订单。如果用户刚好在30分钟支付了,那么后续支付成功后也会直接发起退款。测试订单进入“已取消”状态

支付状态变为“已支付”后:

松果会去第三方创建订单,并同步给第三方订单已支付。如果创建订单失败,订单进入“拒绝服务”装填,并发起退款。如果同步支付失败,订单也进入进入“拒绝服务”状态,并发起退款。

医生接单前,用户主动取消订单,松果会向第三方请求取消订单,如果第三方同步返回取消成功,订单进入“用户退单审核中”状态;等到第三方返回同意退款时,订单进入“用户退单审核通过”的状态,并发起退款。这里用户取消时,可能刚好被医生接单,订单会进入“服务中”的状态

如果订单被第三方分诊平台拒绝,或者医生接到分诊订单后拒绝接单,松果订单进入“拒绝服务”状态,并发起退款。

收到订单开始回调,进入“服务中”状态

服务中

收到订单结束回调,订单接入“服务结束”状态

服务中理论上用户也可以发起客诉退款,订单进入“退款审核”中。(目前没有这个逻辑)

服务结束

用户可以发起客诉退款,订单进入“退款审核”中。退款审核通过,订单进入“退款审核通过”状态,并发起退款;退款审核不通过,订单进入“退款审核被拒绝”状态。

14天后,支付状态进入“分账”。

详细设计

订单

参考:医疗问诊项目订单模块技术方案 医疗订单状态流转优化

医生信息

参考:松果问诊-医院医生信息

会话

参考:松果问诊-会话管理

评价

参考:松果问诊-评价

异步流程

该流程主要涉及三方回调、异步重试任务、定时任务等,在各个模块中有自己的详细涉及,这里主要讨论各个模块处理异步流程的共同点。

当前所有异步流程都是将任务信息推入mq(rocketmq/kafka),然后在sungofaas上单独使用函数消费,但是有两个问题:

sungofaas暂时不支持mesh,不能路由ppe流量

sungofaas也没有ppe环境,不能单独消费ppe环境生产的消息

所以我们计划所有异步流程都切入到事件中心(事件中心接入文档-V1 ),目前事件中心已经能很好支持解决上面两个问题。我们与事件中心的交互都是rpc调用,相比较于sungofaas每类消息一个函数(函数太多维护累),我们的rpc接口能更好收敛到已有服务中,维护起来更方便。

合作方管理

问诊开放接入-合作方标识


人生有無數種可能,人生有無限的精彩,人生沒有盡頭。一個人只要足夠的愛自己,尊重自己內心的聲音,就算是真正的活著。