‼️ 업데이트 내용0. 접속하기/요청 URL계정figma(Tip)헤더에 토큰넣기1. 계정1.1 계정 만들기(구매자,POST)1.2 계정 만들기(판매자,POST)1.3 아이디 검증하기1.4 사업자등록번호 검증하기2. 로그인/로그아웃2.1 로그인2.2 로그아웃3. 상품3.1 상품 전체 불러오기(GET)3.1.1) 상품 전체 불러오기(GET)3.1.2) 판매자 상품 불러오기(GET)3.2 상품 등록하기(POST)3.3 상품 디테일(GET)3.4 상품 수정하기(PUT)3.5 상품 삭제하기(DELETE)3.6 상품 검색하기(GET)4. 장바구니4.1 장바구니 목록 보기(GET)4.2 장바구니에 물건 넣기(POST)4.3 장바구니 디테일(개발용,GET)4.4 장바구니 수량 수정하기(PUT)4.4 장바구니 전부 삭제하기(DELETE)4.4 장바구니 개별 삭제하기(DELETE)5. 주문하기1. 주문 목록 가져오기(GET)2. 주문 생성하기(POST)2-1. 주문 생성하기(POST)2-2. 카트에서 주문 생성하기(POST)2-3. 카트에서 하나만 주문 생성하기(POST)
‼️ 업데이트 내용
- 오픈마켓 서버 종료(24/10/10)
- 계정 검증하기 기능이 추가되었습니다. (22/8/31)
- 사업자 등록번호 검증하기 기능이 추가되었습니다. (22/9/13) 계정 검증하기 요청 URL이 변경되었습니다. (22/9/13)
- product list의
seller_store
가store_name
으로 변경되었습니다. (22/9/19)
- product를 수정할 때 전체 값이 아닌 필요한 값만 보내주시면 됩니다.(23/9/22)
- 23년 9월 22일부로 데이터베이스가 전체 초기화되었습니다.(23/9/22)
0. 접속하기/요청 URL
계정
- 구매자(buyer)
- ID : buyer1 PW: hodu0910
- ID : buyer2 PW: hodu0910
- ID : buyer3 PW: hodu0910
- 판매자(seller)
- ID : seller1 PW : hodu0910
- ID : seller2 PW : hodu0910
- ID : seller3 PW : hodu0910
figma
- 피그마 링크는 상단 페이지로 옮겨갔습니다.
(Tip)헤더에 토큰넣기
const instance = axios.create({ headers: { Authorization: 'JWT eyJ0eXAiOiJKV1Qi...' } });
key - Authorization value - JWT eyJ0eXAiOiJKV1Qi...(생략)

