数据库设计 - 电子商务网站结账建模



通常,当客户单击电子商务网站上的"结帐"按钮时,他们会经历如下所示的结帐过程:

  1. 更新/确认购物车中的产品数量
  2. 输入地址,选择送货方式
  3. 输入信用卡详细信息
  4. 查看所有订单详情,点击"确认"付款
  5. 带有订单号的"谢谢"页面

客户在结帐的步骤 4 上单击"确认"后,我们通常希望创建一些数据库对象,包括:

  • Order
  • Invoice(与相应的Order有关)
  • Payment(与相应的Invoice有关)

我的第一个想法是应该发生这样的事情:

  1. 创建包含订单详细信息的Order对象
  2. 使用订单的总成本创建Invoice对象
  3. 使用 status=PENDING 创建 Payment 对象并尝试向信用卡收费
  4. 如果收费成功,请将Payment更新为status=SUCCESS并将客户重定向到"谢谢"页面
  5. 如果收费失败,请将Payment更新为status=FAIL,并将客户返回到步骤 4,并显示错误消息

但是,此流程存在一个问题:如果收费失败并且客户返回到步骤 4,则如果他们再次单击"确认"重新尝试付款,将生成重复的OrderInvoice

为了避免这种情况,我们可以修改此流以仅创建新的OrderInvoice(如果它们尚不存在)。但是,这样做的问题是用户可能会单击返回步骤 1,更改订单,然后尝试再次付款。在这种情况下,OrderInvoice对象将不正确,因为顺序已更改。

因此,为了避免这种情况,我们可以更新现有的OrderInvoice它们是否已经存在,但现在这似乎过于复杂,并且还打破了发票应该是不可变的常见约定。

对此进行建模的最佳方法是什么?

简单的答案 - 在交易确认之前什么都不会发生。如果信用卡无法通过,请再次向他们显示带有相关错误消息的帐单,然后再试一次。这可能是一个简单的错误。或者可能是他们真的不会做订单。

"发票"意味着欠钱。实际上,这可能是描述客户购物时处理中的订单的一种有趣方式。但是您处于最后一步,一旦交易完成,它只是一个订单。因此,您无需单独创建任何内容。

======

=== 编辑

嘿,我真的很感谢您在其他评论中详细说明发票要求 - 不知道。我仍然会反驳这种在你知道会有订单之前必须创建一个订单的想法。

否则 - 您为什么不在发票上做与付款相同的操作?似乎发票只有在交易完成后才是"不可变的"。因此,有一个状态字段 - 待处理,成功,失败等,如果付款失败,则非常重要 - 在提交交易之前 - 您正在检查购物车等以再次确认所有总数。

而且您需要使客户无法单击返回并更改订单。购物车中必须有一个令牌或某种标识符,这使得这是不可能的。

此外,我强烈建议 - 如果订单发生更改 - 例如退货,换货等 - 您发布新订单。因为这种变化的一部分也是考虑到现有库存的变化。

最新更新