- wholesale 패키지 연동 (SooinSession, GeoYoungSession) - Flask Blueprint 분리 (sooin_api.py, geoyoung_api.py) - order_context 스키마 확장 (wholesaler_id, internal_code 등) - 수인약품 개별 취소 기능 (cancel_item, restore_item) - 문서 추가: WHOLESALE_API_INTEGRATION.md - 테스트 스크립트들
6.9 KiB
6.9 KiB
수인약품 API 리버스 엔지니어링 문서
개요
수인약품 웹 주문 시스템의 API 구조를 분석한 문서입니다. 지오영 API와 같은 하이브리드 방식 (Playwright 로그인 → requests 직접 호출)으로 구현합니다.
기본 정보
- Base URL:
http://sooinpharm.co.kr - 인코딩: EUC-KR (한글 파라미터 인코딩 시 주의)
- 거래처 코드:
50911(청춘약국) - 세션 관리: 쿠키 기반 (ASP 세션)
1. 로그인
로그인 페이지
- URL:
/Homepage/intro.asp - Method: POST (JavaScript 함수
chkLogin()호출)
필드
| 필드명 | 설명 | 예시 |
|---|---|---|
| tx_id | 아이디 | thug0bin |
| tx_pw | 비밀번호 | @Trajet6640 |
인증 쿠키
로그인 성공 시 ASP 세션 쿠키가 발급됨:
ASPSESSIONID*(세션 ID)
로그인 성공 확인
- 로그인 후 페이지에 "로그아웃" 링크 존재 여부로 확인
- 로그인 후 자동으로
/Service/Order/Order.asp로 리다이렉트
2. 제품 검색 API
URL
GET /Service/Order/Order.asp
파라미터
| 파라미터 | 필수 | 설명 | 값 예시 |
|---|---|---|---|
| so | N | 제품분류 | 0=전체, 1=전문, 2=일반 |
| so2 | N | 주문분류 | 0=전체, 1=다빈도, 2=관심, 3=재주문 |
| so3 | N | 검색타입 | 1=제품명, 2=KD코드, 3=표준코드 |
| tx_maker | N | 제조사 | 한독 |
| tx_physic | N | 검색어 | 073100220 (KD코드) |
| tx_ven | Y | 거래처코드 | 50911 |
| currVenNm | Y | 약국명 | 청춘약국 (URL인코딩) |
| sDate | N | 시작일 | 20260306 |
| eDate | N | 종료일 | 20260306 |
| sa | N | 정렬 | phy=제품명순, ven=제조사순 |
| Page | N | 페이지번호 | 1 |
| tx_StockLoc | N | 재고위치 | '00001' |
| df | N | 기간필터 | t=3개월 |
KD코드 검색 예시 URL
/Service/Order/Order.asp?so=0&so2=0&so3=2&tx_physic=073100220&tx_ven=50911&currVenNm=%EC%B2%AD%EC%B6%98%EC%95%BD%EA%B5%AD&sDate=20260306&eDate=20260306&df=t
응답 (HTML)
HTML 테이블 형식으로 반환. BeautifulSoup로 파싱 필요.
테이블 구조
<tr class="ln_physic">
<td>073100220</td> <!-- KD코드 -->
<td>한국오가논</td> <!-- 제조사 -->
<td>
<a href="./PhysicInfo.asp?pc=32495&...">
(오가논)코자정 50mg(PTP)
</a>
</td> <!-- 제품명 (pc=내부코드) -->
<td>30T</td> <!-- 규격 -->
<td>보험전문</td> <!-- 구분 -->
<td>14,220</td> <!-- 단가 -->
<td>238</td> <!-- 재고 -->
<td>
<input name="qty_0"> <!-- 수량입력 -->
<input type="hidden" name="pc_0" value="32495"> <!-- 내부코드 -->
<input type="hidden" name="stock_0" value="238">
<input type="hidden" name="price_0" value="14220">
</td>
</tr>
핵심 필드 추출
- KD코드: 첫 번째 td
- 제조사: 두 번째 td
- 제품명: 세 번째 td의 a 태그 텍스트
- 내부코드(pc): a 태그 href에서
pc=xxxxx추출 - 규격: 네 번째 td
- 단가: 여섯 번째 td (콤마 제거 후 int)
- 재고: 일곱 번째 td
3. 장바구니 추가 API
URL
POST /Service/Order/BagOrder.asp
Content-Type
application/x-www-form-urlencoded
파라미터 (각 제품당)
| 파라미터 | 설명 | 예시 |
|---|---|---|
| qty_N | 수량 | 1 |
| pc_N | 내부 제품코드 | 32495 |
| stock_N | 현재 재고 | 238 |
| saleqty_N | 판매수량 | 0 |
| price_N | 단가 | 14220 |
| soldout_N | 품절여부 | N |
| ordunitqty_N | 주문단위수량 | 1 |
| bidqty_N | 입찰수량 | 0 |
| outqty_N | 출고수량 | 0 |
| overqty_N | 초과수량 | 0 |
| manage_N | 관리여부 | N |
| prodno_N | 제품번호 | (빈값) |
| termdt_N | 종료일자 | (빈값) |
N은 0부터 시작하는 행 인덱스
요청 예시
qty_0=1&pc_0=32495&stock_0=238&saleqty_0=0&price_0=14220&soldout_0=N&ordunitqty_0=1&bidqty_0=0&outqty_0=0&overqty_0=0&manage_0=N&prodno_0=&termdt_0=
응답
HTML (장바구니 iframe 내용)
4. 장바구니 비우기 API
URL
GET /Service/Order/BagOrder.asp?kind=del&currVenCd=50911&currMkind=&currRealVenCd=
파라미터
| 파라미터 | 설명 | 값 |
|---|---|---|
| kind | 동작 | del |
| currVenCd | 거래처코드 | 50911 |
| currMkind | 종류 | (빈값) |
| currRealVenCd | 실제거래처코드 | (빈값) |
5. 장바구니 조회 API
URL
GET /Service/Order/BagOrder.asp?currVenCd=50911
응답 (HTML)
<table class="tbl_list">
<tr>
<td>건별취소</td>
<td>제품명</td>
<td>수량</td>
<td>금액</td>
</tr>
<tr>
<td><a href="...">X</a></td>
<td>(오가논)코자정 50mg(PTP)</td>
<td>1</td>
<td>14,220</td>
</tr>
</table>
<div>
<dt>주문품목</dt><dd>1개</dd>
<dt>주문금액</dt><dd>14,220원</dd>
</div>
6. 주문 전송 API
URL (추정)
POST /Service/Order/BagOrder.asp
파라미터
| 파라미터 | 설명 |
|---|---|
| kind | order (추정) |
| memo | 주문메모 |
| currVenCd | 거래처코드 |
실제 주문 전송은 iframe 내 버튼 클릭으로 수행됨 정확한 API 파라미터는 추가 분석 필요
7. 제품 상세 정보 API
URL
GET /Service/Order/PhysicInfo.asp
파라미터
| 파라미터 | 설명 | 예시 |
|---|---|---|
| pc | 내부제품코드 | 32495 |
| ln | 행번호 | 0 |
| currVenCd | 거래처코드 | 50911 |
| currLoc | 재고위치 | '00001' |
구현 전략
지오영 API 패턴 적용
-
Playwright 로그인
- 초기 로그인만 Playwright 사용
- 쿠키 획득 후 requests 세션에 복사
- 세션 30분 유효 (재로그인 필요 시 자동 갱신)
-
requests 직접 호출
- 검색: GET /Service/Order/Order.asp
- 장바구니 추가: POST /Service/Order/BagOrder.asp
- 장바구니 비우기: GET /Service/Order/BagOrder.asp?kind=del
- 장바구니 조회: GET /Service/Order/BagOrder.asp
-
HTML 파싱
- BeautifulSoup 사용
- 테이블 행에서 제품 정보 추출
- 내부코드(pc) 추출 (장바구니 추가용)
예상 성능
- 기존 Playwright: ~30초/주문
- requests 직접 호출: ~1초/주문
주의사항
-
EUC-KR 인코딩
- 한글 파라미터는 EUC-KR로 인코딩
urllib.parse.quote(text.encode('euc-kr'))
-
세션 관리
- ASP 세션 쿠키 유지 필수
- 장시간 미사용 시 세션 만료
-
동시 접속
- 동일 계정 동시 접속 시 세션 충돌 가능
-
재고 실시간성
- 검색 시점의 재고 정보
- 주문 전 재고 재확인 권장
작성일
- 2026-03-06
- 리버스 엔지니어링 by Claude