Appearance
NextMarket API 엔드포인트 설계서
Base URL:
/api/v1
공통 사항
인증 헤더
http
Authorization: Bearer {access_token}공통 응답 형식
성공 응답
json
{
"success": true,
"data": { ... },
"meta": {
"timestamp": "2025-01-07T12:00:00.000Z"
}
}페이지네이션 응답
json
{
"success": true,
"data": [ ... ],
"meta": {
"page": 1,
"limit": 20,
"total": 100,
"totalPages": 5
}
}에러 응답
json
{
"success": false,
"error": {
"code": "AUTH_001",
"message": "인증 토큰이 만료되었습니다"
}
}공통 쿼리 파라미터
| 파라미터 | 타입 | 설명 |
|---|---|---|
page | number | 페이지 번호 (기본: 1) |
limit | number | 페이지당 항목 수 (기본: 20, 최대: 100) |
sort | string | 정렬 기준 (예: createdAt:desc) |
1. 인증 API
1.1 아이디 중복 체크
http
GET /auth/check-username?username=user@example.comQuery Parameters
| 파라미터 | 타입 | 필수 | 설명 |
|---|---|---|---|
| username | string | O | 확인할 아이디(이메일) |
Response 200 OK
json
{
"success": true,
"data": {
"available": true,
"message": "사용 가능한 아이디입니다"
}
}1.2 회원가입
http
POST /auth/registerRequest Body
json
{
"username": "user@example.com",
"email": "user@example.com",
"password": "Password123!",
"name": "홍길동",
"phone": "010-1234-5678",
"marketingSms": false,
"marketingEmail": true,
"marketingKakao": false,
"countryCode": "KR"
}| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| username | string | O | 로그인 아이디 (이메일 형식 권장) |
| string | O | 이메일 | |
| password | string | O | 비밀번호 (8자 이상) |
| name | string | O | 이름 |
| phone | string | X | 전화번호 |
| marketingSms | boolean | X | SMS 마케팅 동의 |
| marketingEmail | boolean | X | 이메일 마케팅 동의 |
| marketingKakao | boolean | X | 카카오 마케팅 동의 |
| countryCode | string | X | 국가 코드 (기본: KR) |
Response 201 Created
json
{
"success": true,
"data": {
"customerId": 12345,
"customerCode": "customer_abc123",
"username": "user@example.com",
"name": "홍길동"
}
}1.3 로그인
http
POST /auth/loginRequest Body
json
{
"username": "user@example.com",
"password": "Password123!"
}Response 200 OK
json
{
"success": true,
"data": {
"accessToken": "session-token-hex-string...",
"expiresIn": 900,
"customer": {
"id": 12345,
"code": "customer_abc123",
"username": "user@example.com",
"name": "홍길동",
"role": "USER"
}
}
}1.4 로그아웃
http
POST /auth/logoutHeaders: Authorization: Bearer {access_token}
Response 200 OK
json
{
"success": true,
"message": "로그아웃 되었습니다"
}1.5 비밀번호 재설정 요청 📋 예정
http
POST /auth/password/reset-requestRequest Body
json
{
"email": "user@example.com"
}Response 200 OK
json
{
"success": true,
"message": "비밀번호 재설정 이메일이 발송되었습니다"
}1.6 비밀번호 재설정 📋 예정
http
POST /auth/password/resetRequest Body
json
{
"token": "reset-token-from-email",
"newPassword": "NewPassword123!"
}Response 200 OK
json
{
"success": true,
"message": "비밀번호가 변경되었습니다"
}2. 회원 API
2.1 내 정보 조회
http
GET /users/meResponse 200 OK
json
{
"success": true,
"data": {
"id": 12345,
"code": "customer_abc123",
"username": "user@example.com",
"email": "user@example.com",
"name": "홍길동",
"phone": "010-1234-5678",
"marketingSms": false,
"marketingEmail": true,
"marketingKakao": false,
"createTs": "2025-01-01T00:00:00.000Z"
}
}2.2 내 정보 수정
http
PATCH /users/meRequest Body
json
{
"name": "홍길순",
"phone": "010-9876-5432"
}Response 200 OK
json
{
"success": true,
"data": {
"id": 1,
"name": "홍길순",
"phone": "010-9876-5432"
}
}2.3 비밀번호 변경
http
PATCH /users/me/passwordRequest Body
json
{
"currentPassword": "OldPassword123!",
"newPassword": "NewPassword123!"
}Response 200 OK
json
{
"success": true,
"message": "비밀번호가 변경되었습니다"
}2.4 배송지 목록 조회 📋 예정
http
GET /users/me/addressesResponse 200 OK
json
{
"success": true,
"data": [
{
"id": 1,
"name": "집",
"recipientName": "홍길동",
"phone": "010-1234-5678",
"zipCode": "12345",
"address": "서울시 강남구 테헤란로 123",
"addressDetail": "아파트 101동 1001호",
"isDefault": true
}
]
}2.5 배송지 추가 📋 예정
http
POST /users/me/addressesRequest Body
json
{
"name": "회사",
"recipientName": "홍길동",
"phone": "010-1234-5678",
"zipCode": "54321",
"address": "서울시 서초구 서초대로 456",
"addressDetail": "빌딩 10층",
"isDefault": false
}Response 201 Created
json
{
"success": true,
"data": {
"id": 2,
"name": "회사",
...
}
}2.6 배송지 수정 📋 예정
http
PATCH /users/me/addresses/:addressId2.7 배송지 삭제 📋 예정
http
DELETE /users/me/addresses/:addressId2.8 회원 삭제
http
DELETE /users/:id🔒 관리자(ADMIN) 권한 필요
Response 200 OK
json
{
"success": true,
"message": "회원 삭제가 완료되었습니다"
}3. 상품 API
3.1 상품 목록 조회
http
GET /productsQuery Parameters
| 파라미터 | 타입 | 설명 |
|---|---|---|
categoryId | number | 카테고리 ID |
search | string | 검색어 |
minPrice | number | 최소 가격 |
maxPrice | number | 최대 가격 |
type | string | 상품 유형 (NORMAL, SUBSCRIPTION) |
status | string | 상태 (SALE, OUT_OF_STOCK) |
Response 200 OK
json
{
"success": true,
"data": [
{
"id": 1,
"code": "PROD-001",
"name": "프리미엄 상품",
"description": "상품 설명...",
"price": 29000,
"salePrice": 25000,
"thumbnailUrl": "https://...",
"categoryId": 1,
"categoryName": "전자제품",
"type": "NORMAL",
"status": "SALE",
"quantity": 100,
"createdAt": "2025-01-01T00:00:00.000Z"
}
],
"meta": {
"page": 1,
"limit": 20,
"total": 50,
"totalPages": 3
}
}3.2 상품 상세 조회
http
GET /products/:productIdResponse 200 OK
json
{
"success": true,
"data": {
"id": 1,
"code": "PROD-001",
"name": "프리미엄 상품",
"description": "상품 상세 설명...",
"content": "<p>상품 상세 HTML...</p>",
"price": 29000,
"salePrice": 25000,
"thumbnailUrl": "https://...",
"images": [
{ "id": 1, "url": "https://...", "order": 1 }
],
"category": {
"id": 1,
"name": "전자제품"
},
"options": [
{
"id": 1,
"name": "색상",
"values": [
{ "id": 1, "value": "빨강", "priceAdjust": 0 },
{ "id": 2, "value": "파랑", "priceAdjust": 1000 }
]
}
],
"type": "NORMAL",
"status": "SALE",
"quantity": 100,
"steppayProductId": 12345,
"steppayPriceId": 67890
}
}3.3 구독 상품 목록 조회
http
GET /products/subscriptionsResponse 200 OK
json
{
"success": true,
"data": [
{
"id": 10,
"code": "SUB-001",
"name": "프리미엄 멤버십",
"description": "월간 구독 서비스",
"plans": [
{
"id": 1,
"name": "월간 플랜",
"price": 9900,
"interval": 1,
"intervalUnit": "MONTH",
"steppayPriceId": 11111
},
{
"id": 2,
"name": "연간 플랜",
"price": 99000,
"interval": 1,
"intervalUnit": "YEAR",
"steppayPriceId": 22222
}
],
"features": [
"무료 배송",
"10% 추가 할인",
"전용 고객 지원"
]
}
]
}4. 카테고리 API
4.1 카테고리 목록 조회
http
GET /products/categoriesQuery Parameters
| 파라미터 | 타입 | 설명 |
|---|---|---|
parentId | number | 상위 카테고리 ID (미지정 시 최상위 카테고리) |
tree | boolean | 트리 구조로 반환 (기본: false) |
Response 200 OK (tree=true)
json
{
"success": true,
"data": [
{
"id": 1,
"name": "전자제품",
"slug": "electronics",
"order": 1,
"children": [
{
"id": 2,
"name": "스마트폰",
"slug": "smartphones",
"order": 1,
"children": []
},
{
"id": 3,
"name": "노트북",
"slug": "laptops",
"order": 2,
"children": []
}
]
}
]
}4.2 카테고리 상세 조회 📋 예정
http
GET /products/categories/:categoryId5. 장바구니 API 📋 전체 예정
5.1 장바구니 조회
http
GET /cartResponse 200 OK
json
{
"success": true,
"data": {
"items": [
{
"id": 1,
"product": {
"id": 1,
"name": "프리미엄 상품",
"thumbnailUrl": "https://...",
"price": 29000,
"salePrice": 25000
},
"options": [
{ "name": "색상", "value": "빨강" }
],
"quantity": 2,
"unitPrice": 25000,
"totalPrice": 50000
}
],
"summary": {
"totalItems": 2,
"subtotal": 50000,
"shippingFee": 3000,
"discount": 0,
"total": 53000
}
}
}5.2 장바구니 상품 추가
http
POST /cart/itemsRequest Body
json
{
"productId": 1,
"quantity": 2,
"options": [
{ "optionId": 1, "valueId": 1 }
]
}Response 201 Created
json
{
"success": true,
"data": {
"cartItemId": 1,
"message": "장바구니에 추가되었습니다"
}
}5.3 장바구니 상품 수량 변경
http
PATCH /cart/items/:cartItemIdRequest Body
json
{
"quantity": 3
}5.4 장바구니 상품 삭제
http
DELETE /cart/items/:cartItemId5.5 장바구니 비우기
http
DELETE /cart6. 주문 API
6.1 주문 생성 (결제 요청)
http
POST /ordersRequest Body
json
{
"items": [
{
"productId": 1,
"quantity": 2,
"options": [
{ "optionId": 1, "valueId": 1 }
]
}
],
"shippingAddressId": 1,
"couponCode": "SAVE10",
"usePoints": 1000,
"memo": "배송 전 연락 바랍니다"
}또는 장바구니에서 주문
json
{
"fromCart": true,
"cartItemIds": [1, 2, 3],
"shippingAddressId": 1
}Response 201 Created
json
{
"success": true,
"data": {
"orderId": 1,
"orderCode": "ORD-20250107-001",
"steppayOrderCode": "SP-12345",
"paymentUrl": "https://payment.steppay.kr/order/SP-12345",
"summary": {
"subtotal": 50000,
"shippingFee": 3000,
"discount": 5000,
"pointsUsed": 1000,
"total": 47000
},
"expiresAt": "2025-01-07T12:30:00.000Z"
}
}6.2 주문 목록 조회
http
GET /ordersQuery Parameters
| 파라미터 | 타입 | 설명 |
|---|---|---|
status | string | 주문 상태 (PENDING, PAID, SHIPPED 등) |
startDate | string | 시작일 (YYYY-MM-DD) |
endDate | string | 종료일 (YYYY-MM-DD) |
Response 200 OK
json
{
"success": true,
"data": [
{
"id": 1,
"orderCode": "ORD-20250107-001",
"status": "PAID",
"totalAmount": 47000,
"itemCount": 2,
"orderedAt": "2025-01-07T10:00:00.000Z",
"paidAt": "2025-01-07T10:05:00.000Z"
}
],
"meta": { ... }
}6.3 주문 상세 조회
http
GET /orders/:orderIdResponse 200 OK
json
{
"success": true,
"data": {
"id": 1,
"orderCode": "ORD-20250107-001",
"steppayOrderCode": "SP-12345",
"status": "PAID",
"items": [
{
"id": 1,
"product": {
"id": 1,
"name": "프리미엄 상품",
"thumbnailUrl": "https://..."
},
"options": [
{ "name": "색상", "value": "빨강" }
],
"quantity": 2,
"unitPrice": 25000,
"totalPrice": 50000,
"status": "PAID"
}
],
"shipping": {
"recipientName": "홍길동",
"phone": "010-1234-5678",
"address": "서울시 강남구 테헤란로 123",
"addressDetail": "아파트 101동 1001호",
"zipCode": "12345",
"memo": "배송 전 연락 바랍니다",
"trackingNumber": null,
"carrier": null,
"status": "PREPARING"
},
"payment": {
"method": "CARD",
"subtotal": 50000,
"shippingFee": 3000,
"discount": 5000,
"pointsUsed": 1000,
"totalAmount": 47000,
"paidAt": "2025-01-07T10:05:00.000Z"
},
"orderedAt": "2025-01-07T10:00:00.000Z"
}
}6.4 주문 취소
http
POST /orders/:orderId/cancelRequest Body
json
{
"reason": "단순 변심"
}Response 200 OK
json
{
"success": true,
"data": {
"orderId": 1,
"status": "CANCELLED",
"refundAmount": 47000,
"refundStatus": "PROCESSING"
}
}6.5 결제 상태 확인
http
GET /orders/:orderId/payment-statusResponse 200 OK
json
{
"success": true,
"data": {
"orderId": 1,
"paymentStatus": "COMPLETED",
"paidAt": "2025-01-07T10:05:00.000Z"
}
}7. 구독 API
7.1 내 구독 목록 조회
http
GET /subscriptionsResponse 200 OK
json
{
"success": true,
"data": [
{
"id": 1,
"steppaySubscriptionId": 12345,
"product": {
"id": 10,
"name": "프리미엄 멤버십"
},
"plan": {
"name": "월간 플랜",
"price": 9900,
"interval": 1,
"intervalUnit": "MONTH"
},
"status": "ACTIVE",
"currentPeriodStart": "2025-01-01T00:00:00.000Z",
"currentPeriodEnd": "2025-02-01T00:00:00.000Z",
"nextBillingDate": "2025-02-01T00:00:00.000Z",
"createdAt": "2025-01-01T00:00:00.000Z"
}
]
}7.2 구독 상세 조회
http
GET /subscriptions/:subscriptionIdResponse 200 OK
json
{
"success": true,
"data": {
"id": 1,
"steppaySubscriptionId": 12345,
"product": {
"id": 10,
"name": "프리미엄 멤버십",
"description": "월간 구독 서비스"
},
"plan": {
"name": "월간 플랜",
"price": 9900,
"interval": 1,
"intervalUnit": "MONTH"
},
"status": "ACTIVE",
"currentPeriodStart": "2025-01-01T00:00:00.000Z",
"currentPeriodEnd": "2025-02-01T00:00:00.000Z",
"nextBillingDate": "2025-02-01T00:00:00.000Z",
"paymentMethod": {
"type": "CARD",
"cardNumber": "**** **** **** 1234",
"cardBrand": "VISA"
},
"billingHistory": [
{
"id": 1,
"amount": 9900,
"status": "PAID",
"billedAt": "2025-01-01T00:00:00.000Z"
}
],
"createdAt": "2025-01-01T00:00:00.000Z"
}
}7.3 구독 신청
http
POST /subscriptionsRequest Body
json
{
"productId": 10,
"planId": 1
}Response 201 Created
json
{
"success": true,
"data": {
"subscriptionId": 1,
"steppayOrderCode": "SP-SUB-12345",
"paymentUrl": "https://payment.steppay.kr/order/SP-SUB-12345"
}
}7.4 구독 플랜 변경 📋 예정
http
PATCH /subscriptions/:subscriptionId/planRequest Body
json
{
"newPlanId": 2
}Response 200 OK
json
{
"success": true,
"data": {
"subscriptionId": 1,
"previousPlan": "월간 플랜",
"newPlan": "연간 플랜",
"effectiveDate": "2025-02-01T00:00:00.000Z",
"proratedAmount": -20000
}
}7.5 구독 일시정지
http
POST /subscriptions/:subscriptionId/pauseRequest Body
json
{
"resumeDate": "2025-03-01"
}Response 200 OK
json
{
"success": true,
"data": {
"subscriptionId": 1,
"status": "PAUSED",
"pausedAt": "2025-01-07T00:00:00.000Z",
"resumeDate": "2025-03-01T00:00:00.000Z"
}
}7.6 구독 재개
http
POST /subscriptions/:subscriptionId/resume7.7 구독 취소
http
POST /subscriptions/:subscriptionId/cancelRequest Body
json
{
"reason": "서비스 불만족",
"cancelImmediately": false
}Response 200 OK
json
{
"success": true,
"data": {
"subscriptionId": 1,
"status": "PENDING_CANCEL",
"cancelDate": "2025-02-01T00:00:00.000Z",
"message": "현재 구독 기간 종료 후 취소됩니다"
}
}7.8 결제수단 변경 URL 조회
http
GET /subscriptions/:subscriptionId/change-payment-methodResponse 200 OK
json
{
"success": true,
"data": {
"paymentMethodUpdateUrl": "https://payment.steppay.kr/payment-method/..."
}
}8. 웹훅 API
8.1 StepPay 웹훅 수신
http
POST /webhooks/steppay⚠️ StepPay 서버에서만 호출되는 엔드포인트
Headers
http
X-Steppay-Signature: {signature}
Content-Type: application/jsonResponse 200 OK
json
{
"received": true
}9. 관리자 API 📋 분리 예정
🔒 Admin 권한 필요
참고: 현재 관리자 기능은 일반 API (예:
POST /products)에서 SessionAuthGuard로 보호됩니다. 별도/admin/*경로 분리는 예정입니다.
9.1 상품 관리
http
POST /products # 상품 생성
GET /products # 상품 목록
GET /products/:productId # 상품 상세
GET /products/code/:productCode # 상품 코드로 조회
PUT /products/:productId # 상품 수정
PUT /products/:productId/status # 상품 상태 변경
DELETE /products/:productId # 상품 삭제상품 생성 요청
json
{
"name": "신규 상품",
"description": "상품 설명",
"content": "<p>상세 HTML</p>",
"price": 29000,
"salePrice": 25000,
"categoryId": 1,
"type": "NORMAL",
"status": "SALE",
"quantity": 100,
"options": [
{
"name": "색상",
"values": ["빨강", "파랑", "초록"]
}
],
"images": [
{ "url": "https://...", "order": 1 }
],
"syncToSteppay": true
}9.2 카테고리 관리 📋 예정
http
POST /products/categories # 카테고리 생성
PUT /products/categories/:id # 카테고리 수정
DELETE /products/categories/:id # 카테고리 삭제
PUT /products/categories/reorder # 순서 변경9.3 주문 관리
http
GET /admin/orders # 주문 목록
GET /admin/orders/:id # 주문 상세
PATCH /admin/orders/:id/status # 상태 변경
PATCH /admin/orders/:id/shipping # 배송 정보 업데이트
POST /admin/orders/:id/refund # 환불 처리배송 정보 업데이트
json
{
"status": "SHIPPED",
"carrier": "CJ대한통운",
"trackingNumber": "1234567890"
}9.4 회원 관리
http
GET /admin/users # 회원 목록
GET /admin/users/:id # 회원 상세
PATCH /admin/users/:id # 회원 수정
PATCH /admin/users/:id/status # 상태 변경 (정지/복구)9.5 구독 관리
http
GET /admin/subscriptions # 구독 목록
GET /admin/subscriptions/:id # 구독 상세
POST /admin/subscriptions/:id/cancel # 강제 취소9.6 대시보드
http
GET /admin/dashboard/summaryResponse
json
{
"success": true,
"data": {
"today": {
"orders": 50,
"revenue": 2500000,
"newUsers": 10
},
"thisMonth": {
"orders": 1200,
"revenue": 58000000,
"newUsers": 250
},
"activeSubscriptions": 500,
"pendingOrders": 25
}
}에러 코드 목록
인증 관련 (1000번대)
| 코드 | 메시지 |
|---|---|
| AUTH_001 | 인증 토큰이 필요합니다 |
| AUTH_002 | 인증 토큰이 만료되었습니다 |
| AUTH_003 | 유효하지 않은 토큰입니다 |
| AUTH_004 | 아이디 또는 비밀번호가 올바르지 않습니다 |
| AUTH_005 | 이미 사용 중인 아이디입니다 |
| AUTH_006 | 접근 권한이 없습니다 |
주문/결제 관련 (2000번대)
| 코드 | 메시지 |
|---|---|
| ORDER_001 | 주문을 찾을 수 없습니다 |
| ORDER_002 | 재고가 부족합니다 |
| ORDER_003 | 이미 취소된 주문입니다 |
| ORDER_004 | 결제 대기 시간이 초과되었습니다 |
| ORDER_005 | 취소할 수 없는 상태입니다 |
구독 관련 (3000번대)
| 코드 | 메시지 |
|---|---|
| SUB_001 | 구독을 찾을 수 없습니다 |
| SUB_002 | 이미 구독 중입니다 |
| SUB_003 | 일시정지할 수 없는 상태입니다 |
| SUB_004 | 취소할 수 없는 상태입니다 |
StepPay 연동 (9000번대)
| 코드 | 메시지 |
|---|---|
| STEPPAY_001 | StepPay API 연결 실패 |
| STEPPAY_002 | StepPay 인증 실패 |
| STEPPAY_003 | StepPay 주문 생성 실패 |
| STEPPAY_004 | StepPay 웹훅 검증 실패 |
최종 업데이트: 2026년 3월 16일