关于支付:由某披萨品牌的联动事故聊聊支付流程的设计以及区块链解决方案

最近某披萨品牌与出名游戏的联动再次冲上热搜,只不过起因是许多用户在领取过程中遇到问题,呈现长时间无奈领取,反复领取等异常情况。本文想要从个别的秒杀及领取零碎的设计方面探讨一下故障呈现的可能起因,以及预防计划,最初聊一聊区块链在这方面的解决方案。因为作者并不理解本次故障具体的技术细节,所以文中可能蕴含大量的主观揣测,还请读者见谅。 流程复盘流动开始当日上午9点,披萨APP上开启流动产品的预约,不久,产品就已售罄。同时,社交网络上开始呈现“披萨APP解体“的用户反馈。次要反馈的问题有: 订单曾经领取,然而显示领取未实现一份订单领取胜利两次订单无奈领取(提醒网络异样)在大量用户反馈问题之后,披萨品牌示意会将订单的可领取工夫由半小时缩短到24小时。 问题剖析本次流动的次要步骤能够合成为:1. 创立订单;2.领取订单。 在创立订单这一步是没有呈现用户反馈问题的,只管同时抢购的用户数量很多,然而个别只须要正当地将用户进行分区,例如,假如产品限量10万份,能够创立10个并行的服务,每个服务上搁置事后生成的1万份产品编码,咱们这里用 token 来示意。而后应用哈希将用户分流到这10个服务上。每个服务就只须要保护1万 token 的汇合。 次要问题是在领取订单这一步,首先,只有取得 token 的用户才有资格进行领取。那么当服务器拿到用户发来的 token 的时候,须要做以下工作:1. 验证此token是否是实在的;2. 验证此token是否过期;3. 验证此token是否被应用过。 第一步是比较简单的,能够应用数字签名技术来验证,比方每个 token 都是有商家私钥签名的。第二步也很简略,token内的工夫戳和以后的工夫比照一下,就晓得有没有过期。真正简单的是第三步,咱们方才提到了,总共有 10 万份产品,那么至多就有 10 万个 token,且它们始终在更新(每时每刻都有订单领取胜利,领取胜利,token 生效)。这意味着这一步是无奈并行的,一旦并行,就有可能呈现双花 ———— 一个 token 被应用两次。 这一步里极大的串行工作的沉积,有可能是导致服务解体的次要起因。 另外,有用户示意同一笔订单领取了两次,这是因为大多数用户应用的是第三方领取服务,在“领取胜利->token生效“这个过程中,如果两头断开了,就可能导致领取两次。 解决方案首先咱们探讨一下在业务层面的解决方案,能够采纳预付订金的机制,比方,在流动开始前的一周里,用户能够预付订金参加抽签,流动开始当日颁布抽签后果,未中签的用户主动退还订金。将领取的工作分散开来。 如果不想扭转业务逻辑,咱们还能够在 token 上做文章,比方,将全副 token 分为 n 组,并在 token 上标注分组编号;同时启用 n 个验证服务,每个服务只负责保护对应分组的 token 汇合,相当于把串行工作分为了 n 个并行任务。 区块链的利用依据白皮书 "A Peer-to-Peer Electronic Cash System" 实现的区块链零碎实践上是能够有限扩容的,并且由其特有的工作量证实(POW)机制,可能超过分布式系统不可能三角(CAP),无效解决领取过程中的双花问题。 这里咱们尝试设计一个使用区块链零碎的解决方案。首先,商家发行10万个 token,每个 token 是一个 UTXO(未破费输入),其中蕴含的金额能够是 1 聪(区块链上最小的金额单位)。 另外,咱们须要第三方领取也反对这一区块链零碎,例如当初的数字人民币零碎。 在用户取得了 token,进行领取的时候,用户将发动一笔区块链交易,这笔交易的会耗费 token,并向商家领取对应的金额。当商家从区块链的“交易解决商”(俗称矿工)那里理解到这笔交易曾经有极大概率胜利 ———— 这个过程只实践上不到1秒钟,理论取决于区块链零碎中矿工的网络情况 ———— 就能够认为这个token曾经生效,且领取已胜利,这是一个原子操作。 ...

March 1, 2023 · 1 min · jiezi

关于支付:聊聊支付流程的设计与实现逻辑

