@cmarket/partner-sdk 0.2.1 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,4 +1,194 @@
1
- ## @cmarket/partner-sdk@0.2.1
1
+ <!-- cmarket-quickstart-preamble -->
2
+
3
+ # CMARKET V6 Partner SDK
4
+
5
+ CMARKET V6 Partner API 의 공식 클라이언트 SDK — 외부 ERP 가 입찰 등록부터 낙찰·계약서류·검수·정산까지 전 흐름을 연동하기 위한 7개 API 를 타입 안전하게 호출합니다.
6
+
7
+ > 이 상단 섹션(설치·인증·통합 순서·에러·예제)은 CMARKET 가 관리하는 quickstart 입니다. 그 아래 `---` 구분선 이후는 OpenAPI Generator 가 매 릴리스 생성하는 **전체 엔드포인트/모델 레퍼런스**입니다.
8
+
9
+ ## 설치 (Installation)
10
+
11
+ TypeScript / Node (npm):
12
+
13
+ ```bash
14
+ npm install @cmarket/partner-sdk@0.3.0
15
+ ```
16
+
17
+ Java (Maven):
18
+
19
+ ```xml
20
+ <dependency>
21
+ <groupId>net.c-market</groupId>
22
+ <artifactId>partner-sdk</artifactId>
23
+ <version>0.3.0</version>
24
+ </dependency>
25
+ ```
26
+
27
+ ## Base URL
28
+
29
+ ```
30
+ https://partner-api.c-market.net # 예시 — 확정 도메인 아님
31
+ ```
32
+
33
+ 환경별(staging/production) baseURL 과 client_id / client_secret 은 파트너 온보딩 시 개별 발급·안내됩니다. 아래 예제의 baseURL 은 발급받은 값으로 교체하세요.
34
+
35
+ ## 인증 (Authentication) — OAuth 2.0 Client Credentials
36
+
37
+ 모든 호출은 OAuth 2.0 client_credentials 그랜트(RFC 6749 §4.4)로 발급한 JWT access token 을 `Authorization: Bearer <token>` 헤더로 실어야 합니다.
38
+
39
+ 1. 토큰 발급: `POST {BASE}/v1/oauth/token`
40
+ - body(form 또는 JSON): `grant_type=client_credentials`, `client_id`, `client_secret`, (선택) `scope` (space-separated)
41
+ - 응답(RFC 6749 §5.1, snake_case): `{ access_token, token_type: "Bearer", expires_in, scope }`
42
+ - access_token TTL 은 짧습니다(현재 900초/15분) — 만료 시 재발급하세요.
43
+ 2. 이후 모든 비즈니스 호출에 `Authorization: Bearer <access_token>` 부착.
44
+
45
+ ### 스코프 (Scopes)
46
+
47
+ 토큰은 파트너에 부여된 스코프 범위 내에서 발급되며, 각 엔드포인트는 아래 스코프를 요구합니다(미보유 시 403).
48
+
49
+ | Scope | 용도 |
50
+ | ----------------- | -------------------------------------------------------------------------- |
51
+ | `bids:read` | 입찰 결과/정산 조회 (getBidResults, getBidSettlement) |
52
+ | `bids:write` | 입찰 등록 (registerBid) |
53
+ | `awards:write` | 낙찰·유찰·협상점수 (registerAward, markBidFailed, submitNegotiationScores) |
54
+ | `contracts:read` | 계약서류·거래명세서 조회 (getBidContractDocuments, getBidStatement) |
55
+ | `contracts:write` | 검수완료 (completeAcceptance) |
56
+ | `invoices:write` | 분할 계산서 요청 (requestSplitInvoice) |
57
+ | `files:write` | 첨부파일 업로드 (uploadFile) |
58
+
59
+ ## 멱등성 (Idempotency)
60
+
61
+ 모든 write(POST) 엔드포인트는 `Idempotency-Key` 헤더가 **필수**입니다.
62
+
63
+ - 키 포맷: 1~255자, `[A-Za-z0-9_-]`. 호출 단위로 클라이언트가 고유 값(예: UUID) 생성.
64
+ - 같은 키 + 같은 body 로 재전송하면 핸들러를 다시 실행하지 않고 **최초 응답을 그대로 replay**(기본 24시간) — 네트워크 재시도가 안전합니다.
65
+ - 대상: registerBid, registerAward, markBidFailed, submitNegotiationScores, completeAcceptance, requestSplitInvoice, uploadFile.
66
+
67
+ ## 에러 (Errors) — RFC 9457 problem+json
68
+
69
+ 오류 응답은 `application/problem+json` 입니다.
70
+
71
+ ```json
72
+ {
73
+ "type": "https://.../errors/...",
74
+ "title": "사람이 읽는 요약",
75
+ "status": 400,
76
+ "detail": "구체적 원인"
77
+ }
78
+ ```
79
+
80
+ `status` 로 분기하고 `detail` 을 로깅하세요. 401 = 토큰 누락/만료, 403 = 스코프 부족, 409 = idempotency 충돌(동일 키 다른 body) 등.
81
+
82
+ ## 통합 순서 (7개 API — V5 → V6 매핑)
83
+
84
+ V5 push/pull 7개 API 의 V6 후속입니다. 표준 흐름:
85
+
86
+ | 단계 | V6 operation | scope | 비고 |
87
+ | ---- | ----------------------------------------- | ------------------------------- | ---------------------------------------------------------------- |
88
+ | 1 | `registerBid` | bids:write | 입찰 정보 등록 (필요 시 `uploadFile` 선행) |
89
+ | 2 | `getBidResults` / `getBidSettlement` | bids:read | 응찰 결과 / 정산(사업자·계좌·공급가) 조회 |
90
+ | 3a | (협상 H/K) `submitNegotiationScores` | awards:write | 낙찰 전 기술/가격 점수 평가 — `complete=true` 로 평가완료 게이트 |
91
+ | 3b | `registerAward` | awards:write | 낙찰 결과 전송 |
92
+ | 3c | (유찰 시) `markBidFailed` | awards:write | 유찰 사유 코드와 함께 처리 (3b 와 택일) |
93
+ | 4 | `getBidContractDocuments` | contracts:read | 계약서류 조회 |
94
+ | 5 | `completeAcceptance` | contracts:write | 검수완료 통지 |
95
+ | 6 | `getBidStatement` / `requestSplitInvoice` | contracts:read / invoices:write | 거래명세서 조회 / 분할 계산서 요청 |
96
+
97
+ > 협상에 의한 계약(H/K)일 때만 3a(submitNegotiationScores)가 3b(registerAward) 보다 선행합니다. 그 외 낙찰방법은 2 → 3b 로 진행합니다.
98
+
99
+ ## SDK 호출 예제
100
+
101
+ ### TypeScript
102
+
103
+ ```ts
104
+ import {
105
+ Configuration,
106
+ OauthApi,
107
+ PartnerV1Api,
108
+ type CreateBidRequestDto,
109
+ } from '@cmarket/partner-sdk';
110
+
111
+ const BASE = 'https://partner-api.c-market.net'; // 발급받은 baseURL 로 교체
112
+
113
+ async function main() {
114
+ // 1) 토큰 발급 (/v1/oauth/token)
115
+ const oauth = new OauthApi(new Configuration({ basePath: BASE }));
116
+ const { data: token } = await oauth.token({
117
+ grant_type: 'client_credentials',
118
+ client_id: process.env.CMARKET_CLIENT_ID!,
119
+ client_secret: process.env.CMARKET_CLIENT_SECRET!,
120
+ scope: 'bids:write',
121
+ });
122
+
123
+ // 2) access_token 으로 인증된 클라이언트 구성
124
+ const v1 = new PartnerV1Api(
125
+ new Configuration({ basePath: BASE, accessToken: token.access_token }),
126
+ );
127
+
128
+ // 3) 입찰 등록 — write 는 Idempotency-Key 헤더 필수
129
+ const body: CreateBidRequestDto = {
130
+ buyerId: 'BUYER-001',
131
+ projectName: '2026 사무용품 구매',
132
+ // ...나머지 필드는 CreateBidRequestDto 타입 참조
133
+ } as CreateBidRequestDto;
134
+
135
+ const { data } = await v1.registerBid(body, {
136
+ headers: { 'Idempotency-Key': crypto.randomUUID() },
137
+ });
138
+ console.log('created bid:', data);
139
+ }
140
+
141
+ main().catch(console.error);
142
+ ```
143
+
144
+ ### Java
145
+
146
+ ```java
147
+ import net.cmarket.partner.client.ApiClient;
148
+ import net.cmarket.partner.client.api.OauthApi;
149
+ import net.cmarket.partner.client.api.PartnerV1Api;
150
+ import net.cmarket.partner.client.model.*;
151
+ import java.util.Map;
152
+ import java.util.UUID;
153
+
154
+ public class Quickstart {
155
+ public static void main(String[] args) throws Exception {
156
+ String base = "https://partner-api.c-market.net"; // 발급받은 baseURL 로 교체
157
+
158
+ // 1) 토큰 발급 (/v1/oauth/token)
159
+ ApiClient authClient = new ApiClient().setBasePath(base);
160
+ OauthApi oauth = new OauthApi(authClient);
161
+ TokenResponseDto token = oauth.token(new TokenRequestDto()
162
+ .grantType(TokenRequestDto.GrantTypeEnum.CLIENT_CREDENTIALS)
163
+ .clientId(System.getenv("CMARKET_CLIENT_ID"))
164
+ .clientSecret(System.getenv("CMARKET_CLIENT_SECRET"))
165
+ .scope("bids:write"));
166
+
167
+ // 2) access_token 을 Authorization 헤더로 부착
168
+ ApiClient apiClient = new ApiClient()
169
+ .setBasePath(base)
170
+ .setRequestInterceptor(req ->
171
+ req.header("Authorization", "Bearer " + token.getAccessToken()));
172
+ PartnerV1Api v1 = new PartnerV1Api(apiClient);
173
+
174
+ // 3) 입찰 등록 — write 는 Idempotency-Key 헤더 필수
175
+ CreateBidRequestDto body = new CreateBidRequestDto()
176
+ .buyerId("BUYER-001")
177
+ .projectName("2026 사무용품 구매");
178
+ // ...나머지 필드는 CreateBidRequestDto 참조
179
+
180
+ BidCreatedResponseDto created = v1.registerBid(
181
+ body, Map.of("Idempotency-Key", UUID.randomUUID().toString()));
182
+ System.out.println("created bid: " + created);
183
+ }
184
+ }
185
+ ```
186
+
187
+ 각 operation 의 정확한 요청/응답 타입과 전체 엔드포인트 목록은 아래 자동 생성 레퍼런스를 참고하세요.
188
+
189
+ ---
190
+
191
+ ## @cmarket/partner-sdk@0.3.0
2
192
 
