通常,当客户单击电子商务网站上的"结帐"按钮时,他们会经历如下所示的结帐过程:
- 更新/确认购物车中的产品数量
- 输入地址,选择送货方式
- 输入信用卡详细信息
- 查看所有订单详情,点击"确认"付款
- 带有订单号的"谢谢"页面
客户在结帐的步骤 4 上单击"确认"后,我们通常希望创建一些数据库对象,包括:
-
Order
-
Invoice
(与相应的Order
有关) -
Payment
(与相应的Invoice
有关)
我的第一个想法是应该发生这样的事情:
- 创建包含订单详细信息的
Order
对象 - 使用订单的总成本创建
Invoice
对象 - 使用
status=PENDING
创建Payment
对象并尝试向信用卡收费 - 如果收费成功,请将
Payment
更新为status=SUCCESS
并将客户重定向到"谢谢"页面 - 如果收费失败,请将
Payment
更新为status=FAIL
,并将客户返回到步骤 4,并显示错误消息
但是,此流程存在一个问题:如果收费失败并且客户返回到步骤 4,则如果他们再次单击"确认"重新尝试付款,将生成重复的Order
和Invoice
。
为了避免这种情况,我们可以修改此流以仅创建新的Order
并Invoice
(如果它们尚不存在)。但是,这样做的问题是用户可能会单击返回步骤 1,更改订单,然后尝试再次付款。在这种情况下,Order
和Invoice
对象将不正确,因为顺序已更改。
因此,为了避免这种情况,我们可以更新现有的Order
并Invoice
它们是否已经存在,但现在这似乎过于复杂,并且还打破了发票应该是不可变的常见约定。
对此进行建模的最佳方法是什么?
简单的答案 - 在交易确认之前什么都不会发生。如果信用卡无法通过,请再次向他们显示带有相关错误消息的帐单,然后再试一次。这可能是一个简单的错误。或者可能是他们真的不会做订单。
"发票"意味着欠钱。实际上,这可能是描述客户购物时处理中的订单的一种有趣方式。但是您处于最后一步,一旦交易完成,它只是一个订单。因此,您无需单独创建任何内容。
========= 编辑
嘿,我真的很感谢您在其他评论中详细说明发票要求 - 不知道。我仍然会反驳这种在你知道会有订单之前必须创建一个订单的想法。
否则 - 您为什么不在发票上做与付款相同的操作?似乎发票只有在交易完成后才是"不可变的"。因此,有一个状态字段 - 待处理,成功,失败等,如果付款失败,则非常重要 - 在提交交易之前 - 您正在检查购物车等以再次确认所有总数。
而且您需要使客户无法单击返回并更改订单。购物车中必须有一个令牌或某种标识符,这使得这是不可能的。
此外,我强烈建议 - 如果订单发生更改 - 例如退货,换货等 - 您发布新订单。因为这种变化的一部分也是考虑到现有库存的变化。