老手打怵新手头疼的业务;一、业务背景通常在业务体系中,都会或多或少的波及到领取相干的性能;对于一些教训欠缺同学来说,最缓和的就是面对这类领取结算的逻辑,因为流程中的任何细节问题,都可能引发对账异样的状况; 谬误产生之后,再想去修复流程,破费的工夫老本又是昂扬的,还牵扯谬误数据的调平问题,最终很可能引发乱账算不清的后果,而后须要人工染指手动解决; 在领取场景中,岂但波及诸多的简单业务,结算规定,超长的流程,第三方对接,其中更是波及到诸多技术细节,比方:事务管理、异步解决、重试机制、加锁等;上面来剖析具体的细节逻辑。 二、领取业务1、流程拆解面对简单业务的时候,最根本的能力就是要懂得把流程拆成模块,做好各个模块治理,再思考如何连接起整个流程,从而造成解决问题的思路和教训; 如图是对交易场景常见的合成,大抵能够分为四个模块: 账面治理:对于开明领取性能的用户,必须清晰的治理资金信息;比方可用,解冻,账单等;交易流水:整个资金治理的流水记录,不局限于交易场景,还有充值,提现,退款等;领取对接:通常流程中的领取性能都是对接第三方领取平台来实现的,所以要做好申请和报文的记录;订单构造:比方在电商交易中,订单模型的治理,拆单策略等,领取的商品规格等;这里只是从一个惯例的交易流程中去剖析,理论的细节形容会远比图例简单,尽管业务细节各不相同,然而解决思路是大体相通的;再依据各个模块设计流程时序图,布局好节点之间的连接和合作; 2、流程时序通过时序图的设计,来剖析各个节点在连接合作时应该如何解决,在领取业务中,通常分为领取前、领取对接、领取后三个外围阶段: 领取前:在商品下单时,构建订单模型,依据拆单规定校验库存、商品状态等,而后进行账户资金解冻,生成交易流水,此时的状态都是待领取;领取对接:领取前业务模型初始化胜利之后,构建第三方领取对接申请,发动付款流程,并记录相应的申请动作和参数,期待领取后果的告诉;领取后:依据领取后果的胜利与否,执行相应的业务模型状态更新,如果领取胜利则交易记录、解冻的资金、订单构造与库存等都须要做一系列更新;实际上对业务有清晰的了解和拆分之后,再做好时序流程的设计,这样就曾经让一个简单的场景看起来简略许多了,之后就是设计各个节点的数据结构; 3、结构设计基于下面的业务场景剖析和拆解,以及流程时序图的出现,能够很容易输入一份根底维度的结构设计,下图能够作为参考: 账面治理:三个外围维度,账户金额,可用余额,解冻金额;交易记录:存储用户的交易动作,然而可能会产生多个交易明细,典型的场景就是购物车下单;交易明细:通常因为订单拆分,从而导致交易被拆分多条明细,进而将资金领取给不同商家;领取对接:申请第三方领取平台时,须要记录申请时参数,以及第三方回调告诉的报文;订单记录:在一笔订单中可能存在多个拆分的子单,拆分策略也很多,比方仓库,商家,品类等;订单明细:治理每笔子订单的信息,下单的商品、规格、买卖双方、单价、数量、金额等;即便单看下面的简略设计,都能感觉到领取业务的复杂性,更何况还会叠加红包或满减等优惠规定之后,其复杂程度可想而知; 当然如果有明确的开发标准,在简单版本中,所有开发必须输入业务的合成拆分思路,时序和结构设计,在对立评审之后再落地编码,这样即使是简单的业务也会有极大的质量保证。 三、关联业务下面单从领取的主逻辑去剖析流程,实际上波及到的业务远不止流程中提到的这些,以常见的电商场景为例,交易中还存在商品治理、库存治理、物流治理,领取对接还会波及优惠规定嵌入等等; 商品治理 商品主体:保护商品各个维度的信息,并提供各种规格选项,以及根底的定价阶梯,构建商品详情形容;仓储治理:订单拆单之后,须要依据商品编号去校验仓储信息,进行相应的库存解冻以及领取后的仓库发货;优惠券规定 优惠券主体:为了适配更多的业务场景,须要对优惠规定有诸多的设计,比方满减或折扣比例、按价格阶梯优惠、有效期限度等;发放规定:撑持日常的经营流动,用户生命周期的保护,以及渠道流量的转化,提供用户群营销的根底能力;这里简述的商品和优惠券业务,都是与领取流程有严密的分割,比方拆单后库存有余,须要移除该商品;优惠券在领取中的应用策略,以及退款时的解决形式等; 四、实际总结最初从技术实现的角度,总结一下领取流程中的一些关键问题: 业务模型:对业务有清晰的了解,并能拆分出外围的节点,设计出相应的流程时序和数据结构;事务管理:交易流程中罕用TCC事务机制,即Try(预处理)、Confirm(确认)、Cancel(勾销)模式;加锁与重试:领取实现后收回领取胜利的音讯,而后进行业务更新,通常须要对解决的订单号加锁,防止音讯重试机制引发数据问题;资金结算:波及金额的计算,天然要求不能呈现精度损失的问题,在一次交易中必须保障每笔资金能够通过对账核验;流程保护:流程自身是很难保障不呈现谬误的,须要在开发的时候,提供流程的可视化界面,并且反对手动保护的机制;很多简单的业务场景治理,都须要一个长期的迭代过程,然而前提须要牢牢把握住外围的逻辑;对业务的认知是一个由繁入简的过程,而业务的实现是一个由浅到深的过程,即剖析与了解,到落地实现,再到摸索与翻新。 五、参考源码编程文档:https://gitee.com/cicadasmile/butte-java-note利用仓库:https://gitee.com/cicadasmile/butte-flyer-parent

July 3, 2022 · 1 min · jiezi

关于支付:风带来的消息-狂人日记