3
193
  This generator creates TypeScript/JavaScript client that utilizes [axios](https://github.com/axios/axios). The generated Node module can be used in the following environments:
4
194
 
@@ -36,7 +226,7 @@ navigate to the folder of your consuming project and run one of the following co
36
226
  _published:_
37
227
 
38
228
  ```
39
- npm install @cmarket/partner-sdk@0.2.1 --save
229
+ npm install @cmarket/partner-sdk@0.3.0 --save
40
230
  ```
41
231
 
42
232
  _unPublished (not recommended):_
@@ -53,20 +243,20 @@ Class | Method | HTTP request | Description
53
243
  ------------ | ------------- | ------------- | -------------
54
244
  *OauthApi* | [**token**](docs/OauthApi.md#token) | **POST** /v1/oauth/token | OAuth 2.0 access token 발급 (client_credentials)
55
245
  *PartnerV1Api* | [**bidsControllerFindOne**](docs/PartnerV1Api.md#bidscontrollerfindone) | **GET** /v1/bids/{bidId} | 공고 단건 조회
246
+ *PartnerV1Api* | [**completeAcceptance**](docs/PartnerV1Api.md#completeacceptance) | **POST** /v1/bids/{bidId}/acceptance | 검수완료 전송
247
+ *PartnerV1Api* | [**getBidContractDocuments**](docs/PartnerV1Api.md#getbidcontractdocuments) | **GET** /v1/bids/{bidId}/contract-documents | 계약서류 수신 조회
248
+ *PartnerV1Api* | [**getBidContractDocumentsBatch**](docs/PartnerV1Api.md#getbidcontractdocumentsbatch) | **POST** /v1/bids/contract-documents/batch | 계약서류 수신 배치 조회
249
+ *PartnerV1Api* | [**getBidResults**](docs/PartnerV1Api.md#getbidresults) | **GET** /v1/bids/{bidId}/results | 입찰 결과 조회
250
+ *PartnerV1Api* | [**getBidResultsBatch**](docs/PartnerV1Api.md#getbidresultsbatch) | **POST** /v1/bids/results/batch | 입찰결과 배치 조회
251
+ *PartnerV1Api* | [**getBidSettlement**](docs/PartnerV1Api.md#getbidsettlement) | **GET** /v1/bids/{bidId}/settlement | 입찰결과 정산정보 조회
252
+ *PartnerV1Api* | [**getBidStatement**](docs/PartnerV1Api.md#getbidstatement) | **GET** /v1/bids/{bidId}/statement | 거래명세서 조회
56
253
  *PartnerV1Api* | [**healthControllerCheck**](docs/PartnerV1Api.md#healthcontrollercheck) | **GET** /v1/health | Partner API 헬스체크
57
- *PartnerV2Api* | [**completeAcceptance**](docs/PartnerV2Api.md#completeacceptance) | **POST** /v2/bids/{bidId}/acceptance | 검수완료 전송
58
- *PartnerV2Api* | [**getBidContractDocuments**](docs/PartnerV2Api.md#getbidcontractdocuments) | **GET** /v2/bids/{bidId}/contract-documents | 계약서류 수신 조회
59
- *PartnerV2Api* | [**getBidContractDocumentsBatch**](docs/PartnerV2Api.md#getbidcontractdocumentsbatch) | **POST** /v2/bids/contract-documents/batch | 계약서류 수신 배치 조회
60
- *PartnerV2Api* | [**getBidResults**](docs/PartnerV2Api.md#getbidresults) | **GET** /v2/bids/{bidId}/results | 입찰 결과 조회
61
- *PartnerV2Api* | [**getBidResultsBatch**](docs/PartnerV2Api.md#getbidresultsbatch) | **POST** /v2/bids/results/batch | 입찰결과 배치 조회
62
- *PartnerV2Api* | [**getBidSettlement**](docs/PartnerV2Api.md#getbidsettlement) | **GET** /v2/bids/{bidId}/settlement | 입찰결과 정산정보 조회
63
- *PartnerV2Api* | [**getBidStatement**](docs/PartnerV2Api.md#getbidstatement) | **GET** /v2/bids/{bidId}/statement | 거래명세서 조회
64
- *PartnerV2Api* | [**markBidFailed**](docs/PartnerV2Api.md#markbidfailed) | **POST** /v2/awards/fail | 유찰 처리
65
- *PartnerV2Api* | [**registerAward**](docs/PartnerV2Api.md#registeraward) | **POST** /v2/awards | 낙찰 결과 전송
66
- *PartnerV2Api* | [**registerBid**](docs/PartnerV2Api.md#registerbid) | **POST** /v2/bids | 입찰 정보 전송(등록)
67
- *PartnerV2Api* | [**requestSplitInvoice**](docs/PartnerV2Api.md#requestsplitinvoice) | **POST** /v2/invoices/split-requests | 계산서 분할 발급 청구
68
- *PartnerV2Api* | [**submitNegotiationScores**](docs/PartnerV2Api.md#submitnegotiationscores) | **POST** /v2/awards/nego-eval | 협상(H/K) 점수평가
69
- *PartnerV2Api* | [**uploadFile**](docs/PartnerV2Api.md#uploadfile) | **POST** /v2/files | 입찰 첨부파일 업로드(base64 또는 url) → fileKey
254
+ *PartnerV1Api* | [**markBidFailed**](docs/PartnerV1Api.md#markbidfailed) | **POST** /v1/awards/fail | 유찰 처리
255
+ *PartnerV1Api* | [**registerAward**](docs/PartnerV1Api.md#registeraward) | **POST** /v1/awards | 낙찰 결과 전송
256
+ *PartnerV1Api* | [**registerBid**](docs/PartnerV1Api.md#registerbid) | **POST** /v1/bids | 입찰 정보 전송(등록)
257
+ *PartnerV1Api* | [**requestSplitInvoice**](docs/PartnerV1Api.md#requestsplitinvoice) | **POST** /v1/invoices/split-requests | 계산서 분할 발급 청구
258
+ *PartnerV1Api* | [**submitNegotiationScores**](docs/PartnerV1Api.md#submitnegotiationscores) | **POST** /v1/awards/nego-eval | 협상(H/K) 점수평가
259
+ *PartnerV1Api* | [**uploadFile**](docs/PartnerV1Api.md#uploadfile) | **POST** /v1/files | 입찰 첨부파일 업로드(base64 또는 url) → fileKey
70
260
 
71
261
 
72
262
  ### Documentation For Models