상품 구매 시스템
주문 스키마
Fields
userId
- 타입: ObjectId (User 참조)
- 필수: true
- 설명: 구매자 정보
- 참조: User 컬렉션의 _id
productId
- 타입: ObjectId (Product 참조)
- 필수: true
- 설명: 구매한 상품 정보
- 참조: Product 컬렉션의 _id
domain
- 타입: ObjectId (Domain 참조)
- 필수: true
- 설명: 주문이 발생한 도메인
- 참조: Domain 컬렉션의 _id
price
- 타입: Number
- 필수: true
- 설명: 개별 상품의 가격
- 최소값: 0
totalAmount
- 타입: Number
- 필수: true
- 설명: 총 주문 금액 (price * quantity)
- 계산: 상품 가격 × 수량
quantity
- 타입: Number
- 필수: true
- 기본값: 1
- 설명: 주문 수량
status
- 타입: String (enum)
- 필수: true
- 가능한 값:
- REQUESTED: 주문 요청됨
- COMPLETED: 주문 완료
- CANCELLED: 주문 취소
- 설명: 주문 처리 상태
paymentStatus
- 타입: String (enum)
- 기본값: 'PENDING'
- 가능한 값:
- PENDING: 결제 대기
- PAID: 결제 완료
- FAILED: 결제 실패
- 설명: 결제 처리 상태
transactionHash
- 타입: String
- 필수: false
- 설명: 블록체인 트랜잭션 해시
- 용도: 결제 트랜잭션 추적
timestamps
- createdAt: 주문 생성 시간
- updatedAt: 주문 정보 수정 시간
- 자동생성: true
인덱스
{ userId: 1 }: 사용자별 주문 조회 최적화{ domain: 1 }: 도메인별 주문 조회 최적화{ status: 1 }: 주문 상태별 조회 최적화{ createdAt: -1 }: 생성일 기준 정렬 최적화
참고사항
- 모든 주문은 생성 시 REQUESTED 상태로 시작
- 결제는 기본적으로 PENDING 상태로 시작
- totalAmount는 price와 quantity를 기반으로 자동 계산
- 트랜잭션 해시는 블록체인 결제 완료 시에만 기록
- 타임스탬프는 자동으로 관리됨
API 엔드포인트
내 주문 내역 조회
GET /api/v1/orders/my
요청
- 인증: 필수 (JWT)
- 헤더:
Authorization: Bearer {access_token}
응답
[
{
"_id": "507f1f77bcf86cd799439013",
"productId": {
"name": "Premium Package",
"price": 200,
"snpQty": 100
},
"status": "COMPLETED",
"price": 200,
"totalAmount": 200,
"quantity": 1,
"paymentStatus": "PAID",
"transactionHash": "0x123...",
"createdAt": "2024-02-19T02:08:44.285Z"
}
]
응답 필드 설명
_id: 주문 고유 IDproductId: 구매한 상품 정보name: 상품명price: 상품 가격snpQty: SNP 수량status: 주문 처리 상태price: 개별 상품 가격totalAmount: 총 결제 금액quantity: 구매 수량paymentStatus: 결제 상태transactionHash: 블록체인 트랜잭션 해시createdAt: 주문 생성 시간
정렬
- 생성일 기준 내림차순 (
-createdAt)
오류 응답
인증 실패
{
"statusCode": 401,
"message": "Unauthorized",
"error": "Unauthorized"
}
서버 오류
{
"statusCode": 500,
"message": "Internal server error",
"error": "Internal Server Error"
}
상품 구매
POST /api/v1/products/purchase
요청
- 인증: 필수 (JWT)
- 요청 데이터:
{ "productId": "507f1f77bcf86cd799439011", "domainId": "507f1f77bcf86cd799439012" }
응답
{
"success": true,
"order": {
"_id": "507f1f77bcf86cd799439013",
"user": "507f1f77bcf86cd799439014",
"product": {
"_id": "507f1f77bcf86cd799439011",
"name": "Premium Package",
"price": 200
},
"domain": "507f1f77bcf86cd799439012",
"price": 200,
"status": "COMPLETED",
"createdAt": "2024-02-19T02:08:44.285Z"
}
}
구매 프로세스
- 사용자 확인
- 로그인된 사용자 확인
-
해당 도메인 소속 확인
-
상품 확인
- 상품 존재 여부 확인
- 도메인 일치 여부 확인
-
상품 활성화 상태 확인
-
주문 생성
- 주문 정보 생성
- 가격 정보 기록
-
상태를 'COMPLETED'로 설정
-
추천 보상 처리
- 구매자의 추천인 확인
- 각 레벨별 보상 금액 계산
- 보상 지급 처리
오류 처리
상품 없음
{
"statusCode": 404,
"message": "상품을 찾을 수 없습니다.",
"error": "Not Found"
}
도메인 불일치
{
"statusCode": 400,
"message": "잘못된 도메인입니다.",
"error": "Bad Request"
}
구매 실패
{
"statusCode": 500,
"message": "주문 처리 중 오류가 발생했습니다.",
"error": "Internal Server Error"
}
참고사항
- 모든 주문은 특정 도메인에 속해야 함
- 주문 생성 시 현재 상품 가격이 기록됨
- 주문 완료 시 자동으로 추천 보상이 처리됨
- 주문 취소는 지원되지 않음 (상태만 변경 가능)
- 주문 내역은 생성일 기준 내림차순으로 정렬됨
구매 가능한 상품 유형
일반 상품
- 관리자가 개별적으로 등록한 상품
- 단일 상품 API(
POST /v1/products)를 통해 등록됨 - 각 상품은 고유한 ID를 가짐
일괄 등록 상품
- 관리자가 한 번에 다수 등록한 상품
- 일괄 등록 API(
POST /v1/products/bulk)를 통해 등록됨 - 각 상품은 개별적으로 고유한 ID를 가지며 일반 상품과 동일하게 취급됨
- 대량 상품 등록 시 효율적인 방법
주문 프로세스
1. 상품 선택
- 사용자는
/v1/products또는/v1/products/domain/{domain}API를 통해 구매 가능한 상품 목록 조회 - 일반 등록 상품과 일괄 등록 상품 모두 동일하게 표시됨
- 표시 방식이나 구매 과정에서 차이 없음