老王经营着一家蹄花店,凌晨,像平常一样,老王关上店门 “老板,来一碗蹄花” 老王抬起头,空空的街道上一个人也没有,只有远处的小区保安在打盹 肯定是我听错了,最近压力好大,头发都掉了不少,得好好劳动了 “老板,听到没有啊,一碗蹄花” 老王暴怒,一拳打在桌子上,筷子哗啦啦散了一地 “别躲在角落里,要买货色你给我进去!” 无人回应,大风吹起,一张白纸飘到老王背后 商品:蹄花 x1客户: 二狗老王又怒,“先付钱!”,抄起一支笔在纸下边写上 价格:40元完了把纸一揉,使劲丢了进来,纸团随着风滚走了。一会儿,又滚了回来,老王捡起来关上一看,外面夹了两张 20 元纸币 “老板,快点儿吧,我快饿死了” 老王一点不焦急,拿起纸币举起来细看,嗯,有水印,是真的 起初,据说老王把门店大半改成了厨房,分心做外卖,登上了2019年外卖必吃榜

May 11, 2022 · 1 min · jiezi

关于支付:多国政府严厉打击勒索软件支付渠道以色列医院遭受重大勒索攻击|10月18日全球网络安全热点

平安资讯报告世界各国政府严厉打击勒索软件领取渠道来自30多个国家的高级官员示意,他们的政府将采取行动毁坏为勒索软件提供资金的非法加密货币领取渠道。 该联合声明是在白宫国家平安委员会本周促成的虚构反勒索软件倡导会议之后公布的,以应答继续的攻打,这些攻打揭示了寰球要害基础设施的重大破绽。 打击勒索软件个人滥用加密货币的致力将包含监管机构、金融情报部门和执法部门,对虚构资产的利用进行监管、监督、考察和采取行动。 “咱们还将寻求与虚构资产行业单干的形式,以增强与勒索软件相干的信息共享,”官员补充道。这一口头背地的国家将利用其金融机构和基础设施,独特抵挡针对国内合作伙伴要害基础设施的勒索软件流动。补充性致力还将包含通过执法单干毁坏勒索软件生态系统、进步网络弹性以避免攻打、解决勒索软件犯罪分子的避风港问题,以及通过内政接触激励其余国家应答在其领土内沉闷的勒索软件流动。 新闻来源: https://www.bleepingcomputer.... 钻研人员称要害基础设施安全性“糟糕透顶”新的钻研发现,工业控制系统(ICS)的“极差”平安状态正在将要害服务置于重大危险之中。 查看往年针对ColonialPipeline发动的勒索软件攻打造成的凌乱——导致美国局部地区的恐慌性购买和燃料短缺——即可理解事实世界中的网络中断事件可能引发什么,及其结果能够远远超出一家公司必须修复的侵害。 周五,CloudSEK的Sparsh Kulshrestha公布了一份新报告,依据最近针对工业、公用事业和制作指标的网络攻击,摸索ICS及其平安态势。该钻研侧重于可通过互联网取得的ICS。 “尽管攻击者领有丰盛的工具、工夫和资源,但其余威逼行为者次要依附互联网来抉择指标并辨认他们的破绽,”该团队指出。“尽管大多数ICS都有肯定水平的网络安全措施,但人为谬误是导致威逼行为者依然可能一次又一次地毁坏它们的次要起因之一。” 报告中援用的一些容许初始拜访的最常见问题,包含默认凭据、易受破绽利用的过期或未打补丁的软件、第三方导致的凭据透露、影子IT和源代码透露等。 新闻来源: https://www.zdnet.com/article... 安全漏洞威逼以色列医院成为勒索软件攻打的指标官员们示意,以色列一家医院周三受到勒索软件攻打,该州网络局称这是该国第一次针对医院的此类攻打。HillelYaffe医疗核心“目前正在应用代替零碎来医治患者”,它在一份申明中示意,称这次袭击“齐全出其不意”。 “除了非紧急的选择性手术外,医疗照常持续,”希勒尔·亚菲说。 以色列国家网络局局长YigalUnna称这是一次“重大”攻打。 “咱们正在致力解决它,看起来不太好,”他在美国国家平安委员会主办的勒索软件攻打虚构峰会上说。 依据Unna的说法,勒索软件网络攻击针对医院是“以色列第一次”,只管其余国家的医疗核心也经验过相似的攻打。 他的机构示意,“卫生部已更新医院作为预防措施”。 依据Unna7月份提供的数据,以色列五分之一的企业成为网络攻击的指标,这些攻打对五分之一的被攻打企业造成了侵害。 新闻来源: https://www.securityweek.com/... 勒索软件攻打了美国3个供水设施的SCADA零碎美国政府机构周四公布警报,正告水和废水行业的组织无关正在进行的网络攻击。该警报还形容了三个以前未报告的勒索软件攻打,这些攻打影响了供水设施的工业控制系统(ICS)。该警报由FBI、CISA、EPA和NSA公布。 新警报突出了与数据、勒索软件、网络分段、网络复杂性和系统维护相干的危险,并分享了无关威逼行为者用来毁坏IT和OT零碎和网络的策略、技术和程序(TTP)的信息。它还提供无关组织如何预防、检测和响应网络威逼的倡议。 该警报还提供了过来几年由歹意内部人员和内部威逼参与者进行的攻打的几个示例。这些例子包含往年产生的三起事件,之前没有公开。在每一次攻打中,监控和数据采集(SCADA)零碎都受到了影响。 在3月份产生的一起事件中,网络犯罪分子应用未知勒索软件攻打内华达州的一个供水设施。 另一起事件产生在7月,指标是缅因州的一家工厂。黑客部署了ZuCaNo勒索软件,该软件已进入废水SCADA计算机。 第三次新披露的攻打产生在8月。威逼行为者在加利福尼亚州一家水厂的零碎上部署了一种名为Ghost的勒索软件。 平安警报还形容了2019年和2020年产生的两起已知事件,其中一起波及往年早些时候被指控的内部人员。 据政府称,有超过150,000个公共供水系统为数百万美国人提供饮用水,废水处理设施解决大概340亿加仑的废水。美国将供水和废水零碎归类为国家要害性能,它们的毁坏或糜烂将“对平安、国家经济平安、国家公共衰弱或平安,或其任何组合产生减弱作用”。 新闻来源: https://www.securityweek.com/...

