在我面临的一次技术面试中,我被要求设计一个电子商务系统,允许用户从第三方提供商处购买互联网积分。
自信地,我提出了一个简单的解决方案:显示可用的套餐,让用户选择一个,通过外部网关处理付款,并与提供商交互以提供积分。然而,当被问及失败场景时(例如用户完成付款后供应商缺货),我意识到我的设计缺乏有效处理此类问题的弹性。
几周前,我对闪购系统和库存预订模式进行了研究,特别关注库存预订策略。限时抢购通常需要应对高需求和有限的库存,需要复杂的机制来维持系统稳定性和管理客户期望。我发现的一个概念是临时库存预订,这有助于防止高峰时段超售。
这项研究让我想起了我的面试经历。我认识到应用这些库存预留策略可以解决我最初设计中的缺点。通过在结帐过程中临时保留库存,系统可以有效处理提供商库存耗尽的情况。
在本研究文档中,我旨在分享从我的研究中获得的见解,并提出一种设计互联网信用购买系统的改进方法。通过整合库存预留策略,我们可以构建一个既强大又用户友好的平台,能够处理各种故障场景,同时提供无缝体验。
在设计互联网信用购买系统时,需要考虑几个关键因素,以确保无缝、安全和愉快的用户体验。让我们来分解一下:
通过考虑这些因素,我们可以设计一个高效、安全、用户友好的互联网信用购买系统,从而提高用户满意度和信任度。
基于上述基本考虑因素,下一步是将这些原则转化为稳健且有效的系统设计。通过仔细规划各个组件之间的交互,我们可以确保系统不仅满足功能需求,而且在保持可靠性和可扩展性的同时提供无缝的用户体验。
在本节中,我们将深入研究系统的架构和流程,展示配额管理、支付处理和服务激活等核心功能是如何紧密结合实现的。目的是强调每种设计选择如何有助于解决潜在挑战并提供可靠的电子商务信用购买平台。
让我们首先概述系统流程,通过流程图可视化,以说明用户从开始到结束如何与系统交互。
为了清晰起见,系统流程分为六个阶段:
此流程可确保为用户提供流畅、可靠的体验,同时还可以有效管理资源和潜在错误。
下面的序列图有助于说明不同角色和组件之间的交互。
为了清晰起见,系统流程分为六个阶段:
现在我们已经概述了系统的流程和交互,是时候深入研究它们如何在代码中组合在一起了。本节逐步分解实现,展示如何将设计转化为工作部件,处理从管理订单到与提供商和支付系统交互的所有事务。
// Domain Models @Getter @Setter @Entity public class Package { @Id private String id; private String name; private BigDecimal price; private BigDecimal providerCost; private String description; private boolean active; } @Getter @Setter @Entity public class Order { @Id private String id; private String customerId; private String packageId; private String reservationId; private String paymentId; private String escrowId; private OrderStatus status; private BigDecimal amount; private BigDecimal providerCost; private LocalDateTime createdAt; private LocalDateTime updatedAt; } @Getter @Setter @Entity public class QuotaReservation { @Id private String id; private String packageId; private LocalDateTime expiresAt; private ReservationStatus status; } // Enums public enum OrderStatus { CREATED, RESERVED, PAYMENT_PENDING, PAYMENT_COMPLETED, IN_ESCROW, ACTIVATING, ACTIVATION_FAILED, COMPLETED, REFUNDED } public enum ReservationStatus { ACTIVE, EXPIRED, USED, CANCELLED }
这些类的作用如下:
套餐:这是我们定义用户可以购买的互联网积分套餐的地方。它会跟踪包 ID、名称、价格、提供商成本、描述以及包是否处于活动状态等详细信息。
订单:将此视为用户购买的记录。它包括订单 ID、客户 ID、所选套餐 ID 等信息,以及预订 ID、付款 ID、托管 ID、订单状态、付款金额、提供商成本和时间戳等相关详细信息。
QuotaReservation:处理套餐配额的临时预订。它记录预订 ID、所绑定的套餐、过期时间及其当前状态(如有效或过期)。
OrderStatus 枚举:此枚举列出了订单可能经历的所有可能阶段,从 CREATED 和 RESERVED 到 PAYMENT_PENDING、COMPLETED 甚至 REFUNDED。
ReservationStatus 枚举:同样,此枚举跟踪配额预留的状态,无论是活动、过期、已使用还是已取消。
这些类和枚举共同构建了系统中管理包裹、订单和配额预留的主干。这是一种有效处理电子商务功能的简单而结构化的方法。
// Request/Response DTOs @Getter @Setter public class OrderRequest { private String customerId; private String packageId; private BigDecimal amount; } @Getter @Setter public class PaymentCallback { private String orderId; private String paymentId; private String status; private BigDecimal amount; private LocalDateTime timestamp; } @Getter @Setter public class QuotaResponse { private String packageId; private boolean available; private Integer remainingQuota; private LocalDateTime timestamp; } @Getter @Setter public class ReservationResponse { private String id; private String packageId; private LocalDateTime expiresAt; private ReservationStatus status; } @Getter @Setter public class ActivationResponse { private String orderId; private boolean success; private String activationId; private String errorCode; private String errorMessage; } @Getter @Setter public class VerificationResponse { private String orderId; private String activationId; private boolean success; private String status; private LocalDateTime activatedAt; } @Getter @Setter public class PaymentRequest { private String orderId; private BigDecimal amount; private String currency; private String customerId; private String returnUrl; private String callbackUrl; } @Getter @Setter public class PaymentSession { private String sessionId; private String paymentUrl; private LocalDateTime expiresAt; private String status; } @Getter @Setter public class EscrowResponse { private String id; private String paymentId; private BigDecimal amount; private String status; private LocalDateTime createdAt; }
让我们来分解一下:
OrderRequest:这都是关于创建新订单所需的数据。它包括客户 ID、他们想要购买的套餐以及他们将支付的总金额。
PaymentCallback:将此视为来自支付网关的通知。尝试付款后,它会提供订单 ID、付款 ID、状态(成功或失败)、支付金额以及付款时间等详细信息。
QuotaResponse:这是关于检查可用性的。它告诉我们套餐是否可用、剩余配额以及信息上次更新的时间。
ReservationResponse:预订套餐后,这将为您提供所有详细信息:预订 ID、关联的套餐、预订何时到期以及其当前状态(例如有效或已过期) .
ActivationResponse:这告诉我们服务激活的情况。如果成功或失败,如果出现问题,它会向我们提供激活 ID 和错误详细信息。
VerificationResponse:激活后,我们验证一切是否顺利。其中包括订单 ID、激活 ID、成功状态以及激活时间。
PaymentRequest:在开始付款流程之前,此 DTO 会收集必要的详细信息,例如订单 ID、要支付的金额、货币、客户 ID 和回调 URL。
PaymentSession:这是付款流程开始时创建的内容。它包括会话 ID、支付 URL(用户去支付的地方)、过期时间以及会话状态。
EscrowResponse:如果资金被托管,这会告诉我们所有相关信息,例如托管 ID、付款 ID、持有金额、状态以及创建时间。
所有这些类都定义了系统不同部分之间通信的构建块——无论是发出请求还是返回响应。他们确保每个人(和所有事物)都在同一页面上。
// Domain Models @Getter @Setter @Entity public class Package { @Id private String id; private String name; private BigDecimal price; private BigDecimal providerCost; private String description; private boolean active; } @Getter @Setter @Entity public class Order { @Id private String id; private String customerId; private String packageId; private String reservationId; private String paymentId; private String escrowId; private OrderStatus status; private BigDecimal amount; private BigDecimal providerCost; private LocalDateTime createdAt; private LocalDateTime updatedAt; } @Getter @Setter @Entity public class QuotaReservation { @Id private String id; private String packageId; private LocalDateTime expiresAt; private ReservationStatus status; } // Enums public enum OrderStatus { CREATED, RESERVED, PAYMENT_PENDING, PAYMENT_COMPLETED, IN_ESCROW, ACTIVATING, ACTIVATION_FAILED, COMPLETED, REFUNDED } public enum ReservationStatus { ACTIVE, EXPIRED, USED, CANCELLED }
该服务负责存储包数据的本地缓存。目标是使系统更快并减少对提供商 API 的不必要调用。
此服务处理与提供商的 API 的通信。它管理诸如检查配额、预订套餐、激活服务和验证这些激活等任务。
当出现临时问题时,该服务使用 RetryTemplate 自动重试对提供商 API 的请求。这确保了系统即使在出现轻微问题时也能保持可靠和弹性。
通过组合这些功能,此代码可确保系统有效地管理包数据,同时保持与提供商的 API 的顺畅且可靠的通信。
// Domain Models @Getter @Setter @Entity public class Package { @Id private String id; private String name; private BigDecimal price; private BigDecimal providerCost; private String description; private boolean active; } @Getter @Setter @Entity public class Order { @Id private String id; private String customerId; private String packageId; private String reservationId; private String paymentId; private String escrowId; private OrderStatus status; private BigDecimal amount; private BigDecimal providerCost; private LocalDateTime createdAt; private LocalDateTime updatedAt; } @Getter @Setter @Entity public class QuotaReservation { @Id private String id; private String packageId; private LocalDateTime expiresAt; private ReservationStatus status; } // Enums public enum OrderStatus { CREATED, RESERVED, PAYMENT_PENDING, PAYMENT_COMPLETED, IN_ESCROW, ACTIVATING, ACTIVATION_FAILED, COMPLETED, REFUNDED } public enum ReservationStatus { ACTIVE, EXPIRED, USED, CANCELLED }
此类在管理系统如何与支付网关交互以顺利、安全地处理金融交易方面发挥着关键作用。
在管理系统中安全高效的金融交易时,此类是拼图的关键部分。
// Domain Models @Getter @Setter @Entity public class Package { @Id private String id; private String name; private BigDecimal price; private BigDecimal providerCost; private String description; private boolean active; } @Getter @Setter @Entity public class Order { @Id private String id; private String customerId; private String packageId; private String reservationId; private String paymentId; private String escrowId; private OrderStatus status; private BigDecimal amount; private BigDecimal providerCost; private LocalDateTime createdAt; private LocalDateTime updatedAt; } @Getter @Setter @Entity public class QuotaReservation { @Id private String id; private String packageId; private LocalDateTime expiresAt; private ReservationStatus status; } // Enums public enum OrderStatus { CREATED, RESERVED, PAYMENT_PENDING, PAYMENT_COMPLETED, IN_ESCROW, ACTIVATING, ACTIVATION_FAILED, COMPLETED, REFUNDED } public enum ReservationStatus { ACTIVE, EXPIRED, USED, CANCELLED }
此服务处理发送给用户的有关订单状态的所有通知。其工作原理如下:
这项服务可确保用户始终了解其订单,无论是通过电子邮件、短信还是实时更新。
// Domain Models @Getter @Setter @Entity public class Package { @Id private String id; private String name; private BigDecimal price; private BigDecimal providerCost; private String description; private boolean active; } @Getter @Setter @Entity public class Order { @Id private String id; private String customerId; private String packageId; private String reservationId; private String paymentId; private String escrowId; private OrderStatus status; private BigDecimal amount; private BigDecimal providerCost; private LocalDateTime createdAt; private LocalDateTime updatedAt; } @Getter @Setter @Entity public class QuotaReservation { @Id private String id; private String packageId; private LocalDateTime expiresAt; private ReservationStatus status; } // Enums public enum OrderStatus { CREATED, RESERVED, PAYMENT_PENDING, PAYMENT_COMPLETED, IN_ESCROW, ACTIVATING, ACTIVATION_FAILED, COMPLETED, REFUNDED } public enum ReservationStatus { ACTIVE, EXPIRED, USED, CANCELLED }
这就是所有 WebSocket 魔法发生的地方!它管理服务器和客户端之间的实时更新。
此设置可确保后端和前端之间的顺畅和即时通信,因此用户始终可以获得有关配额可用性和订单状态的最新信息。
// Domain Models @Getter @Setter @Entity public class Package { @Id private String id; private String name; private BigDecimal price; private BigDecimal providerCost; private String description; private boolean active; } @Getter @Setter @Entity public class Order { @Id private String id; private String customerId; private String packageId; private String reservationId; private String paymentId; private String escrowId; private OrderStatus status; private BigDecimal amount; private BigDecimal providerCost; private LocalDateTime createdAt; private LocalDateTime updatedAt; } @Getter @Setter @Entity public class QuotaReservation { @Id private String id; private String packageId; private LocalDateTime expiresAt; private ReservationStatus status; } // Enums public enum OrderStatus { CREATED, RESERVED, PAYMENT_PENDING, PAYMENT_COMPLETED, IN_ESCROW, ACTIVATING, ACTIVATION_FAILED, COMPLETED, REFUNDED } public enum ReservationStatus { ACTIVE, EXPIRED, USED, CANCELLED }
以下是这些自定义异常类的详细信息以及如何使用它们来处理系统中的特定错误场景:
QuotaNotAvailableException:
OrderNotFoundException:
PaymentVerificationException:
通过使用这些异常,系统以干净且可预测的方式处理错误。它们不仅可以提高开发人员的调试效率,还可以确保用户在出现问题时收到清晰且可操作的反馈。
// Request/Response DTOs @Getter @Setter public class OrderRequest { private String customerId; private String packageId; private BigDecimal amount; } @Getter @Setter public class PaymentCallback { private String orderId; private String paymentId; private String status; private BigDecimal amount; private LocalDateTime timestamp; } @Getter @Setter public class QuotaResponse { private String packageId; private boolean available; private Integer remainingQuota; private LocalDateTime timestamp; } @Getter @Setter public class ReservationResponse { private String id; private String packageId; private LocalDateTime expiresAt; private ReservationStatus status; } @Getter @Setter public class ActivationResponse { private String orderId; private boolean success; private String activationId; private String errorCode; private String errorMessage; } @Getter @Setter public class VerificationResponse { private String orderId; private String activationId; private boolean success; private String status; private LocalDateTime activatedAt; } @Getter @Setter public class PaymentRequest { private String orderId; private BigDecimal amount; private String currency; private String customerId; private String returnUrl; private String callbackUrl; } @Getter @Setter public class PaymentSession { private String sessionId; private String paymentUrl; private LocalDateTime expiresAt; private String status; } @Getter @Setter public class EscrowResponse { private String id; private String paymentId; private BigDecimal amount; private String status; private LocalDateTime createdAt; }
OrderService 类处理管理订单时的繁重工作。让我们来看看它是如何工作的:
createOrder(OrderRequest 请求):
processPayment(String orderId, PaymentCallback 回调):
验证激活(订单顺序):
completeOrder(订单顺序):
handleActivationFailure(订单顺序):
getOrder(String orderId):
此服务是订单管理流程的支柱,将所有内容结合在一起以提供无缝的用户体验。
// Domain Models @Getter @Setter @Entity public class Package { @Id private String id; private String name; private BigDecimal price; private BigDecimal providerCost; private String description; private boolean active; } @Getter @Setter @Entity public class Order { @Id private String id; private String customerId; private String packageId; private String reservationId; private String paymentId; private String escrowId; private OrderStatus status; private BigDecimal amount; private BigDecimal providerCost; private LocalDateTime createdAt; private LocalDateTime updatedAt; } @Getter @Setter @Entity public class QuotaReservation { @Id private String id; private String packageId; private LocalDateTime expiresAt; private ReservationStatus status; } // Enums public enum OrderStatus { CREATED, RESERVED, PAYMENT_PENDING, PAYMENT_COMPLETED, IN_ESCROW, ACTIVATING, ACTIVATION_FAILED, COMPLETED, REFUNDED } public enum ReservationStatus { ACTIVE, EXPIRED, USED, CANCELLED }
OrderController 类负责管理系统中订单的 REST API 端点。 Think 是发出请求的客户端和执行繁重任务的后端服务之间的桥梁。
POST /api/orders (createOrder):
POST /api/orders/callback (handlePaymentCallback):
GET /api/orders/{orderId} (getOrder):
该控制器确保客户端和后端无缝通信,使订单管理尽可能顺利。
本研究文档为设计电子商务信用销售系统、解决配额管理、支付处理和服务激活等重要挑战奠定了基础。虽然此设计涵盖了基础知识,但总有改进的空间!
以下是改进此设计的一些想法:
非常感谢您的阅读!我希望本文档有用,并为探索类似挑战的任何人提供清晰的思路。当然,这种设计并不完美——总有改进的空间。如果您有任何想法或建议,我很想听听。
资源:
以上是设计一个互联网信用购买系统的详细内容。更多信息请关注PHP中文网其他相关文章!