Java生鲜电商平台-电商虚拟币的充值与消费思考

项目背景

最近由于项目业务原因,需要为系统设计虚拟币的充值及消费功能。公司内已经有成熟的支付网关服务,所以重点变成了如何设计项目内虚拟币的充值流程,让整个充值流程都实现幂等,确保用户的虚拟币余额不会重复增加或扣减。

商品购买及支付流程

 
微信支付时序图

(1)用户购买商品,商户后台请求生成支付订单并返回相关信息到客户端。
(2)客户端根据返回的信息唤起支付SDK,用户确认支付。
(3)用户完成支付后,支付系统会异步通知商户后台支付结果。
(4)商户后台接收支付回调,在回调接口内完成自己的业务逻辑。
(5)客户端在支付完成后延时一定时间从商户后台查询支付结果,此时若尚未接收到支付回调,可主动同步支付结果(保底策略)。

支付宝支付流程和微信支付类似,此处省略。正常情况下支付回调都会在毫秒级别进行通知回调。

虚拟币充值流程

虚拟币充值流程会嵌套支付回调流程中。若虚拟币没有完成完整的业务流程,支付系统会进行重试。因此业务流程需要支持幂等。

 
虚拟币充值流程

在实践过程遇到以下问题并最终得到解决:
(1)如何支持订单按用户维度分表?
支付回调信息只包括订单ID信息,在这种情况下一般只能根据订单ID进行分表。考虑到订单会越来越多,我们一开始就把订单按用户维度进行分表。一般情况下按用户维度的查询是很多的,而单纯按订单维度的查询会比较少。所以在预下单的时候把用户ID信息写入attach附加信息,支付回调时会携带上原先的附加信息,这样就可以知道用户及订单ID信息,完成后续操作。

在后来的优化中,订单ID生成时预留低位段存储用户订单表ID信息,这样完全不依赖附加信息进行传递,在用户进行自动扣费授权时的回调通知也可以适用。

(2)虚拟币如何做事务操作?
若只有用户虚拟币的数量信息,很容易会出现错误的重复操作。因此需要流水表配合进行事务操作,当流水表已经有相同的记录时说明当前操作是重复的,需要回滚虚拟币数值。通过数据库的单机事务即可实现虚拟币的正确变更,支持重入。
(3)如何做虚拟币的版本控制?
我们虚拟币每次变更都会对应一个版本号,在对虚拟币的并发操作时一般都是通过判断version是否符合预期时才进行数据变更。这个和乐观锁的控制类似,可是在这种情况下容易出现死锁,尤其是数据库性能差更容易触发。因此不再严格判断version版本号,只需要变更后的虚拟币数量不小于0即可,所有符合这个条件的变更都视为有效变更。这个情景适合不用版本号,只更新是做数据安全校验,适合库存模型,性能更高。

update table_xxx set avai_amount=avai_amount+:deltaAmount where user_id=:userId and avai_amount+:deltaAmount >= 0

有虚拟币消费才会出现并发修改,因此我们只需要严格控制虚拟币不出现余额不足以扣除的情况。

苹果内购虚拟币充值流程

用户在应用内购买商品时,客户端可以获取到用户ID、交易凭证receipt和交易ID等信息。整体购买流程和Android端差异比较大,因为对receipt验证流程参考Android下单流程做了拆解,更容易做到重入。
(1)客户端获取到充值列表;
(2)客户端支付成功后提交交易凭证receipt给服务端验证,服务端创建对应的凭证和订单记录,更新状态,完成充值;

 
苹果内购充值流程

苹果内购有以下事项需要注意:
(1)如何避免receipt被重复使用?
iOS客户端支付成功后能获取到transactionId和receipt信息,两者唯一对应。因此服务端在验证receipt有效后,可创建对应的transaction记录,根据transactionId进行分表,transactionId作为唯一键。这样可避免receipt被重复使用。
(2)transaction和订单记录的映射关系
订单记录包含渠道transactionId信息,这样在创建transaction记录后也可以唯一绑定到订单信息,避免重复创建订单。

设计总结

在设计订单系统时幂等性是首要考虑的问题,需要严格保证金额的准确性,不能给用户多扣款或多打款。一般情况下我们通过数据库单机事务和幂等重试等方式提高订单系统的健壮性。根据需要也可以选用消息队列等。

