- 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 - 테스트 스크립트들
278 lines
6.9 KiB
Markdown
278 lines
6.9 KiB
Markdown
# 수인약품 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로 파싱 필요.
|
|
|
|
#### 테이블 구조
|
|
```html
|
|
<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)
|
|
```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 패턴 적용
|
|
|
|
1. **Playwright 로그인**
|
|
- 초기 로그인만 Playwright 사용
|
|
- 쿠키 획득 후 requests 세션에 복사
|
|
- 세션 30분 유효 (재로그인 필요 시 자동 갱신)
|
|
|
|
2. **requests 직접 호출**
|
|
- 검색: GET /Service/Order/Order.asp
|
|
- 장바구니 추가: POST /Service/Order/BagOrder.asp
|
|
- 장바구니 비우기: GET /Service/Order/BagOrder.asp?kind=del
|
|
- 장바구니 조회: GET /Service/Order/BagOrder.asp
|
|
|
|
3. **HTML 파싱**
|
|
- BeautifulSoup 사용
|
|
- 테이블 행에서 제품 정보 추출
|
|
- 내부코드(pc) 추출 (장바구니 추가용)
|
|
|
|
### 예상 성능
|
|
- 기존 Playwright: ~30초/주문
|
|
- requests 직접 호출: **~1초/주문**
|
|
|
|
---
|
|
|
|
## 주의사항
|
|
|
|
1. **EUC-KR 인코딩**
|
|
- 한글 파라미터는 EUC-KR로 인코딩
|
|
- `urllib.parse.quote(text.encode('euc-kr'))`
|
|
|
|
2. **세션 관리**
|
|
- ASP 세션 쿠키 유지 필수
|
|
- 장시간 미사용 시 세션 만료
|
|
|
|
3. **동시 접속**
|
|
- 동일 계정 동시 접속 시 세션 충돌 가능
|
|
|
|
4. **재고 실시간성**
|
|
- 검색 시점의 재고 정보
|
|
- 주문 전 재고 재확인 권장
|
|
|
|
---
|
|
|
|
## 작성일
|
|
- 2026-03-06
|
|
- 리버스 엔지니어링 by Claude
|
|
|