在我面臨的一次技術面試中,我被要求設計一個電子商務系統,允許用戶從第三方供應商購買網路積分。
自信地,我提出了一個簡單的解決方案:顯示可用的套餐,讓用戶選擇一個,透過外部網關處理付款,並與提供者互動以提供積分。然而,當被問及失敗場景時(例如用戶完成付款後供應商缺貨),我意識到我的設計缺乏有效處理此類問題的彈性。
幾週前,我對閃購系統和庫存預訂模式進行了研究,特別關注庫存預訂策略。限時搶購通常需要應對高需求和有限的庫存,需要複雜的機制來維持系統穩定性和管理客戶期望。我發現的一個概念是臨時庫存預訂,這有助於防止高峰時段超售。
這項研究讓我想起了我的面試經驗。我認識到應用這些庫存預留策略可以解決我最初設計中的缺點。透過在結帳過程中暫時保留庫存,系統可以有效處理提供者庫存耗盡的情況。
在本研究文件中,我旨在分享從我的研究中獲得的見解,並提出一種設計網路信用購買系統的改進方法。透過整合庫存預留策略,我們可以建立一個既強大又用戶友好的平台,能夠處理各種故障場景,同時提供無縫體驗。
在設計網路信用購買系統時,需要考慮幾個關鍵因素,以確保無縫、安全和愉快的使用者體驗。讓我們來分解一下:
透過考慮這些因素,我們可以設計一個高效、安全、用戶友好的網路信用購買系統,從而提高用戶滿意度和信任度。
基於上述基本考慮因素,下一步是將這些原則轉化為穩健且有效的系統設計。透過仔細規劃各個組件之間的交互,我們可以確保系統不僅滿足功能需求,而且在保持可靠性和可擴展性的同時提供無縫的用戶體驗。
在本節中,我們將深入研究系統的架構和流程,展示配額管理、支付處理和服務激活等核心功能是如何緊密結合實現的。目的是強調每種設計選擇如何有助於解決潛在挑戰並提供可靠的電子商務信用購買平台。
讓我們先概述系統流程,透過流程圖視覺化,以說明使用者從開始到結束如何與系統互動。
為了清晰起見,系統流程分為六個階段:
此流程可確保為使用者提供流暢、可靠的體驗,同時還可有效管理資源和潛在錯誤。
下面的序列圖有助於說明不同角色和組件之間的交互作用。
為了清晰起見,系統流程分為六個階段:
現在我們已經概述了系統的流程和交互,是時候深入研究它們如何在程式碼中組合在一起了。本節逐步分解實現,展示如何將設計轉化為工作部件,處理從管理訂單到與提供者和支付系統互動的所有事務。
// 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中文網其他相關文章!