제가 직면한 기술 인터뷰 중 저는 사용자가 제3자 제공업체로부터 인터넷 크레딧을 구매할 수 있는 전자상거래 시스템을 설계해 달라는 요청을 받았습니다.
저는 자신있게 간단한 솔루션을 제안했습니다. 사용 가능한 패키지를 표시하고, 사용자가 하나를 선택하도록 하고, 외부 게이트웨이를 통해 결제를 처리하고, 공급자와 상호 작용하여 크레딧을 제공하는 것입니다. 그러나 사용자가 결제를 완료한 후 제공업체의 재고가 소진되는 등의 실패 시나리오에 대해 질문을 받았을 때 저는 이러한 문제를 효과적으로 처리할 수 있는 복원력이 내 디자인에 부족하다는 것을 깨달았습니다.
몇 주 전, 저는 플래시 세일 시스템과 재고 예약 패턴, 특히 재고 예약 전략에 초점을 맞춰 연구를 진행했습니다. 반짝 세일은 높은 수요와 제한된 재고를 다루는 경우가 많으므로 시스템 안정성을 유지하고 고객 기대치를 관리하기 위한 정교한 메커니즘이 필요합니다. 제가 발견한 한 가지 개념은 피크 시간대에 과잉 판매를 방지하는 데 도움이 되는 임시 재고 예약이었습니다.
이 조사를 통해 저의 인터뷰 경험이 생각났습니다. 나는 이러한 재고 예약 전략을 적용하면 초기 디자인의 단점을 해결할 수 있다는 것을 인식했습니다. 결제 과정에서 재고에 대한 임시 보류를 통합함으로써 시스템은 제공업체의 재고가 고갈되는 시나리오를 효과적으로 처리할 수 있습니다.
이 연구 문서에서는 연구에서 얻은 통찰력을 공유하고 인터넷 신용 구매 시스템 설계에 대한 세련된 접근 방식을 제안하는 것을 목표로 합니다. 재고 예약 전략을 통합함으로써 다양한 실패 시나리오를 처리하는 동시에 원활한 경험을 제공할 수 있는 강력하고 사용자 친화적인 플랫폼을 구축할 수 있습니다.
인터넷 크레딧 구매 시스템을 설계할 때 원활하고 안전하며 즐거운 사용자 경험을 보장하기 위해 고려해야 할 몇 가지 주요 요소가 있습니다. 분석해 보겠습니다.
이러한 사항을 고려하여 효율적이고 안전하며 사용자 친화적인 인터넷 신용 구매 시스템을 설계하여 사용자 만족도와 신뢰도를 높일 수 있습니다.
위에 설명된 기본 고려 사항을 바탕으로 다음 단계는 이러한 원칙을 강력하고 효과적인 시스템 설계로 변환하는 것입니다. 다양한 구성 요소 간의 상호 작용을 주의 깊게 매핑함으로써 시스템이 기능적 요구 사항을 충족할 뿐만 아니라 안정성과 확장성을 유지하면서 원활한 사용자 경험을 제공하도록 할 수 있습니다.
이 섹션에서는 시스템의 아키텍처와 흐름을 자세히 살펴보고 할당량 관리, 결제 처리, 서비스 활성화 등의 핵심 기능이 어떻게 일관되게 구현되는지 보여줍니다. 목표는 각 디자인 선택이 잠재적인 문제를 해결하고 신뢰할 수 있는 전자상거래 크레딧 구매 플랫폼을 제공하는 데 어떻게 기여하는지 강조하는 것입니다.
사용자가 처음부터 끝까지 시스템과 상호 작용하는 방식을 설명하기 위해 순서도를 통해 시각화된 시스템 흐름 개요부터 시작하겠습니다.
명확성을 위해 시스템 흐름은 6단계로 구분됩니다.
이 흐름은 사용자에게 원활하고 안정적인 경험을 보장하는 동시에 리소스와 잠재적인 오류를 효과적으로 관리합니다.
아래 시퀀스 다이어그램은 다양한 역할과 구성 요소 간의 상호 작용을 설명하는 데 도움이 됩니다.
명확성을 위해 시스템 흐름은 6단계로 구분됩니다.
이제 시스템의 흐름과 상호 작용을 개략적으로 설명했으므로 이제 모든 것이 코드에서 어떻게 통합되는지 알아볼 차례입니다. 이 섹션에서는 구현을 단계별로 분석하여 디자인이 주문 관리부터 공급자 및 결제 시스템과의 상호 작용까지 모든 것을 처리하는 작업 부분으로 변환되는 방법을 보여줍니다.
// 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 Enum: 이 열거형은 CREATED 및 RESERVED부터 PAYMENT_PENDING, COMPLETED 또는 REFUNDED까지 주문이 겪을 수 있는 모든 가능한 단계를 매핑합니다.
ReservationStatus Enum: 마찬가지로 이 열거형은 ACTIVE, EXPIRED, USED 또는 CANCELLED 등 할당량 예약 상태를 추적합니다.
이러한 클래스와 열거형은 함께 시스템의 패키지, 주문 및 할당량 예약을 관리하기 위한 백본을 구축합니다. 전자상거래 기능을 효과적으로 처리하기 위한 간단하면서도 구조화된 접근 방식입니다.
// 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와 문제가 발생한 경우 오류 세부 정보를 제공합니다.
확인응답: 활성화 후 모든 것이 원활하게 진행되었는지 확인합니다. 여기에는 주문 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 }
이 서비스는 주문 상태에 대해 사용자에게 전송되는 모든 알림을 처리합니다. 작동 방식은 다음과 같습니다.
이 서비스를 통해 사용자는 이메일, SMS 또는 실시간 업데이트를 통해 항상 주문에 대한 정보를 얻을 수 있습니다.
// 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:
결제 확인 예외:
이러한 예외를 사용함으로써 시스템은 명확하고 예측 가능한 방식으로 오류를 처리합니다. 이를 통해 개발자의 디버깅 효율성이 향상될 뿐만 아니라 문제가 발생했을 때 사용자가 명확하고 실행 가능한 피드백을 받을 수 있습니다.
// 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(주문 요청 요청):
processPayment(문자열 orderId, PaymentCallback 콜백):
verifyActivation(주문 주문):
completeOrder(주문 주문):
handleActivationFailure(주문 순서):
getOrder(문자열 주문 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 }
OrderController 클래스는 시스템에서 주문을 관리하는 REST API 엔드포인트를 관리합니다. Think는 요청을 하는 클라이언트와 무거운 작업을 수행하는 백엔드 서비스 사이의 다리 역할을 합니다.
POST /api/orders(createOrder):
POST /api/orders/callback(PaymentCallback 처리):
GET /api/orders/{orderId}(getOrder):
이 컨트롤러는 클라이언트와 백엔드의 원활한 통신을 보장하여 주문 관리를 최대한 원활하게 만듭니다.
이 연구 문서는 할당량 관리, 결제 처리, 서비스 활성화와 같은 중요한 문제를 해결하면서 전자 상거래 신용 판매 시스템을 설계하기 위한 기반을 마련합니다. 이 디자인은 기본 사항을 다루지만 항상 더 나은 결과를 얻을 수 있는 여지가 있습니다!
다음은 이 디자인을 개선할 수 있는 몇 가지 아이디어입니다.
읽어주셔서 정말 감사합니다! 이 문서가 비슷한 문제를 탐구하는 모든 사람에게 유용하고 명확성을 제공하기를 바랍니다. 물론 이 디자인이 완벽하지는 않습니다. 항상 개선의 여지가 있습니다. 어떤 생각이나 제안이 있으시면 듣고 싶습니다.
자원:
위 내용은 인터넷 크레딧 구매 시스템 설계의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!