October 18, 2021 · 1 min · jiezi

关于支付:简单易用且优雅的跨境支付-PHP-SDK-扩展包

GlobalPay反对国际版领取的 PHP SDK,目前只反对支付宝国际版。因目前支付宝跨境在线领取服务只反对 app、wap、web 和报关这四种,本 SDK 提供了 app、wap、web 这三种跨境领取,详见国内支付宝官网文档 。 装置composer require pudongping/global-pay -vvv特点命名标准暗藏开发者不须要关注的细枝末节合乎 PSR 标准,能够不便的与各种 PHP 框架集成有良好的文档,蕴含各种示例办法以及官网返回后果。文档地址 : https://pudongping.github.io/...运行环境PHP >= 7.1.3Composer反对的领取办法支付宝电脑领取手机网站领取APP 领取method形容web电脑领取wap手机网站领取appAPP 领取反对的办法所有网关均反对以下办法find(array|string $order) 阐明: 查找订单接口 参数: $order 为 string 类型时,请传入零碎订单号,对应跨境支付宝中的 out_trade_no 参数; array 类型时,参数请参考支付宝境外订单单笔查问文档 。 返回: 查问胜利,返回 Illuminate\Support\Collection 实例,能够通过 $collection->toArray() 或者 $collection->all() 或者 $collection->get('field') 拜访服务器返回的数据。refund(array $order) 阐明: 退款接口 参数: $order 数组格局,退款参数请参考支付宝境外退款接口文档 。 返回: 退款胜利,返回 Illuminate\Support\Collection 实例,能够通过 $collection->toArray() 或者 $collection->all() 或者 $collection->get('field') 拜访服务器返回的数据。verify() 阐明: 验证服务器返回数据是否非法 返回: 验证胜利,返回 Illuminate\Support\Collection 实例,能够通过 $collection->toArray() 或者 $collection->all() 或者 $collection->get('field') 拜访服务器返回的数据。其余通用办法getExchangeRate() 阐明: 获取汇率。详见支付宝境外汇率查问接口 。 返回: 获取胜利,返回 Illuminate\Support\Collection 实例,能够通过 $collection->toArray() 或者 $collection->all() 或者 $collection->get('field') 拜访服务器返回的数据。 留神: 1、货币间的汇率会在北京工夫每日 9:00 到 11:00 间变动一次; 2、汇率每日获取下限为 100 次。 (可能须要思考通过缓存保留汇率,避免接口出现异常,因为本 SDK 没有做缓存解决)getHbFqCost(float $totalAmount, bool $isShowAll = false, bool $isSellerPercent = false) 阐明: 获取花呗分期计费状况 参数: $totalAmount 为分期的本金,$isShowAll 为是否显示每一期的还款数,$isSellerPercent 为 true 示意商家承当全副手续费,为 false 示意用户承当全副手续费。 返回: 获取胜利,返回 Illuminate\Support\Collection 实例,能够通过 $collection->toArray() 或者 $collection->all() 或者 $collection->get('field') 拜访服务器返回的数据。返回参数阐明 ...

October 10, 2021 · 6 min · jiezi

关于支付:关于聚合支付方案支付策略模式

