Skip to content

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": "인증 토큰이 만료되었습니다"
  }
}

공통 쿼리 파라미터

파라미터타입설명
pagenumber페이지 번호 (기본: 1)
limitnumber페이지당 항목 수 (기본: 20, 최대: 100)
sortstring정렬 기준 (예: createdAt:desc)

1. 인증 API

1.1 아이디 중복 체크

http
GET /auth/check-username?username=user@example.com

Query Parameters

파라미터타입필수설명
usernamestringO확인할 아이디(이메일)

Response 200 OK

json
{
  "success": true,
  "data": {
    "available": true,
    "message": "사용 가능한 아이디입니다"
  }
}

1.2 회원가입

http
POST /auth/register

Request 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"
}
필드타입필수설명
usernamestringO로그인 아이디 (이메일 형식 권장)
emailstringO이메일
passwordstringO비밀번호 (8자 이상)
namestringO이름
phonestringX전화번호
marketingSmsbooleanXSMS 마케팅 동의
marketingEmailbooleanX이메일 마케팅 동의
marketingKakaobooleanX카카오 마케팅 동의
countryCodestringX국가 코드 (기본: KR)

Response 201 Created

json
{
  "success": true,
  "data": {
    "customerId": 12345,
    "customerCode": "customer_abc123",
    "username": "user@example.com",
    "name": "홍길동"
  }
}

1.3 로그인

http
POST /auth/login

Request 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/logout

Headers: Authorization: Bearer {access_token}

Response 200 OK

json
{
  "success": true,
  "message": "로그아웃 되었습니다"
}

1.5 비밀번호 재설정 요청 📋 예정

http
POST /auth/password/reset-request

Request Body

json
{
  "email": "user@example.com"
}

Response 200 OK

json
{
  "success": true,
  "message": "비밀번호 재설정 이메일이 발송되었습니다"
}

1.6 비밀번호 재설정 📋 예정

http
POST /auth/password/reset

Request Body

json
{
  "token": "reset-token-from-email",
  "newPassword": "NewPassword123!"
}

Response 200 OK

json
{
  "success": true,
  "message": "비밀번호가 변경되었습니다"
}

2. 회원 API

2.1 내 정보 조회

http
GET /users/me

Response 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/me

Request 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/password

Request Body

json
{
  "currentPassword": "OldPassword123!",
  "newPassword": "NewPassword123!"
}

Response 200 OK

json
{
  "success": true,
  "message": "비밀번호가 변경되었습니다"
}

2.4 배송지 목록 조회 📋 예정

http
GET /users/me/addresses

Response 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/addresses

Request 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/:addressId

2.7 배송지 삭제 📋 예정

http
DELETE /users/me/addresses/:addressId

2.8 회원 삭제

http
DELETE /users/:id

🔒 관리자(ADMIN) 권한 필요

Response 200 OK

json
{
  "success": true,
  "message": "회원 삭제가 완료되었습니다"
}

3. 상품 API

3.1 상품 목록 조회

http
GET /products

Query Parameters

파라미터타입설명
categoryIdnumber카테고리 ID
searchstring검색어
minPricenumber최소 가격
maxPricenumber최대 가격
typestring상품 유형 (NORMAL, SUBSCRIPTION)
statusstring상태 (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/:productId

Response 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/subscriptions

Response 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/categories

Query Parameters

파라미터타입설명
parentIdnumber상위 카테고리 ID (미지정 시 최상위 카테고리)
treeboolean트리 구조로 반환 (기본: 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/:categoryId

5. 장바구니 API 📋 전체 예정

5.1 장바구니 조회

http
GET /cart

Response 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/items

Request 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/:cartItemId

Request Body

json
{
  "quantity": 3
}

5.4 장바구니 상품 삭제

http
DELETE /cart/items/:cartItemId

5.5 장바구니 비우기

http
DELETE /cart

6. 주문 API

6.1 주문 생성 (결제 요청)

http
POST /orders

Request 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 /orders

Query Parameters

파라미터타입설명
statusstring주문 상태 (PENDING, PAID, SHIPPED 등)
startDatestring시작일 (YYYY-MM-DD)
endDatestring종료일 (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/:orderId

Response 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/cancel

Request 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-status

Response 200 OK

json
{
  "success": true,
  "data": {
    "orderId": 1,
    "paymentStatus": "COMPLETED",
    "paidAt": "2025-01-07T10:05:00.000Z"
  }
}

7. 구독 API

7.1 내 구독 목록 조회

http
GET /subscriptions

Response 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/:subscriptionId

Response 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 /subscriptions

Request 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/plan

Request 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/pause

Request 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/resume

7.7 구독 취소

http
POST /subscriptions/:subscriptionId/cancel

Request 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-method

Response 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/json

Response 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/summary

Response

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_001StepPay API 연결 실패
STEPPAY_002StepPay 인증 실패
STEPPAY_003StepPay 주문 생성 실패
STEPPAY_004StepPay 웹훅 검증 실패

최종 업데이트: 2026년 3월 16일