1. 계정
1.1 계정 만들기(구매자,POST)
- API
POST /accounts/signup/
- Req
{ "username": String, // 아이디 "password": String, "password2": String, "phone_number": String, // 전화번호는 010으로 시작하는 10~11자리 숫자 "name": String, // 이름 }
- 모든 필드는 필수로 작성해야 합니다.
- 비밀번호는 8자 이상, 영소문자를 포함해야 합니다.
- 핸드폰 번호는 010으로 시작하는 10~11자리 숫자로만 이루어져 있습니다.
- Res
// SUCCESS { "name": String, "phone_number": String, "type": String, "username": String, } // FAIL // username, password, password2, name, phone_number 중 하나라도 작성하지 않을 경우 이 필드는 필수 항목입니다. // password를 8자 이상 입력하지 않을 경우 비밀번호는 8자 이상이어야 합니다. // password에 영소문자가 없을 경우 비밀번호는 한개 이상의 영소문자가 필수적으로 들어가야 합니다. // password에 숫자가 없을 경우 비밀번호는 한개 이상의 숫자가 필수적으로 들어가야 합니다. // 가입된 username일 경우 해당 사용자 아이디는 이미 존재합니다. // username에 지정된 문자 이외의 문자가 들어갈 경우 ID는 20자 이내의 영어 소문자, 대문자, 숫자만 가능합니다.' // 가입된 phone_number일 경우 해당 사용자 전화번호는 이미 존재합니다. // 핸드폰번호가 양식에 맞지 않을 경우 핸드폰번호는 01*으로 시작해야 하는 10~11자리 숫자여야 합니다.
1.2 계정 만들기(판매자,POST)
- API
POST /accounts/signup_seller/
- Req
// SUCCESS { "username": String, // 아이디 "password": String, "password2": String, "phone_number": String, // 전화번호는 010으로 시작하는 10~11자리 숫자 "name": String, // 이름 "company_registration_number": String, "store_name": String, }
- 모든 필드는 필수로 작성해야 합니다.
- 비밀번호는 8자 이상, 영소문자를 포함해야 합니다.
- 핸드폰 번호는 010으로 시작하는 10~11자리 숫자로만 이루어져 있습니다.
- 사업자등록번호는 10자리로 이루어진 숫자입니다.
- 이름(name)은 중복될 수 있습니다.
- 스토어이름(store_name)은 중복될 수 없습니다.
- Res
// SUCCESS { "name": String, "phone_number": String, "type": String, "username": String, "company_registration_number": String, "store_name": String, } // FAIL // username, password, password2, name, phone_number 중 하나라도 작성하지 않을 경우 이 필드는 blank일 수 없습니다. // password를 8자 이상 입력하지 않을 경우 비밀번호는 8자 이상이어야 합니다. // password에 영소문자가 없을 경우 비밀번호는 한개 이상의 영소문자가 필수적으로 들어가야 합니다. // password에 숫자가 없을 경우 비밀번호는 한개 이상의 숫자가 필수적으로 들어가야 합니다. // 가입된 username일 경우 해당 사용자 아이디는 이미 존재합니다. // username에 지정된 문자 이외의 문자가 들어갈 경우 ID는 20자 이내의 영어 소문자, 대문자, 숫자만 가능합니다.' // 가입된 phone_number일 경우 해당 사용자 전화번호는 이미 존재합니다. // 핸드폰번호가 양식에 맞지 않을 경우 핸드폰번호는 01*으로 시작해야 하는 10~11자리 숫자여야 합니다. // 사업자등록번호가 이미 있을 경우 해당 사업자등록번호는 이미 존재합니다. // 스토어 이름이 이미 있을 경우 해당 스토어이름은 이미 존재합니다.
1.3 아이디 검증하기
- API
POST /accounts/signup/valid/username/
- Req
{ "username": String }
- Res
// username 필드를 입력하지 않았거나 비어있을 경우 "FAIL_Message": "username 필드를 추가해주세요 :)" // 중복아이디가 없을 경우 "Success": "멋진 아이디네요 :)" // 중복아이디가 있을 경우 "FAIL_Message": "이미 사용 중인 아이디입니다."
1.4 사업자등록번호 검증하기
- API
POST /accounts/signup/valid/company_registration_number/
- Req
{ "company_registration_number": String }
- Res
// username 필드를 입력하지 않았거나 비어있을 경우 "FAIL_Message": "company_registration_number 필드를 추가해주세요 :)" // 중복아이디가 없을 경우 "Success": "사용 가능한 사업자등록번호입니다." // 중복아이디가 있을 경우 "FAIL_Message": "이미 등록된 사업자등록번호입니다."
2. 로그인/로그아웃
2.1 로그인
로그인 유형별로 로그인됩니다. 로그인 요청을 보낼 때 login_type도 함께 보내야 합니다.
- API
POST /accounts/login/
- Req
{ "username": String, "password": String, "login_type": String // BUYER : 일반 구매자, SELLER : 판매자 }
*username, password은 필수로 작성해야 합니다.
- Res
// SUCCESS { "product_id": Int, "token": String } // FAIL { "username": [ "이 필드는 필수 항목입니다." ], "password": [ "이 필드는 필수 항목입니다." ] "login_type": [ "이 필드는 필수 항목입니다." ] } // 아이디 및 비밀번호가 틀렸을 때 { "message": "로그인 정보가 없습니다." } // 로그인을 요청한 사용자의 정보와 사용자 유형이 다를 경우 { "message": "로그인 정보가 없습니다. 로그인 유형을 학인해주세요." }
*token으로 인증합니다.
2.2 로그아웃
- API
POST /accounts/logout/
- Res
{ "detail": "로그아웃되었습니다." }
3. 상품
3.1 상품 전체 불러오기(GET)
3.1.1) 상품 전체 불러오기(GET)
- API
GET /products/
- Res
// SUCCESS { "count": Int, "next": String, "previous": String, "results": [ { "product_id": Int, "product_name": String, "seller": Int, "store_name": String, "image": String, "price": Int, "shipping_method": String, //parcel: 택배발송, delivery: 직접전달 중 선택 1 "shipping_fee": Int, "stock": Int, "products_info": String, }] } // product가 없을 경우 { "count": 0, "next": null, "previous": null, "results": [] }
3.1.2) 판매자 상품 불러오기(GET)
- API
GET /seller/
- Res
// SUCCESS { "count": Int, "next": String, "previous": String, "results": [ { "product_id": Int, "product_name": String, "seller": Int, "store_name": String, "image": String, "price": Int, "shipping_method": String, //"PARCEL" or "DELIVERY" "shipping_fee": Int, "stock": Int, "products_info": String, }] } // product가 없을 경우 { "count": 0, "next": null, "previous": null, "results": [] }
3.2 상품 등록하기(POST)
- user 중 “seller”만 요청을 보내줄 수 있습니다.
- API
POST /products/
- Req
{ "product_name": String, "image": 이미지 파일(*.jpg, *.gif, *.png), "price": Int, "shipping_method": String, // PARCEL 또는 DELIVERY 선택 "shipping_fee": Int, "stock": Int, "product_info": String, }
- Res
// header -> 토큰이 있어야 함 Authorization: JWT 토큰 // SUCCESS { "count": Int, "next": String, "previous": String, "results": [ { "product_id": Int, "created_at": String, "updated_at": String, "product_name": String, "image": String, "price": Int, "shipping_method": String, // PARCEL 또는 DELIVERY 선택 "shipping_fee": Int, "stock": Int, "products_info": String, "seller": Int }] } // FAIL : token이 없을 경우 { "detail": "자격 인증데이터(authentication credentials)가 제공되지 않았습니다." } // FAIL : 필드가 비었을 경우 { "product_name": [ "이 필드는 blank일 수 없습니다." ], // image 파일이 없을 경우 "image": [ "제출된 데이터는 파일이 아닙니다. 제출된 서식의 인코딩 형식을 확인하세요." ], "price": [ "유효한 정수(integer)를 넣어주세요." ], "shipping_fee": [ "유효한 정수(integer)를 넣어주세요." ], "stock": [ "유효한 정수(integer)를 넣어주세요." ], "products_info": [ "이 필드는 blank일 수 없습니다." ] }
3.3 상품 디테일(GET)
- API
GET /products/<int:product_id>/ 예제 : /products/1/
- Res
// SUCCESS { "product_id": Int, "created_at": String, "updated_at": String, "product_name": String, "image": String, "price": Int, "shipping_method": String, //string, 선택 "shipping_fee": Int, "stock": Int, "products_info": String, "seller": Int, "store_name": String } // FAIL { "detail": "찾을 수 없습니다." }
3.4 상품 수정하기(PUT)
- API
PUT /products/<int:product_id>/
- Req
- 수정이 필요한 값들만 넣어주면 됩니다. 값을 넣지 않을경우 이전에 저장된 값들이 그대로 저장됩니다.
// header -> 토큰이 있어야 함 Authorization: JWT 토큰 // Body { "product_name": String, "price": Int, "shipping_method": String, "shipping_fee": Int, "stock": Int, "products_info": String }
- Res
// SUCCESS { "product_id": Int, "created_at": String, "updated_at": String, "product_name": String, "image": String, "price": Int, "shipping_method": String, //string, 선택 "shipping_fee": Int, "stock": Int, "product_info": String, "seller": Int } // FAIL { "product_name": [ "이 필드는 blank일 수 없습니다." ], // image 파일이 없을 경우 "image": [ "제출된 데이터는 파일이 아닙니다. 제출된 서식의 인코딩 형식을 확인하세요." ], "price": [ "유효한 정수(integer)를 넣어주세요." ], "shipping_fee": [ "유효한 정수(integer)를 넣어주세요." ], "stock": [ "유효한 정수(integer)를 넣어주세요." ], "product_info": [ "이 필드는 blank일 수 없습니다." ] }
3.5 상품 삭제하기(DELETE)
- API
DELETE /products/<int:product_id>/
- Res
// header -> 토큰이 있어야 함 Authorization: JWT 토큰 // body // SUCCESS { "detail": "상품이 삭제되었습니다." }
3.6 상품 검색하기(GET)
- API
GET /products/?search=입력값
입력값 필드에 원하는 값을 넣으면 됩니다.
4. 장바구니
- 아래 설명은 가볍게 읽어주세요. 이해가 가지 않으셔도 됩니다.

- 장바구니는 buyer만 접근할 수 있습니다.
- (참고)개인별 장바구니가 있고(Cart), 그 안에 CartItem을 넣어주는 형태. cart는 한번만 생성되지만 cartItem은 요청될 때 마다 생성됨.
- (참고)장바구니 기본 로직 : user(buyer)에 대한 개인 Cart가 할당되며 이 Cart안에 CartItem(product, 수량, is_active 정보가 담겨있음)을 넣습니다.
- (참고) my_cart는 CartItem에서 접근할 수 있는 Cart의 pk값입니다. cart_item_id는 상품을 카트에 담을 때 마다 생성되는 pk 값
4.1 장바구니 목록 보기(GET)
- API
GET /cart/
- Req
// header -> 토큰이 있어야 함 Authorization: `JWT ${토큰}`
- Res
// SUCCESS { "count": Int, "next": String, "previous": String, "results": [ { "my_cart": Int, // 카트 고유번호, User가 바뀌지 않는이상 번호가 바뀌지 않음 "cart_item_id": Int, // cartItem의 고유번호, 요청시마다 번호가 바뀜 "product_id": Int, // 상품 아이디 "quantity": Int // 장바구니에 담긴 상품의 개수 "is_active": Bool // 장바구니 내 상품 활성화 버튼, 같이 보내지 않으면 False } ] } // 장바구니에 상품이 없을 경우 { "count": 0, "next": null, "previous": null, "results": [] }
4.2 장바구니에 물건 넣기(POST)
장바구니에 이미 있는경우에도 POST요청을 보내줍니다.(백엔드에서 이미 있으면 재고와 현재 요청 수량을 체크하고, 요청 수량이 재고를 넘을 경우 에러를 보내줍니다.)
- API
POST /cart/
- Req
// header -> 토큰이 있어야 함 Authorization: JWT 토큰 //body { "product_id": Int, //product의 id 값을 넣어주면 됩니다. "quantity": Int }
- Res
{ "my_cart": Int, // 내 카트 고유번호 "cart_item_id": Int, // 카트 아이템 번호/ PUT,DELETE 메소드를 사용하기 위해 필요함 "product_id": Int, "quantity": Int }
4.3 장바구니 디테일(개발용,GET)
- API
GET /cart/<int:cart_item_id>/
- Res
// SUCCESS { "my_cart": Int, "cart_item_id": Int, "product_id": Int, "quantity": Int } // FAIL : buyer가 아니거나 token이 없을 경우 { "detail": "자격 인증데이터(authentication credentials)가 제공되지 않았습니다." } // FAIL : user가 다를 경우 { "detail": "접근권한이 없습니다." } // FAIL : 해당 pk값이 없을 경우 { "detail": "찾을 수 없습니다." }
4.4 장바구니 수량 수정하기(PUT)
- API
PUT /cart/<int:cart_item_id>/
- Req
// header -> 토큰이 있어야 함 Authorization: JWT 토큰 //body { "product_id": Int, "quantity": Int, "is_active": Bool // 장바구니 내 상품 활성화 버튼, 같이 보내지 않으면 False }
- Res
{ "product_id": Int, "quantity": Int, "is_active": Bool } // FAIL // is_active 값이 없을 때 { "detail": "is_active 값이 없습니다." } // is_active 값이 bool이 아닐 때 { "is_active": [ "Must be a valid boolean." ] }
4.4 장바구니 전부 삭제하기(DELETE)
- API
DELETE /cart/
- Res
// SUCCESS { "detail": "장바구니의 모든 상품이 삭제되었습니다." }
4.4 장바구니 개별 삭제하기(DELETE)
- API
DELETE /cart/<int:cart_item_id>/
- Res
// SUCCESS { "detail": "장바구니의 상품이 삭제되었습니다." } // FAIL
5. 주문하기
주문하기는 세가지 방법으로 나뉩니다.
- 바로 주문하기(product detail 페이지에서 접근)
- 카트에서 주문하기(cart에서 is_active = True인 값만 주문)
- 카트에서 한가지만 주문하기(장바구니 페이지에서 주문하기 버튼 누를 경우)
이 세가지 분기를 처리해주기 위해서
order_kind
를 서버에 보내주셔야 합니다.direct_order
cart_order
cart_one_order
1. 주문 목록 가져오기(GET)
- API
GET /order/
- Req
// header -> buyer 토큰이 있어야 함 Authorization: JWT 토큰
- Res
// SUCCESS { "count": Int, "next": null, "previous": null, "results": [ { "buyer": Int, // 구매자(로그인 된 유저) "order_number": Int, // 주문번호 "order_items": [ // 구매 상품들 Int, Int, ], "order_quantity": [ // 구매 상품들의 수량 Int, Int, ], "receiver": String, // 받는사람 "receiver_phone_number": String, // 받는사람의 핸드폰번호 "address": String, // 주소 "address_message": String, // 배송메세지 "payment_method": String, // 배송방법 "total_price": Int // 결제금액 } ] } // 값이 없을 떄 { "count": 0, "next": null, "previous": null, "results": [] }
2. 주문 생성하기(POST)
2-1. 주문 생성하기(POST)
참고
>>> myList = [1,2,3,4,5,'hello'] >>> import simplejson as json >>> myJsonList = json.dumps(myList) >>> myJsonList '[1, 2, 3, 4, 5, "hello"]' >>> myJsonList.__class__ <type 'str'> >>> jsonDec = json.decoder.JSONDecoder() >>> myPythonList = jsonDec.decode(myJsonList) >>> myPythonList [1, 2, 3, 4, 5, u'hello'] >>> myPythonList.__class__ <type 'list'>
- API
POST /order/
- Req
{ "product_id": Int, "quantity" : Int, "order_kind" : String, // 바로주문하기일 경우에는 direct_order여야 합니다. "reciever": String, "reciever_phone_number": String, "address": String, "address_message": String, "payment_method": String, //CARD, DEPOSIT, PHONE_PAYMENT, NAVERPAY, KAKAOPAY 중 하나 선택 "total_price": Int // 총 금액(total_price)은 자동계산되나, 유효성검사를 위해 받아와야 합니다. }
- Res
// SUCCESS { "buyer": Int, "order_number": Int, "order_items": [ Int, ], "receiver": String, "receiver_phone_number": String, "address": String, "address_message": String, "payment_method": String, "total_price": Int, "order_quantity": [ Int ], "delivery_status": String } // 값이 없을 떄 { "count": 0, "next": null, "previous": null, "results": [] } // product_id 정보가 없을 때 { "FAIL_message": "product_id 정보가 없습니다." } // quantity 정보가 없을 떄 { "FAIL_message": "quantity 정보가 없습니다." } // 총 금액이 백엔드에서 계산한 것과 다를 때 { "FAIL_message": "total_price 금액이 맞지 않습니다. 백엔드에서 계산한 금액은 __원 입니다." } // 총 금액이 백엔드에서 계산한 것과 다를 때 { "FAIL_message": "total_price 금액이 맞지 않습니다. 백엔드에서 계산한 금액은 __원 입니다." }
2-2. 카트에서 주문 생성하기(POST)
참고
>>> myList = [1,2,3,4,5,'hello'] >>> import simplejson as json >>> myJsonList = json.dumps(myList) >>> myJsonList '[1, 2, 3, 4, 5, "hello"]' >>> myJsonList.__class__ <type 'str'> >>> jsonDec = json.decoder.JSONDecoder() >>> myPythonList = jsonDec.decode(myJsonList) >>> myPythonList [1, 2, 3, 4, 5, u'hello'] >>> myPythonList.__class__ <type 'list'>
카트로 보내기 전 카트의 각 quantity가 product의 재고보다 많지 않은지 유효성 검사를 해주셔야 합니다.
ex) product 9번의 재고가 10개인데 카트에 담긴 재고는 15개임 → 에러 (카트 수량과 재고 검사가 주기적으로 확인이 가능하다면 이 유효성검사는 무시하셔도 됩니다.)
- API
POST /order/
- Req
{ "total_price": Int // cart에 담긴 총 금액(수량*가격+배송비)을 보내줘야 합니다. "order_kind" : String // 카트에서 주문할 경우에는 cart_order를 보내줘야 합니다. "receiver": String, "receiver_phone_number": String, // 01012341234 와 같은 형태로 보내야 합니다. "address": String, "address_message": String, "payment_method": String, //CARD, DEPOSIT, PHONE_PAYMENT, NAVERPAY, KAKAOPAY 중 하나 선택 }
- Res
// SUCCESS { "buyer": Int, "order_number": Int, "order_items": [ Int, Int, ], "receiver": String, "receiverr_phone_number": String, "address": String, "address_message": String, "payment_method": String, "total_price": Int, "order_quantity": [ Int, Int, ], "delivery_status": String } // FAIL // 총 금액이 백엔드에서 계산한 것과 다를 때 { "FAIL_message": "total_price 금액이 맞지 않습니다. 백엔드에서 계산한 금액은 __원 입니다." } // total_price 정보가 없을 때 { "FAIL_message": "total_price 정보가 없습니다." } // 품절된 상품이 있을 때 { "FAIL_message":"품절된 상품이 있습니다. 다시 주문해주세요" } // order_items와 order_quantity의 개수가 맞지 않을 때 { "FAIL_message":"카트내 제품 개수와 수량 개수가 맞지 않습니다. 다시 요청해주세요." }
2-3. 카트에서 하나만 주문 생성하기(POST)
참고
>>> myList = [1,2,3,4,5,'hello'] >>> import simplejson as json >>> myJsonList = json.dumps(myList) >>> myJsonList '[1, 2, 3, 4, 5, "hello"]' >>> myJsonList.__class__ <type 'str'> >>> jsonDec = json.decoder.JSONDecoder() >>> myPythonList = jsonDec.decode(myJsonList) >>> myPythonList [1, 2, 3, 4, 5, u'hello'] >>> myPythonList.__class__ <type 'list'>
해당 경우에는
is_active
즉, 선택한 아이템의 상태값이 False
일 경우도 생각해야 합니다.(백엔드에서
is_active
값이 False
인 제품의 정보를 불러올 수 없도록 구현되어 있어요.)
→ 만약 주문할 제품의 is_active
값이 False
인데 주문하기를 누른다면?
: 이 경우를 생각해서 구현해주세요!힌트(스포가 될 수 있으니 ,, 생각해보고 눌러주세요)
is_active 값을 주문하기 버튼을 누르는 순간 True로 PUT..
- API
POST /order/
- Req
{ "product_id": Int, "quantity" : Int, "order_kind" : String // 카트에서 주문할 경우에는 cart_one_order를 보내줘야 합니다. "total_price": Int // cart에 담긴 총 금액(수량*가격+배송비)을 보내줘야 합니다. "receiver": String, "receiver_phone_number": String, // 01012341234 와 같은 형태로 보내야 합니다. "address": String, "address_message": String, "payment_method": String, //CARD, DEPOSIT, PHONE_PAYMENT, NAVERPAY, KAKAOPAY 중 하나 선택 }
- Res
// SUCCESS { "buyer": Int, "order_number": Int, "order_items": [ Int, Int, ], "receiver": String, "receiver_phone_number": String, "address": String, "address_message": String, "payment_method": String, "total_price": Int, "order_quantity": [ Int, Int, ], "delivery_status": String } // FAIL // 총 금액이 백엔드에서 계산한 것과 다를 때 { "FAIL_message": "total_price 금액이 맞지 않습니다. 백엔드에서 계산한 금액은 __원 입니다." } // total_price 정보가 없을 때 { "FAIL_message": "total_price 정보가 없습니다." } // product_id 정보가 없을 때 { "FAIL_message": "product_id 정보가 없습니다." } // quantity 정보가 없을 떄 { "FAIL_message": "quantity 정보가 없습니다." } // 품절된 상품이 있을 때 { "FAIL_message":"품절된 상품이 있습니다. 다시 주문해주세요" } // order_items와 order_quantity의 개수가 맞지 않을 때 { "FAIL_message":"카트내 제품 개수와 수량 개수가 맞지 않습니다. 다시 요청해주세요." } // 카트안에 보낸 아이템 정보가 없을 때 { "FAIL_message": "카트안에 해당 아이템 정보가 없습니다." }