公司最近在做聚合领取的性能,原来领取计划是不同的领取商户不同的业务解决,扩展性极差,且每新增一个业务商户都要独自开发一套领取接口,很显著这违反了OOP的思维。策略模式的组成部分有三局部 环境类(Context):用一个ConcreteStrategy对象来配置。保护一个对Strategy对象的援用。可定义一个接口来让Strategy拜访它的数据。形象策略类(Strategy):定义所有反对的算法的公共接口。 Context应用这个接口来调用某ConcreteStrategy定义的算法。 具体策略类(ConcreteStrategy):以Strategy接口实现某具体算法。领取形式的组成也有三局部 领取策略接口(PayStrategy):定义领取形式 具体领取形式(H5PayStrategy、WxPayStrategy、依据本人的):具体的领取算法 领取策略上下文(PayStrategyContent):治理所有领取形式的援用,并依据用户抉择援用对应的领取形式。代码实现(本案例是接的银联领取)   领取策略接口(PayStrategy) /***@program:traffic-resource*@description领取策略接口*@author:belive*@create:2020-12-2521:06**/publicinterfacePayStrategy{/***领取接口*1.小程序领取*2.h5领取*3.扫码领取*4.app领取**@param param*@returnStringjson字符串*/RestRes<String>consumeApply(Stringparam);/***查问领取后果接口*1.小程序领取*2.h5领取*3.扫码领取*4.app领取**@param param*@returnStringjson字符串*/RestRes<String>consumeApplyDetail(Stringparam);/***退款接口*1.小程序领取*2.h5领取*3.扫码领取*4.app领取**@param param*@returnStringjson字符串*/RestRes<String>refund(Stringparam);/***查问退款后果接口*1.小程序领取*2.h5领取*3.扫码领取*4.app领取**@param param*@returnStringjson字符串*/RestRes<String>refundQuery(Stringparam);/***敞开订单接口*1.小程序领取*2.h5领取*3.扫码领取*4.app领取**@param param*@returnStringjson字符串*/RestRes<String>depositApply(Stringparam);具体领取形式(MiniPayStrategy) 本案例就以扫码领取为例 /***@program:traffic-resource*@description*@author:belive*@create:2020-12-2521:18**/@Slf4j@ServicepublicclassQrCodePayStrategyimplementsPayStrategy{@Value("${unionPay.url.qrcode_get_qrcode}")privateStringqrcode_get_qrcode;@OverridepublicRestRes<String>consumeApply(Stringbody){RestRes<String>restRes=newRestRes<>();TransactionHttptransactionHttp=newTransactionHttp();Stringresult=transactionHttp.send("https://api-mop.chinaums.com/v1/netpay/bills/get-qrcode",body);JSONObjectresultObj=JSON.parseObject(result);if("SUCCESS".equals(resultObj.getString("errCode"))){restRes.setMessage("获取领取链接胜利");restRes.setCode(0);}else{restRes.setMessage("获取领取链接失败");restRes.setCode(1000);}restRes.setData(result);Return restRes;}@OverridepublicRestRes<String>consumeApplyDetail(Stringparam){Return null;}@OverridepublicRestRes<String>refund(Stringparam){Return null;}@OverridepublicRestRes<String>refundQuery(Stringparam){Return null;}@OverridepublicRestRes<String>depositApply(Stringparam){Return null;}}领取策略上下文(PayStrategyContent) /***@program:traffic-resource*@description领取策略上下文*@author:belive*@create:2020-12-2521:19**/@ComponentpublicclassPayStrategyContent{/**策略实例汇合*/ privateConcurrentHashMap<String,PayStrategy>strategyMap=newConcurrentHashMap<>(20);/***注入策略实例*如果应用的是结构器注入,可能会有多个参数注入进来。**如果应用的是field反射注入**如果应用的是setter办法注入,那么你将不能将属性设置为final。**@paramstrategyMap*留神注入类型要是Map根底类型*/@AutowiredpublicPayStrategyContent(Map<String,PayStrategy>strategyMap){ //清空集合数据 this.strategyMap.clear(); if(!CollectionUtils.isEmpty(strategyMap)){ strategyMap.forEach((beanName,payStrategy)->{ if(StringUtils.isEmpty(beanName)||payStrategy==null){ return; } this.strategyMap.put(beanName.toLowerCase(),payStrategy); }); } }/***抉择领取形式*小程序、H5、扫码**@parampaymentEnums**@returnRemoteResult*/publicRestRes<String>consumeApply(PaymentEnumspaymentEnums,Stringparam){if(CollectionUtils.isEmpty(strategyMap)){thrownewApiException(ErrorCodeEnum.UNION05);}returnthis.strategyMap.get(paymentEnums.getBeanName()).consumeApply(param);}/***查问领取后果接口*1.小程序领取*2.h5领取*3.扫码领取*4.app领取**@parampaymentEnums**@returnRemoteResult*/publicRestRes<String>consumeApplyDetail(PaymentEnumspaymentEnums,Stringparam){if(CollectionUtils.isEmpty(strategyMap)){thrownewApiException(ErrorCodeEnum.UNION05);}returnthis.strategyMap.get(paymentEnums.getBeanName()).consumeApplyDetail(param);}/***退款接口*1.小程序领取*2.h5领取*3.扫码领取*4.app领取**@parampaymentEnums**@returnRemoteResult*/publicRestRes<String>refund(PaymentEnumspaymentEnums,Stringparam){if(CollectionUtils.isEmpty(strategyMap)){thrownewApiException(ErrorCodeEnum.UNION05);}returnthis.strategyMap.get(paymentEnums.getBeanName()).refund(param);}/***查问退款后果接口*1.小程序领取*2.h5领取*3.扫码领取*4.app领取**@parampaymentEnums**@returnRemoteResult*/publicRestRes<String>refundQuery(PaymentEnumspaymentEnums,Stringparam){if(CollectionUtils.isEmpty(strategyMap)){thrownewApiException(ErrorCodeEnum.UNION05);}returnthis.strategyMap.get(paymentEnums.getBeanName()).refundQuery(param);}/***敞开订单接口*1.小程序领取*2.h5领取*3.扫码领取*4.app领取**@parampaymentEnums**@returnRemoteResult*/publicRestRes<String>depositApply(PaymentEnumspaymentEnums,Stringparam){if(CollectionUtils.isEmpty(strategyMap)){thrownewApiException(ErrorCodeEnum.UNION05);}returnthis.strategyMap.get(paymentEnums.getBeanName()).depositApply(param);} 领取形式枚举(PaymentEnums) /***@program:traffic-resource*领取形式枚举对象*code->领取形式别名*beanName->实例的名称*@author:belive*@create:2020-12-2521:00**/publicenumPaymentEnums{/**领取形式*/H5_PAY("H5_PAY",H5PayStrategy.class.getSimpleName()),MINI_PAY("MINI_PAY",MiniPayStrategy.class.getSimpleName()),QR_CODE_PAY("QR_CODE_PAY",QrCodePayStrategy.class.getSimpleName()),;/***枚举定义+形容*/privateStringcode;privateStringbeanName;PaymentEnums(Stringcode,StringbeanName){this.code=code;this.beanName=StringUtils.isNotEmpty(beanName)?beanName.toLowerCase():null;}/***依据code获取对应的枚举对象*/publicstaticPaymentEnumsgetEnum(Stringcode){PaymentEnums[]values=PaymentEnums.values();if(null!=code&&values.length>0){for(PaymentEnumsvalue:values){if(value.code.equals(code)){returnvalue;}}}returnnull;}/***该code在枚举列表code属性是否存在*/publicstaticbooleancontainsCode(Stringcode){PaymentEnumsanEnum=getEnum(code);returnanEnum!=null;}/***判断code与枚举中的code是否雷同*/publicstaticbooleanequals(Stringcode,PaymentEnumscalendarSourceEnum){returncalendarSourceEnum.code.equals(code);}publicStringgetCode(){returncode;}publicStringgetBeanName(){returnbeanName;}}自定义Bean加载(PayStrategyContentConfig) /***@program: traffic-resource*@description*@author: belive*@create: 2020-12-3023:07**/@Configurationpublic class PayStrategyContentConfig {@Bean public PayStrategyContent payStrategyContentInit() { H5PayStrategy h5PayStrategy = new H5PayStrategy(); MiniPayStrategy miniPayStrategy = new MiniPayStrategy(); QrCodePayStrategy qrCodePayStrategy = new QrCodePayStrategy(); HashMap<String, PayStrategy> strategyMap = new HashMap<>(); strategyMap.put(PaymentEnums.H5_PAY.getBeanName(), h5PayStrategy); strategyMap.put(PaymentEnums.MINI_PAY.getBeanName(), miniPayStrategy); strategyMap.put(PaymentEnums.QR_CODE_PAY.getBeanName(), qrCodePayStrategy); PayStrategyContent payStrategyContent = new PayStrategyContent(strategyMap); return payStrategyContent; }} 领取相干业务调用(代码片段) ...

January 11, 2021 · 1 min · jiezi

关于支付:一笔订单但是误付了两笔钱这种重复付款异常到底该如何解决原创

封面送给我狗哥~ Hello,大家好,我是楼下小黑哥~ 明天的文章咱们接着上次的话题,持续聊聊领取零碎异样解决办法。 在上篇文章中「领取掉单异样解决方案」,咱们次要提到的是领取过程中掉单的场景,用户明明付款胜利,银行卡都扣款了,然而订单却还显示待付款。 而在明天的文章中,咱们将聊到反复付款的异样,即同一笔订单,扣了用户两笔钱。 另外咱们还将会提到另外一种异样,用户扣款胜利,然而订单却领取失败的场景。 以上两种异样对于被扣款的用户来讲,应用体验极差,本人多付了钱,订单却还不胜利。所以如果不及时处理这两类异样,那就真的等着被投诉吧。 欢送关注我的公众号:程序通事,取得日常干货推送。如果您对我的专题内容感兴趣,也能够关注我的博客:studyidea.cn反复付款异样异样场景反复付款异样个别常见于网银领取,微信领取,支付宝等这类须要跳转到一个领取网关页(网银领取),或者跳转到钱包 APP(支付宝、微信),从而异步实现扣款的领取场景。 这种领取场景下,只能通过承受异步告诉能力晓得领取后果,咱们个别将其称为异步领取。 PS:有了异步领取,那么同步领取是什么?其实同步领取指的就是调用领取接口之后,就能够立即返回领取后果的,比方银行卡类快捷/代扣等领取就是同步领取。 当然也有一些奇葩的银行卡领取渠道,同步领取后果为受理胜利,只能承受异步告诉或者查问返回领取后果。 因为银行卡领取须要返回明确领取后果,对于这类渠道只能外部设计将异步转为同步,感兴趣能够看下之前历史文章: 架构设计|异步申请如何同步解决? 后盾领取流程如下: 图片来自之前的文章:银行卡领取原理 为什么会产生反复付款?次要起因其实跟上次外部掉单异样一样,跟业务表设计无关。 上次咱们提到,领取零碎次要表构造如下: 在这个表构造下,只有领取订单未胜利,商户就能够重复使用其外部同一订单号调用领取接口。 假如这样一个场景,用户在收银台领取时抉择招行进行网银领取,当他点击领取之后,商户零碎将会调用领取公司的网银接口。 这时领取零碎外部将会创立一笔领取单以及关联的渠道订单,并且调用招行零碎的接口。 而后用户的浏览器页面将会关上一个新页面,而后跳转到招行网站。 这时如果此时用户再次在收银台点击领取,将会再次调用领取零碎接口。这时候因为领取单已存在,所以仅仅会再创立一条渠道订单记录,并且调用招行零碎的接口。这时用户的浏览器将会再次关上一个招行的网站。 如果用户在两个招行网银页都实现领取,这时就产生了反复付款。 下面这种场景看起来有点傻,然而实在用户操作真的会产生。除了这种,博客园上的小伙伴还提到这么上面这种状况: 解决办法反复付款异样的次要的解决办法有两种,分为事先与预先。 事先次要的目是尽可能避免用户反复付款,次要解决办法为优化付款页面,尽可能做好提醒。 第一种优化形式,付款页面间接跳转到第三方/银行的网银页面,不要关上新的页面去跳转。 这种形式能够避免用户误关上两个网银付款的页面,从而导致反复付款。 然而这里会有一个问题,银行网银页面付款胜利之后,用户如何晓得其在商户侧订单状态也胜利了? 其实很简略,当初网银领取接口,个别都会有一个参数 return_url:同步跳转地址 。 只有在接口传入这个地址,当领取胜利之后,页面最终就会跳转到这个传入的地址,商户侧就能够在地址显示订单是否领取胜利。 下面咱们提到,用户有可能会应用浏览器回退性能,跳转到领取页,从而导致反复付款。 对于这种状况,咱们能够在其回退领取页时,首先向后盾查问这笔订单领取后果,如果已领取胜利,那就间接显示胜利页面。 第二种优化,对于这种从新关上一个页面跳转到银行网站,咱们能够在页面退出弹窗提醒,询问用户是否已领取实现。 比方下面这种解决形式,当用户点击确认实现充值,能够马上向后盾发动查问订单状态。 上面来聊聊预先的解决办法,其实解决办法很简略,发动外部退款,将多余领取的一笔反向退款回去。 领取零碎外部能够有个定时工作,定时扫描领取单下有多条胜利渠道订单的记录,而后抉择将反复领取渠道订单发动退款。 这种形式是领取公司零碎外部的操作,不须要商户侧发动指令。 订单生效异样异样场景这种场景个别常见于电商购物,秒杀等购物场景。当用户下单之后,页面将会开始倒计时,用户须要在有效期内领取胜利。 假如用户点击跳转到支付宝,然而其没有立即领取,而是停留了很久,在订单最初一秒工夫内实现了领取,然而这个时候订单早已因为工夫到期而被主动勾销。 这样就产生用户扣款曾经胜利,然而订单却是失败或敞开的场景的。 另外还有一种状况,用户在有效期内领取胜利,然而因为网络、外部利用等问题,领取后果的异步告诉过了很久才收到,这时外部订单的早因为工夫到期而被勾销。 解决办法第一种解决办法,上送有效期给领取渠道。 个别领取接口都会有一个领取有效期的字段,表明这笔领取最晚能够领取的工夫。如果超时未领取,这笔领取将会被敞开。 当然个别状况下,如果未上送,这个字段外部个别会有个默认的有效期,比方 3 天,这个工夫就比拟长了。 所以当调用领取接口时,能够将订单残余有效期传入领取接口。这样用户如果在超时工夫内未实现领取,领取将会失败。 第二种解决办法,外部发动退款。 这个解决办法仍然预先托底的解决办法,对于领取订单已敞开,然而领取却胜利的状况,发动外部退款,将钱退给用户。 外部能够有个定时工作,定时扫描领取订单已敞开然而领取却胜利的状况,而后发动退款指令。 最初最初用思维导图形式帮大家总结一下领取零碎可能会碰到的异样。 历史领取零碎相干文章收款神器!解读聚合收款码背地的原理|原创手机没网了,却还能领取,这是什么原理?|原创微微一扫,立即扣款,付款码背地的原理你不想晓得吗?|原创领取渠道路由零碎进化史从零开始设计对账零碎

October 27, 2020 · 1 min · jiezi

关于支付:微信支付踩坑合集微信小程序支付失败是什么原因持续更新

微信小程序开发的过程肯定会遇到各种问题,最让人辣手的就是领取问题,因为没有领取做商城相似的小程序就没有方法实现最要害的一步。那么领取失败到底什么起因呢?一下子收集了几个谬误相似,心愿对你有帮忙: No.1{err_code: "-1", err_desc: "调用领取JSAPI短少参数: total_fee", errMsg: "requestPayment:fail"}errMsg:"requestPayment:fail"err_code:"-1"err_desc:"调用领取JSAPI短少参数: total_fee" <?xml version="1.0" encoding="utf-8"?> <xml> <appid>xx</appid> <body><![CDATA[测试商品名称]]></body> <mch_id>xxx</mch_id> <nonce_str>krwub67ymmvm1nkjb9fitm6muqplqa45</nonce_str> <notify_url>xx</notify_url> <openid>xxx</openid> <out_trade_no>xx</out_trade_no> <spbill_create_ip>xxx</spbill_create_ip> <total_fee>1</total_fee> <trade_type>JSAPI</trade_type> <sign>xxx</sign> </xml> <?xml version="1.0" encoding="utf-8"?> <xml> <return_code><![CDATA[SUCCESS]]></return_code> <return_msg><![CDATA[OK]]></return_msg> <appid><![CDATA[wx64db6c2b70842ec1]]></appid> <mch_id><![CDATA[1504167501]]></mch_id> <nonce_str><![CDATA[Y34OjPAY9ReOCPDZ]]></nonce_str> <sign><![CDATA[039CF2A0B217BFCCAA01CCF4ECA1B32E]]></sign> <result_code><![CDATA[FAIL]]></result_code> <err_code><![CDATA[ORDERPAID]]></err_code> <err_code_des><![CDATA[该订单已领取]]></err_code_des> </xml> No.2如果微信小程序在进行微信领取时若提醒“商户号mch_id与appid不匹配”或者是提醒“无奈实现微信领取““签名谬误”等,请参考以下步骤查看; 筹备工作:查看以下步骤前,请先留神核查appid是否是同一个。具体核查形式: 1、微信小程序核查地址为:设置-开发设置 有显示具体 appid,如图: 2、我司后盾受权的 小程序 appid 地址,如图: 若核查无误的前提下,筹备以下三步的查看。 第一步:登录微信领取平台 https://pay.weixin.qq.com 查看对应的商户号与密钥及证书,并重置下密钥及重新安装下证书。 第二步:登录到对应的微信小程序账户下 https://mp.weixin.qq.com(留神此处是微信小程序账户不是公众号账户),查看是否开明微信领取。 若显示未开明,请参考教程,绑定第一步外面的商户号 第三步:登录我司小程序管理后盾,填写步骤一外面的商户号和密钥及证书(注:.P12证书) 以上步骤操作实现后,再从新去下单领取测试。 No.3如果你应用的是第三方开源我的项目,个别都是封装好了,依照要求去填写即可,出错的时候次要是证书的配置问题,譬如来客推商城领取的谬误解决方案: 起因有几点: 1、微信小程序没有与微信领取绑定 2、来客零碎后盾领取设置不正确,如图地位: 3、我的项目的目录权限请设置为 chmod 777 No.4ios的微信小程序领取失败解决办法:前两天做了个小程序,波及到了领取,后果在自测ios零碎时碰到了钉子 苹果手机领取失败的起因是:微信早在「微信小程序经营规定」第 14 条「小程序领取标准」中已明确示意:目前,在iOS 零碎下,微信小程序暂不得为虚构物品购买提供领取性能 这就导致,许多须要线上领取,并且无实物的领取时,每每碰壁 你须要做的就是,让后盾人员在生成预领取订单时,不要呈现,费用、领取、付费、续费、转账等与费用相干的字眼 如果改了这个还不行,那么就须要查看是否有代码中的谬误 我解决的计划就是去掉了无关费用的字眼 No.5微信小程序领取性能开发与踩坑经验总结 ...

September 4, 2020 · 3 min · jiezi

关于支付:支付微信h5

背景h5领取分两种1.浏览器2.app 浏览器里的h5,最终也会跳转到app。 而app里的h5,实质是公众号。在微信里叫公众号,支付宝叫服务窗。 这里次要讲微信h5。 外围原理最终目标是下单,所以先倒着看,间接看最初一步须要什么入参,而后倒推。 1.下单 须要用户id //外围就是获取用户id,后面的获取受权码只是为了平安的获取用户id 2.如何获取用户id? 须要先受权 所以流程是 1.受权 获取受权码 //不同的app,名字不同,微信叫code,其实目标就是获取受权码 2.用户id 依据公众号id和受权码,就能够获取用户id //外围业务逻辑 3.下单 入参:用户id //即依据用户id,下单 流程图 和微信打交道的外围步骤就三步 受权码会变 用户id不变 //惟一标识用户/消费者 总结微信 支付宝 银联,都差不多,大的流程基本上都是一样的,只有受权码和用户id的名字可能不一样。 非间接对接微信间接对接微信,就会须要用户id,须要用户id就须要获取受权码。 如果是非间接对接微信,而是对接第三方领取公司,就不须要1.获取用户id 2.获取受权码,因为第三方领取公司曾经封装好了。 弹起微信领取明码框 如果是间接对接微信,须要本人调用微信js弹出微信领取明码框。 如果是对接第三方公司,就是调用第三方公司js,而后由第三方公司去调用微信js和弹出微信领取明码框。 参考https://pay.weixin.qq.com/wik... https://developers.weixin.qq.... https://www.cnblogs.com/0201z...

July 29, 2020 · 1 min · jiezi

关于支付:支付微信h5

背景h5领取分两种1.浏览器2.app 浏览器里的h5,最终也会跳转到app。 而app里的h5,实质是公众号。在微信里叫公众号,支付宝叫服务窗。 这里次要讲微信h5。 外围原理最终目标是下单,所以先倒着看,间接看最初一步须要什么入参,而后倒推。 1.下单 须要用户id //外围就是获取用户id,后面的获取受权码只是为了平安的获取用户id 2.如何获取用户id? 须要先受权 所以流程是 1.受权 获取受权码 //不同的app,名字不同,微信叫code,其实目标就是获取受权码 2.用户id 依据公众号id和受权码,就能够获取用户id //外围业务逻辑 3.下单 入参:用户id //即依据用户id,下单 流程图 和微信打交道的外围步骤就三步 受权码会变 用户id不变 //惟一标识用户/消费者 总结微信 支付宝 银联,都差不多,大的流程基本上都是一样的,只有受权码和用户id的名字可能不一样。 非间接对接微信间接对接微信,就会须要用户id,须要用户id就须要获取受权码。 如果是非间接对接微信,而是对接第三方领取公司,就不须要1.获取用户id 2.获取受权码,因为第三方领取公司曾经封装好了。 弹起微信领取明码框 如果是间接对接微信,须要本人调用微信js弹出微信领取明码框。 如果是对接第三方公司,就是调用第三方公司js,而后由第三方公司去调用微信js和弹出微信领取明码框。 参考https://pay.weixin.qq.com/wik... https://developers.weixin.qq.... https://www.cnblogs.com/0201z...

July 29, 2020 · 1 min · jiezi