Java生鲜电商平台-电商虚拟币的充值与消费思考的更多相关文章

  1. Java生鲜电商平台-电商会员体系系统的架构设计与源码解析

    Java生鲜电商平台-电商会员体系系统的架构设计与源码解析 说明:Java生鲜电商平台中会员体系作为电商平台的基础设施,重要性不容忽视.我去年整理过生鲜电商中的会员系统,但是比较粗,现在做一个最好的整 ...

  2. Java生鲜电商平台-电商会员体系搭建

    Java生鲜电商平台-电商会员体系搭建 说明:因为之前一直从事的是B端的生鲜电商方面的产品,对会员体系方面有深刻的理解,今天来聊一聊会员体系的搭建. 明确会员体系的目的 首先我们需要明确的知道,搭建电 ...

  3. Java生鲜电商平台-电商起送价的深入思考与实战

    Java生鲜电商平台-电商起送价的深入思考与实战 说明:在生鲜电商中,起送价是一个非常普遍的话题,今天我们就用实战来告诉大家,如何设置起送价,如何编写起送价的代码,以及如何同步起送价. 在开始题目之前 ...

  4. Java生鲜电商平台-电商系统性能指标

    Java生鲜电商平台-电商系统性能指标 1.响应时间和吞吐量 根据应用程序的响应时间可以知道程序完成传输数据所用的时间.也可以从HTTP请求级别,或者成为数据库级别来看.对那些缓慢的查询你需要做一些优 ...

  5. Java生鲜电商平台-电商数据运营统计与分析

    Java生鲜电商平台-电商数据运营统计与分析 今天分享将会分为以下几个方面来阐述: 1. 作为运营我们需要统计与分析的几个核心数据是什么? 2. 核心数据对业务的指导价值在哪里呢? 3. 作为产品PM ...

  6. Java生鲜电商平台-电商订单系统全解析

    Java生鲜电商平台-电商订单系统全解析 说明:Java生鲜电商平台-电商订单系统全解析主要讲解OMS的内容,设计,开发,架构等知识. 今天分享将会分为以下三个环节来阐述: 1.订单系统的介绍 2.订 ...

  7. Java生鲜电商平台-电商中海量搜索ElasticSearch架构设计实战与源码解析

    Java生鲜电商平台-电商中海量搜索ElasticSearch架构设计实战与源码解析 生鲜电商搜索引擎的特点 众所周知,标准的搜索引擎主要分成三个大的部分,第一步是爬虫系统,第二步是数据分析,第三步才 ...

  8. Java生鲜电商平台-电商支付流程架构实战

    Java生鲜电商平台-电商支付流程架构实战 说明:我一直秉承的就是接地气的业务架构实战.我的文章都有一个这样的核心. 1. 业务场景 2. 解决问题. 3.代码实现. 4.代码重构. 5.总结与复盘. ...

  9. Java生鲜电商平台-电商促销业务分析设计与系统架构

    Java生鲜电商平台-电商促销业务分析设计与系统架构 说明:Java开源生鲜电商平台-电商促销业务分析设计与系统架构,列举的是常见的促销场景与源代码下载 左侧为享受促销的资格,常见为这三种: 首单 大 ...

随机推荐

  1. c++之基础数据类型

    c++规定了在创建一个变量或者常量时,必须先要指定相应的数据类型,否发无法将变量分配给内存. 1.整型 数据类型 占用空间 取值范围 short 2字节 -2^15-2^15-1 int 4字节 -2 ...

  2. conda pip 安装 dgl 并运行demo 出现:Segmentation fault (core dumped) 错误

    安装dgl 并运行的时候,出现了如上错误,很是郁闷:使用 gdb python; run train.py 进行调试,发现是torch的问题:我猜测估计是torch 安装的版本过于新:于是重新安装 1 ...

  3. 针对base64编码和URIEncode的一点研究

    Base64编码的作用 将任意的二进制比特串编码成由ASCii码中的64个可显示字符组成的字符串. 为什么需要base64编码? 所有的文件,本质上都是0.1组成的比特串,文本文件.二进制文件的区别只 ...

  4. 【1】基于OpenCV的DLL动态库隐式连接

    1DLL的作用 DLL是一个包含可由多个程序同时使用的代码和数据的库.例如:在Windows操作系统中,Comdlg32 DLL执行与对话框有关的常见函数.因此,每个程序都可以使用该DLL中包含的功能 ...

  5. 磁盘修复 mount: wrong fs type running e2fsck

    当服务器或PC机器的硬盘在使用一段时间后,会出现无法使用正常进行使用: 1. 当将文件系统挂载到指定的目录的时候,会出现mount 失败,如下图: [root@template ~]# mount / ...

  6. [认证 & 授权] 3. 基于OAuth2的认证(译)

    OAuth 2.0 规范定义了一个授权(delegation)协议,对于使用Web的应用程序和API在网络上传递授权决策非常有用.OAuth被用在各钟各样的应用程序中,包括提供用户认证的机制.这导致许 ...

  7. Consul初探-在深交之前先认识

    Consul 是什么? Consul 官方站点:https://www.consul.io/ 首先,官方介绍是:Consul 是一种服务网格的解决方案,在 Consul 中,提供了服务发现.配置.分段 ...

  8. android 引入一个布局库后该有的操作

    背景 引入一个布局库:com.zhy:percent-support-extends 然后sync now 成功了,也就是同步成功了. 然而开始使用的时候报告了: The following clas ...

  9. 知识图谱基础之RDF,RDFS与OWL 2

    https://zhuanlan.zhihu.com/p/32122644 看过之前两篇文章([1](为什么需要知识图谱?什么是知识图谱?——KG的前世今生), [2](语义网络,语义网,链接数据和知 ...

  10. Virtual Box复制虚拟机

    用惯了VM换BOX还是有点不大一样的,比如复制 我用了2个网卡,所以看起来麻烦了一次 注释了UUID 应该有更好的办法来操作,下面的看起来有点啰嗦,先凑合着这样弄... 1.关机 2.复制 3.改名称 ...