@sayren/store-sdk 0.6.0 → 0.8.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/dist/index.d.mts +303 -31
- package/dist/index.mjs +331 -217
- package/dist/server.d.mts +45 -1
- package/dist/server.mjs +56 -1
- package/package.json +1 -1
- package/src/client.ts +31 -0
- package/src/member-delegation.ts +98 -0
- package/src/schemas/analytics.ts +145 -0
- package/src/schemas/order.ts +10 -0
- package/src/schemas/payment.ts +84 -32
- package/src/server.ts +6 -0
package/dist/index.mjs
CHANGED
|
@@ -204,7 +204,8 @@ const analyticsOverviewSchema = z.object({
|
|
|
204
204
|
...rangeMeta,
|
|
205
205
|
summary: analyticsTotalsSchema.describe("기간 합계"),
|
|
206
206
|
funnel: z.array(analyticsFunnelStepSchema).describe("세션 기준 구매 퍼널. 각 단계는 그 행동을 한 세션 수이고, 앞 단계를 거쳤는지는 따지지 않는다"),
|
|
207
|
-
rows: z.array(analyticsTotalsSchema.extend({ date: z.string().describe("일자 (YYYY-MM-DD)") })).describe("날짜별 값. 세션이 없는 날은 생략된다")
|
|
207
|
+
rows: z.array(analyticsTotalsSchema.extend({ date: z.string().describe("일자 (YYYY-MM-DD)") })).describe("날짜별 값. 세션이 없는 날은 생략된다"),
|
|
208
|
+
excludedBotSessions: z.number().int().describe("집계에서 뺀 봇 세션 수 — 봇 표시 이벤트가 하나라도 있는 세션은 모든 값에서 빠진다")
|
|
208
209
|
});
|
|
209
210
|
const analyticsProductSortSchema = z.enum([
|
|
210
211
|
"VIEWS",
|
|
@@ -227,7 +228,8 @@ const analyticsProductRowSchema = z.object({
|
|
|
227
228
|
purchases: z.number().int().describe("이 상품이 포함된 구매(주문) 수"),
|
|
228
229
|
quantity: z.number().int().describe("구매 수량"),
|
|
229
230
|
revenue: z.number().int().describe("이 상품의 구매 금액 — 주문 상품 금액(할인 반영, 배송비 제외) 합계. 이후 취소·환불은 빼지 않는다"),
|
|
230
|
-
purchaseRate: rate("구매율 = 구매 / 조회 세션. 조회 세션이 없으면 null")
|
|
231
|
+
purchaseRate: rate("구매율 = 구매 / 조회 세션. 조회 세션이 없으면 null"),
|
|
232
|
+
clickThroughRate: rate("목록 → 상세 전환율 = 상세 조회 / 목록 노출. 노출이 없으면 null(검색·외부 링크로 바로 들어온 조회는 노출 없이 잡힌다)")
|
|
231
233
|
});
|
|
232
234
|
const analyticsProductsSchema = z.object({
|
|
233
235
|
...rangeMeta,
|
|
@@ -275,6 +277,94 @@ const analyticsSourcesSchema = z.object({
|
|
|
275
277
|
groupBy: analyticsSourceGroupBySchema,
|
|
276
278
|
rows: z.array(analyticsSourceRowSchema).describe("세션 수 내림차순")
|
|
277
279
|
});
|
|
280
|
+
const analyticsRealtimeSchema = z.object({
|
|
281
|
+
asOf: z.string().describe("기준 시각(ISO 8601)"),
|
|
282
|
+
windowMinutes: z.literal(5).describe("최근 몇 분 동안 활동한 방문을 세는가"),
|
|
283
|
+
visitors: z.number().int().describe("최근 5분 안에 이벤트가 있는 방문자 수(봇 제외)"),
|
|
284
|
+
sessions: z.number().int(),
|
|
285
|
+
pageViews: z.number().int(),
|
|
286
|
+
pages: z.array(z.object({
|
|
287
|
+
path: z.string(),
|
|
288
|
+
visitors: z.number().int(),
|
|
289
|
+
pageViews: z.number().int()
|
|
290
|
+
})).describe("최근 5분 페이지뷰가 있는 경로. 방문자 수 내림차순 최대 10개")
|
|
291
|
+
});
|
|
292
|
+
const analyticsDeviceRowSchema = z.object({
|
|
293
|
+
device: z.enum([
|
|
294
|
+
"desktop",
|
|
295
|
+
"mobile",
|
|
296
|
+
"tablet",
|
|
297
|
+
"unknown"
|
|
298
|
+
]),
|
|
299
|
+
sessions: z.number().int(),
|
|
300
|
+
productViewSessions: z.number().int(),
|
|
301
|
+
addToCartSessions: z.number().int(),
|
|
302
|
+
beginCheckoutSessions: z.number().int(),
|
|
303
|
+
purchaseSessions: z.number().int(),
|
|
304
|
+
conversionRate: rate("전환율 = 구매 세션 / 세션")
|
|
305
|
+
});
|
|
306
|
+
const analyticsDevicesSchema = z.object({
|
|
307
|
+
...rangeMeta,
|
|
308
|
+
rows: z.array(analyticsDeviceRowSchema).describe("기기별 세션 기준 퍼널. 세션 수 내림차순")
|
|
309
|
+
});
|
|
310
|
+
const limitParam = z.coerce.number().int().min(1).max(100).optional().describe("최대 행 수. 기본 20, 최대 100");
|
|
311
|
+
const analyticsPagesQuerySchema = analyticsRangeQuerySchema.extend({ limit: limitParam });
|
|
312
|
+
const analyticsPagesSchema = z.object({
|
|
313
|
+
...rangeMeta,
|
|
314
|
+
landings: z.array(z.object({
|
|
315
|
+
path: z.string(),
|
|
316
|
+
entrances: z.number().int().describe("이 페이지로 시작한 세션 수"),
|
|
317
|
+
bounces: z.number().int().describe("이 페이지로 시작해 참여하지 않고 끝난 세션 수"),
|
|
318
|
+
bounceRate: rate("반송률 = 반송 / 진입")
|
|
319
|
+
})).describe("첫 페이지. 진입 수 내림차순"),
|
|
320
|
+
exits: z.array(z.object({
|
|
321
|
+
path: z.string(),
|
|
322
|
+
pageViews: z.number().int(),
|
|
323
|
+
exits: z.number().int().describe("이 페이지가 세션의 마지막 페이지뷰였던 수"),
|
|
324
|
+
exitRate: rate("이탈률 = 이탈 / 페이지뷰")
|
|
325
|
+
})).describe("이탈 페이지. 이탈 수 내림차순")
|
|
326
|
+
});
|
|
327
|
+
const analyticsSearchQuerySchema = analyticsRangeQuerySchema.extend({ limit: limitParam });
|
|
328
|
+
const analyticsSearchSchema = z.object({
|
|
329
|
+
...rangeMeta,
|
|
330
|
+
summary: z.object({
|
|
331
|
+
searches: z.number().int(),
|
|
332
|
+
zeroResultSearches: z.number().int().describe("결과가 0개였던 검색 수"),
|
|
333
|
+
searchSessions: z.number().int().describe("검색한 세션 수(세션당 한 번)"),
|
|
334
|
+
purchaseSessions: z.number().int().describe("검색한 뒤 같은 날 구매한 세션 수(세션당 한 번). 검색 전에 끝난 구매는 세지 않는다"),
|
|
335
|
+
conversionRate: rate("검색 후 구매율 = 구매 세션 / 검색 세션")
|
|
336
|
+
}),
|
|
337
|
+
terms: z.array(z.object({
|
|
338
|
+
term: z.string().describe("검색어 — 소문자, 공백 정리"),
|
|
339
|
+
searches: z.number().int(),
|
|
340
|
+
zeroResultSearches: z.number().int(),
|
|
341
|
+
searchSessions: z.number().int().describe("이 검색어로 검색한 세션 수"),
|
|
342
|
+
purchaseSessions: z.number().int().describe("이 검색어로 검색한 뒤 같은 날 구매한 세션 수"),
|
|
343
|
+
conversionRate: rate("검색 후 구매율 = 구매 세션 / 검색 세션")
|
|
344
|
+
})).describe("검색 수 내림차순. 세션 수는 검색어마다 세므로 여러 검색어를 쓴 세션은 검색어마다 잡힌다(더하면 요약보다 크다)"),
|
|
345
|
+
zeroResultTerms: z.array(z.object({
|
|
346
|
+
term: z.string(),
|
|
347
|
+
searches: z.number().int(),
|
|
348
|
+
zeroResultSearches: z.number().int()
|
|
349
|
+
})).describe("결과가 0개였던 적이 있는 검색어. 결과 없음 수 내림차순 — 검색 수 상위(`terms`)에 들지 않는 드문 검색어도 여기 잡힌다")
|
|
350
|
+
});
|
|
351
|
+
const analyticsCheckoutOutcomeSchema = z.enum([
|
|
352
|
+
"COMPLETED",
|
|
353
|
+
"NOT_OPENED",
|
|
354
|
+
"USER_CANCELED",
|
|
355
|
+
"DECLINED",
|
|
356
|
+
"PREPARE_FAILURE",
|
|
357
|
+
"OTHER",
|
|
358
|
+
"IN_PROGRESS"
|
|
359
|
+
]).describe("결제 세션의 최종 결과 — `COMPLETED`(결제 완료), `NOT_OPENED`(결제창을 열지 않고 끝남), `USER_CANCELED`(결제창에서 취소), `DECLINED`(카드 거절 등 승인 거절), `PREPARE_FAILURE`(결제창을 띄우기 전 장애), `OTHER`(그 밖의 이탈·만료), `IN_PROGRESS`(아직 진행 중 — 만료 전 대기·승인 중). 실패 분류는 세션의 마지막 결제 시도 기준이다");
|
|
360
|
+
const analyticsCheckoutSchema = z.object({
|
|
361
|
+
...rangeMeta,
|
|
362
|
+
sessions: z.number().int().describe("기간 안에 시작한 결제 세션 수(결제 요청 단위)"),
|
|
363
|
+
outcomes: z.array(z.object({
|
|
364
|
+
outcome: analyticsCheckoutOutcomeSchema,
|
|
365
|
+
sessions: z.number().int()
|
|
366
|
+
})).describe("결과별 결제 세션 수. 결과마다 한 행")
|
|
367
|
+
});
|
|
278
368
|
//#endregion
|
|
279
369
|
//#region src/schemas/api-client.ts
|
|
280
370
|
/**
|
|
@@ -1092,205 +1182,6 @@ const reviewReportResultSchema = z.object({
|
|
|
1092
1182
|
status: z.literal("PENDING_REVIEW")
|
|
1093
1183
|
});
|
|
1094
1184
|
//#endregion
|
|
1095
|
-
//#region src/schemas/order.ts
|
|
1096
|
-
const orderSummarySchema = z.object({
|
|
1097
|
-
orderId: z.string(),
|
|
1098
|
-
ordererName: z.string(),
|
|
1099
|
-
itemCount: z.number().int(),
|
|
1100
|
-
totalAmount: z.number().int(),
|
|
1101
|
-
representativeStatus: orderItemStatusSchema,
|
|
1102
|
-
orderedAt: z.string(),
|
|
1103
|
-
testPayment: z.boolean().describe("테스트 결제(샌드박스 결제) 주문인가. true면 실제로 돈이 오가지 않았어요. 상품을 발송하지 않도록 주의하세요")
|
|
1104
|
-
});
|
|
1105
|
-
const shippingAddressSchema = z.object({
|
|
1106
|
-
receiverName: z.string(),
|
|
1107
|
-
phone: z.string(),
|
|
1108
|
-
zipCode: z.string(),
|
|
1109
|
-
address1: z.string(),
|
|
1110
|
-
address2: z.string().nullish(),
|
|
1111
|
-
deliveryMemo: z.string().nullish(),
|
|
1112
|
-
entranceCode: z.string().nullish()
|
|
1113
|
-
});
|
|
1114
|
-
const orderItemSchema = z.object({
|
|
1115
|
-
orderItemId: z.string(),
|
|
1116
|
-
orderId: z.string(),
|
|
1117
|
-
status: orderItemStatusSchema,
|
|
1118
|
-
claimStatus: z.enum([
|
|
1119
|
-
"CANCEL_REQUESTED",
|
|
1120
|
-
"RETURN_REQUESTED",
|
|
1121
|
-
"EXCHANGE_REQUESTED"
|
|
1122
|
-
]).nullable(),
|
|
1123
|
-
productId: z.string(),
|
|
1124
|
-
productName: z.string(),
|
|
1125
|
-
optionId: z.string().nullable(),
|
|
1126
|
-
optionName: z.string().nullable(),
|
|
1127
|
-
sellerCode: z.string().nullable(),
|
|
1128
|
-
quantity: z.number().int(),
|
|
1129
|
-
unitPrice: z.number().int(),
|
|
1130
|
-
discountAmount: z.number().int(),
|
|
1131
|
-
totalPrice: z.number().int(),
|
|
1132
|
-
hold: z.object({
|
|
1133
|
-
reason: z.string(),
|
|
1134
|
-
expectedDispatchDate: z.string()
|
|
1135
|
-
}).nullable(),
|
|
1136
|
-
autoDecisionDate: z.string().nullable(),
|
|
1137
|
-
sellerMemo: z.string().nullable(),
|
|
1138
|
-
orderedAt: z.string(),
|
|
1139
|
-
lastChangedAt: z.string(),
|
|
1140
|
-
lastChangedType: changeTypeSchema,
|
|
1141
|
-
testPayment: z.boolean().describe("소속 주문이 테스트 결제(샌드박스 결제) 주문인가. true면 실제로 돈이 오가지 않았어요")
|
|
1142
|
-
});
|
|
1143
|
-
const orderSchema = z.object({
|
|
1144
|
-
orderId: z.string(),
|
|
1145
|
-
orderedAt: z.string(),
|
|
1146
|
-
orderer: z.object({
|
|
1147
|
-
name: z.string(),
|
|
1148
|
-
phone: z.string(),
|
|
1149
|
-
email: z.email().optional()
|
|
1150
|
-
}),
|
|
1151
|
-
shippingAddress: shippingAddressSchema,
|
|
1152
|
-
payment: z.object({
|
|
1153
|
-
method: z.enum([
|
|
1154
|
-
"CARD",
|
|
1155
|
-
"BANK_TRANSFER",
|
|
1156
|
-
"VIRTUAL_ACCOUNT",
|
|
1157
|
-
"MOBILE",
|
|
1158
|
-
"POINT",
|
|
1159
|
-
"MIXED"
|
|
1160
|
-
]).describe("method는 호환용이며 간편결제를 CARD로 표시한다. 실제 수단은 approvedMethod를 본다"),
|
|
1161
|
-
approvedMethod: z.string().nullable().optional().default(null).describe("실제 결제수단. method는 호환용이며 간편결제를 CARD로 표시한다. 실제 수단은 approvedMethod를 본다. 현재 값은 `pgPaymentMethodSchema`(`PgPaymentMethod`: CARD·BANK_TRANSFER·VIRTUAL_ACCOUNT·MOBILE·EASY_PAY)이고 매출 리포트·스토어프론트·환불 원장과 같은 값이다. 값이 추가될 수 있어 문자열로 받는다. PG가 알려 주지 않았으면 요청 수단, 시도 기록이 없는 오래된 주문은 null. 서버는 항상 싣는다"),
|
|
1162
|
-
productAmount: z.number().int(),
|
|
1163
|
-
deliveryFee: z.number().int(),
|
|
1164
|
-
discountAmount: z.number().int(),
|
|
1165
|
-
totalAmount: z.number().int(),
|
|
1166
|
-
paidAt: z.string().nullable()
|
|
1167
|
-
}),
|
|
1168
|
-
testPayment: z.boolean().describe("테스트 결제(샌드박스 결제) 주문인가. true면 실제로 돈이 오가지 않았어요. 상품을 발송하지 않도록 주의하세요"),
|
|
1169
|
-
items: z.array(orderItemSchema)
|
|
1170
|
-
});
|
|
1171
|
-
/** 주문 목록 응답 — `GET /v1/orders` */
|
|
1172
|
-
const orderSummaryPageSchema = pageSchema(orderSummarySchema);
|
|
1173
|
-
/** 주문상품 변경 목록 응답 — `GET /v1/order-items` */
|
|
1174
|
-
const orderItemPageSchema = pageSchema(orderItemSchema);
|
|
1175
|
-
const testPaymentQuery = z.enum(["true", "false"]).optional().describe("테스트 결제(샌드박스 결제) 필터. `true`면 테스트 결제만, `false`면 실결제만, 생략하면 전부예요");
|
|
1176
|
-
const pageQuery = { page: z.string().optional().describe("페이지 번호 (1부터, 기본 1)") };
|
|
1177
|
-
/**
|
|
1178
|
-
* `GET /v1/orders` 쿼리 — OpenAPI 문서용 형태(값은 쿼리 문자열). 검증 규칙은 서버가 적용한다:
|
|
1179
|
-
* `orderedFrom` 누락 400 `MISSING_PARAMETER`, 날짜 형식 오류 400 `INVALID_PARAMETER`, 31일 초과 400 `RANGE_TOO_WIDE`,
|
|
1180
|
-
* `testPayment`가 `true`·`false`가 아니면 400 `INVALID_PARAMETER`
|
|
1181
|
-
*/
|
|
1182
|
-
const orderListQuerySchema = z.object({
|
|
1183
|
-
orderedFrom: z.string().describe("조회 시작 시각 (ISO 8601 날짜 또는 일시, 포함). 필수"),
|
|
1184
|
-
orderedTo: z.string().optional().describe("조회 끝 시각 (ISO 8601, 포함). 생략하면 orderedFrom부터 31일. 기간은 최대 31일"),
|
|
1185
|
-
status: orderItemStatusSchema.optional().describe("주문상품 상태 필터 — 이 상태의 주문상품이 하나라도 있는 주문"),
|
|
1186
|
-
keyword: z.string().optional().describe("주문번호(일치)·주문자명·수령인명(포함) 검색"),
|
|
1187
|
-
testPayment: testPaymentQuery,
|
|
1188
|
-
...pageQuery,
|
|
1189
|
-
size: z.string().optional().describe("페이지 크기 (기본 20, 최대 100)")
|
|
1190
|
-
});
|
|
1191
|
-
/**
|
|
1192
|
-
* `GET /v1/order-items` 쿼리 — OpenAPI 문서용 형태. `lastChangedFrom` 누락 400 `MISSING_PARAMETER`, 형식 오류 400
|
|
1193
|
-
* `INVALID_PARAMETER`, 24시간 초과 400 `RANGE_TOO_WIDE`, `testPayment` 값 오류 400 `INVALID_PARAMETER`
|
|
1194
|
-
*/
|
|
1195
|
-
const orderItemListQuerySchema = z.object({
|
|
1196
|
-
lastChangedFrom: z.string().describe("마지막 변경 시각 조회 시작 (ISO 8601, 포함). 필수"),
|
|
1197
|
-
lastChangedTo: z.string().optional().describe("마지막 변경 시각 조회 끝 (ISO 8601, 포함). 생략하면 시작부터 24시간. 기간은 최대 24시간"),
|
|
1198
|
-
lastChangedType: changeTypeSchema.optional().describe("마지막 변경 유형 필터"),
|
|
1199
|
-
testPayment: testPaymentQuery,
|
|
1200
|
-
...pageQuery,
|
|
1201
|
-
size: z.string().optional().describe("페이지 크기 (기본 100, 최대 300)")
|
|
1202
|
-
});
|
|
1203
|
-
const deliveryMethodSchema = z.enum([
|
|
1204
|
-
"COURIER",
|
|
1205
|
-
"DIRECT",
|
|
1206
|
-
"QUICK",
|
|
1207
|
-
"NOTHING"
|
|
1208
|
-
]);
|
|
1209
|
-
const dispatchRequestSchema = z.object({
|
|
1210
|
-
deliveryMethod: deliveryMethodSchema,
|
|
1211
|
-
carrierCode: z.string().optional(),
|
|
1212
|
-
trackingNumber: z.string().optional(),
|
|
1213
|
-
dispatchedAt: z.string().optional()
|
|
1214
|
-
}).refine((value) => value.deliveryMethod === "DIRECT" || value.deliveryMethod === "NOTHING" ? true : !!value.carrierCode && !!value.trackingNumber, { message: "COURIER/QUICK 발송은 carrierCode와 trackingNumber가 필수입니다" });
|
|
1215
|
-
const deliveryInfoSchema = z.object({
|
|
1216
|
-
orderItemId: z.string(),
|
|
1217
|
-
deliveryMethod: deliveryMethodSchema,
|
|
1218
|
-
carrierCode: z.string().nullable(),
|
|
1219
|
-
carrierName: z.string().nullable(),
|
|
1220
|
-
trackingNumber: z.string().nullable(),
|
|
1221
|
-
trackingUrl: z.url().nullable(),
|
|
1222
|
-
status: z.enum([
|
|
1223
|
-
"DISPATCHED",
|
|
1224
|
-
"DELIVERING",
|
|
1225
|
-
"DELIVERED"
|
|
1226
|
-
]),
|
|
1227
|
-
dispatchedAt: z.string(),
|
|
1228
|
-
deliveredAt: z.string().nullable()
|
|
1229
|
-
});
|
|
1230
|
-
/** `GET /v1/order-items/{orderItemId}/delivery` 응답 — 배송 정보 + 배송 추적 이벤트 */
|
|
1231
|
-
const deliveryStatusSchema = deliveryInfoSchema.extend({ trackingEvents: z.array(z.object({
|
|
1232
|
-
status: z.string(),
|
|
1233
|
-
location: z.string(),
|
|
1234
|
-
occurredAt: z.string()
|
|
1235
|
-
})).optional() });
|
|
1236
|
-
/** `PUT /v1/order-items/{orderItemId}/dispatch/tracking` 응답 — 바뀐 송장 */
|
|
1237
|
-
const trackingUpdateResultSchema = z.object({
|
|
1238
|
-
orderItemId: z.string(),
|
|
1239
|
-
carrierCode: z.string(),
|
|
1240
|
-
trackingNumber: z.string()
|
|
1241
|
-
});
|
|
1242
|
-
const carrierSchema = z.object({
|
|
1243
|
-
carrierCode: z.string(),
|
|
1244
|
-
name: z.string(),
|
|
1245
|
-
trackingUrlTemplate: z.string()
|
|
1246
|
-
});
|
|
1247
|
-
const holdOrderItemRequestSchema = z.object({
|
|
1248
|
-
reason: z.enum([
|
|
1249
|
-
"OUT_OF_STOCK",
|
|
1250
|
-
"CUSTOMER_REQUEST",
|
|
1251
|
-
"CUSTOMS",
|
|
1252
|
-
"ETC"
|
|
1253
|
-
]),
|
|
1254
|
-
detail: z.string().max(500).optional(),
|
|
1255
|
-
expectedDispatchDate: z.string()
|
|
1256
|
-
});
|
|
1257
|
-
const cancelBySellerRequestSchema = z.object({
|
|
1258
|
-
reason: z.enum([
|
|
1259
|
-
"OUT_OF_STOCK",
|
|
1260
|
-
"PRICE_ERROR",
|
|
1261
|
-
"DELIVERY_IMPOSSIBLE",
|
|
1262
|
-
"ETC"
|
|
1263
|
-
]),
|
|
1264
|
-
detail: z.string().max(500).optional()
|
|
1265
|
-
});
|
|
1266
|
-
/** `POST /v1/order-items/{orderItemId}/cancel` 응답 — 셀러 직권취소 환불 결과 */
|
|
1267
|
-
const cancelBySellerResultSchema = z.object({
|
|
1268
|
-
orderItemId: z.string(),
|
|
1269
|
-
refundAmount: z.number().int(),
|
|
1270
|
-
refundedAt: z.string()
|
|
1271
|
-
});
|
|
1272
|
-
/** `PUT /v1/order-items/{orderItemId}/memo` 응답 — 빈 문자열로 저장하면 메모가 지워져 `null`이다 */
|
|
1273
|
-
const orderItemMemoResultSchema = z.object({
|
|
1274
|
-
orderItemId: z.string(),
|
|
1275
|
-
sellerMemo: z.string().nullable()
|
|
1276
|
-
});
|
|
1277
|
-
/** `POST /v1/order-items/{orderItemId}/purchase-decision/request` 응답 */
|
|
1278
|
-
const purchaseDecisionRequestResultSchema = z.object({
|
|
1279
|
-
orderItemId: z.string(),
|
|
1280
|
-
requestedAt: z.string()
|
|
1281
|
-
});
|
|
1282
|
-
/** `POST /v1/order-items/{orderItemId}/purchase-decision/extend` 응답 — 연장은 최대 2회 */
|
|
1283
|
-
const purchaseDecisionExtendResultSchema = z.object({
|
|
1284
|
-
orderItemId: z.string(),
|
|
1285
|
-
autoDecisionDate: z.string(),
|
|
1286
|
-
extendCount: z.number().int().max(2)
|
|
1287
|
-
});
|
|
1288
|
-
/**
|
|
1289
|
-
* `GET /v1/orders/{orderId}/address-change-requests` 응답 — 배송지 변경 요청 플로우는 아직 제공하지 않아
|
|
1290
|
-
* 현재는 항상 빈 배열이다
|
|
1291
|
-
*/
|
|
1292
|
-
const addressChangeRequestListSchema = z.array(z.record(z.string(), z.unknown())).describe("배송지 변경 요청 목록 (현재 항상 빈 배열)");
|
|
1293
|
-
//#endregion
|
|
1294
1185
|
//#region src/schemas/payment.ts
|
|
1295
1186
|
/**
|
|
1296
1187
|
* 스토어 결제(PG) 설정과 매출 리포트 계약.
|
|
@@ -1307,13 +1198,22 @@ const pgPaymentMethodSchema = z.enum([
|
|
|
1307
1198
|
"MOBILE",
|
|
1308
1199
|
"EASY_PAY"
|
|
1309
1200
|
]).describe("결제수단 (스토어프론트 결제 요청의 `paymentMethod`와 같은 값)");
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
"
|
|
1316
|
-
|
|
1201
|
+
/**
|
|
1202
|
+
* 간편결제사 — 결제 옵션(스토어프론트 `paymentOptions`)과 PG 설정의 `easyPayProviders`에 쓴다.
|
|
1203
|
+
* `@sayren/storefront-sdk`의 `easyPayProviderSchema`와 같은 값이다(api 계약 테스트가 고정한다)
|
|
1204
|
+
*/
|
|
1205
|
+
const easyPayProviderSchema = z.enum([
|
|
1206
|
+
"NAVERPAY",
|
|
1207
|
+
"KAKAOPAY",
|
|
1208
|
+
"TOSSPAY",
|
|
1209
|
+
"PAYCO"
|
|
1210
|
+
]);
|
|
1211
|
+
/**
|
|
1212
|
+
* 응답에 실리는 간편결제사 — 서버가 간편결제사를 추가해도 파싱이 깨지지 않게 문자열로 받는다
|
|
1213
|
+
* (`pgProvider`·결제수단과 같은 방식). 요청(`easyPayProviders`)은 값을 골라 보내는 자리라 enum 그대로다.
|
|
1214
|
+
* 현재 값은 `NAVERPAY`·`KAKAOPAY`·`TOSSPAY`·`PAYCO`이고 화면은 모르는 값을 원문 그대로 보여 준다.
|
|
1215
|
+
*/
|
|
1216
|
+
const easyPayProviderResponseSchema = z.string();
|
|
1317
1217
|
const pgEnvironmentSchema = z.enum(["TEST", "LIVE"]).describe("PG 결제 환경. `TEST`=PG 샌드박스(테스트 키, 실제로 돈이 오가지 않음), `LIVE`=실결제(운영 키)");
|
|
1318
1218
|
const pgVerificationResultSchema = z.enum(["SUCCESS", "FAILED"]).describe("연결 테스트 결과");
|
|
1319
1219
|
/** 비밀 값 입력 — 저장 후 다시 조회할 수 없다 */
|
|
@@ -1372,13 +1272,14 @@ const upsertPortOneProviderRequestSchema = z.object({
|
|
|
1372
1272
|
});
|
|
1373
1273
|
const updatePaymentProviderRequestSchema = z.object({
|
|
1374
1274
|
enabled: z.boolean().optional().describe("사용 여부. 켜려면 활성 환경(샌드박스면 TEST, 아니면 LIVE) 자격 증명이 모두 저장돼 있어야 한다(`PAYMENT_PROVIDER_INCOMPLETE`)"),
|
|
1375
|
-
sandboxMode: z.boolean().optional().describe("샌드박스 스위치. `true`면 새 결제에 TEST 세트를 쓴다(항상 허용). `false`(라이브 전환)는 라이브 개방 조건을 모두 충족해야 한다(`LIVE_GATE_NOT_MET`)")
|
|
1376
|
-
|
|
1275
|
+
sandboxMode: z.boolean().optional().describe("샌드박스 스위치. `true`면 새 결제에 TEST 세트를 쓴다(항상 허용). `false`(라이브 전환)는 라이브 개방 조건을 모두 충족해야 한다(`LIVE_GATE_NOT_MET`)"),
|
|
1276
|
+
easyPayProviders: z.array(easyPayProviderSchema).max(easyPayProviderSchema.options.length).optional().describe("이 PG로 받는 간편결제사 — 통째로 바꾼다. PG 계약(포트원은 채널)에 추가한 간편결제만 켠다. 켠 간편결제사마다 스토어프론트 결제 옵션이 하나씩 생긴다(포트원은 간편결제를 받는 채널이 있어야 한다)")
|
|
1277
|
+
}).refine((body) => body.enabled !== void 0 || body.sandboxMode !== void 0 || body.easyPayProviders !== void 0, { message: "enabled·sandboxMode·easyPayProviders 중 하나는 보내야 해요" });
|
|
1377
1278
|
const verifyPaymentProviderRequestSchema = z.object({ environment: pgEnvironmentSchema.optional().describe("연결 테스트할 자격 증명 세트. 생략하면 활성 환경(샌드박스면 TEST, 아니면 LIVE)") });
|
|
1378
1279
|
const updatePaymentSettingsRequestSchema = z.object({
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
});
|
|
1280
|
+
priority: z.array(pgProviderSchema).min(1).max(50).optional().describe("PG 우선순위(앞이 1순위) — 스토어프론트 결제 옵션 목록의 PG 순서다. 연결된 PG 수만큼 **모두 한 번씩** 나열한다(길이 상한 50은 안전장치다). 빠지거나 중복되거나 연결되지 않은 PG가 있으면 `INVALID_PRIORITY`"),
|
|
1281
|
+
checkoutOrigins: z.array(z.string().max(200)).max(20).optional().describe("결제 도메인 — 통째로 바꾼다. 결제를 마친 구매자가 돌아올 스토어프론트 origin(`https://shop.example.com`, https·경로 없음). 결제 시작의 `returnUrl`은 이 목록 안이어야 한다. 비어 있으면 실결제를 시작할 수 없다(테스트 결제는 localhost 허용). 같은 도메인을 PG 가맹 정보에도 등록한다. 형식이 틀리면 `INVALID_CHECKOUT_ORIGIN`")
|
|
1282
|
+
}).refine((body) => body.priority !== void 0 || body.checkoutOrigins !== void 0, { message: "priority 또는 checkoutOrigins 중 하나는 보내야 해요" });
|
|
1382
1283
|
const maskedSecretSchema = z.object({
|
|
1383
1284
|
field: z.string().describe("비밀 필드 이름 (`secretKey`·`apiSecret`·`webhookSecret`)"),
|
|
1384
1285
|
configured: z.boolean().describe("값이 저장돼 있는가"),
|
|
@@ -1439,6 +1340,7 @@ const paymentProviderSchema = z.object({
|
|
|
1439
1340
|
LIVE: paymentCredentialSetSchema.nullable()
|
|
1440
1341
|
}).describe("환경별 자격 증명 세트. 등록되지 않은 세트는 null"),
|
|
1441
1342
|
liveGate: liveGateSchema.describe("라이브 개방 조건. 조건을 모두 충족해야 샌드박스를 끌 수 있다"),
|
|
1343
|
+
easyPayProviders: z.array(easyPayProviderResponseSchema).describe("이 PG로 받는 간편결제사. 연결되지 않았으면 빈 목록. 현재 값은 `NAVERPAY`·`KAKAOPAY`·`TOSSPAY`·`PAYCO`이고 값이 추가될 수 있어 문자열로 받는다"),
|
|
1442
1344
|
retiredCredentialCount: z.number().int().describe("보관된(가맹점 교체·연결 해제로 새 결제에 더 쓰이지 않는) 자격 증명 수. 그 가맹점으로 받은 결제의 환불·대사에 계속 쓰인다"),
|
|
1443
1345
|
routingExclusion: z.string().nullable().optional().default(null).describe("지금 새 결제의 후보가 아닌 사유. 후보면 null. 판정 원천은 서버 라우팅이다(콘솔이 다시 계산하지 않는다). 후보가 아닌 PG에는 항상 사유 코드를 붙인다(연결 안 된 PG 포함) — 모든 PG는 `candidates`에 있거나 이 값이 null이 아니다. 현재 값: `NOT_CONNECTED`(연결 안 됨) · `DISABLED`(사용 중지) · `CREDENTIAL_MISSING`(활성 환경 자격 증명 없음) · `SANDBOX_IN_LIVE_STORE`(다른 PG가 라이브라 이 샌드박스 PG는 실구매자 결제에 쓰지 않음) · `PLATFORM_BLOCKED`(플랫폼이 실결제를 막음) · `MODE_MISMATCH`(라이브를 연 서버 모드와 현재 모드가 다름). 값이 추가될 수 있어 문자열로 받는다 — 모르는 값은 후보 아님으로 다룬다. 서버는 항상 싣는다. 이 필드가 없는 이전 서버 응답은 기본값(null)으로 읽는다")
|
|
1444
1346
|
});
|
|
@@ -1455,8 +1357,7 @@ const PAYMENT_ROUTING_EXCLUSION_CODES = [
|
|
|
1455
1357
|
"MODE_MISMATCH"
|
|
1456
1358
|
];
|
|
1457
1359
|
const paymentSettingsSchema = z.object({
|
|
1458
|
-
|
|
1459
|
-
effectiveRoutingMode: effectivePaymentRoutingModeSchema,
|
|
1360
|
+
checkoutOrigins: z.array(z.string()).describe("결제 도메인 — 결제를 마친 구매자가 돌아올 스토어프론트 origin 목록"),
|
|
1460
1361
|
providers: z.array(paymentProviderSchema).describe("지원하는 모든 PG. 연결된 것은 우선순위순, 연결되지 않은 것은 뒤에 온다"),
|
|
1461
1362
|
environment: pgEnvironmentSchema.nullable().optional().default(null).describe("지금 결제를 시작하면 쓰는 결제 환경. 사용 가능한 PG 중 하나라도 라이브면 `LIVE`(샌드박스 PG는 제외), 아니면 `TEST`. 사용 가능한 PG가 없으면 null. 서버는 항상 싣는다. 이 필드가 없는 이전 서버 응답은 기본값(null)으로 읽는다"),
|
|
1462
1363
|
candidates: z.array(z.string()).optional().default(() => []).describe("지금 결제를 시작하면 쓰는 PG, 우선순위순(`tosspayments`·`portone`). 비어 있으면 구매자가 결제할 수 없다. 빠진 PG의 사유는 `providers[].routingExclusion` — 후보가 아닌 PG에는 항상 사유 코드를 붙인다. 서버는 항상 싣는다. 이 필드가 없는 이전 서버 응답은 기본값(빈 배열)으로 읽는다")
|
|
@@ -1533,6 +1434,7 @@ const paymentRecordSchema = z.object({
|
|
|
1533
1434
|
refundedAmount: z.number().int().describe("환불 완료 금액 합계. 실패한 환불은 빼고 센다"),
|
|
1534
1435
|
provider: pgProviderSchema.nullable().describe("승인한 PG. 승인 전에 끝났으면 마지막 시도의 PG"),
|
|
1535
1436
|
method: pgPaymentMethodSchema.nullable().describe("실제 결제수단. 모르면 요청 수단"),
|
|
1437
|
+
easyPayProvider: easyPayProviderResponseSchema.nullable().optional().default(null).describe("간편결제사. `method`가 `EASY_PAY`일 때만 값이 있고, PG가 알려 주지 않았으면 요청한 간편결제사다. 그 밖의 결제수단과 간편결제 이전 결제는 null. 서버는 항상 싣는다. 현재 값은 `NAVERPAY`·`KAKAOPAY`·`TOSSPAY`·`PAYCO`이고 값이 추가될 수 있어 문자열로 받는다"),
|
|
1536
1438
|
environment: pgEnvironmentSchema.nullable().describe("결제 환경"),
|
|
1537
1439
|
testPayment: z.boolean().describe("샌드박스 결제인가"),
|
|
1538
1440
|
pgTransactionId: z.string().nullable().describe("PG 거래 id (토스 paymentKey, 포트원 txId)"),
|
|
@@ -1550,7 +1452,9 @@ const paymentAttemptRecordSchema = z.object({
|
|
|
1550
1452
|
provider: pgProviderSchema,
|
|
1551
1453
|
status: paymentAttemptStatusSchema,
|
|
1552
1454
|
method: pgPaymentMethodSchema.describe("주문서에서 고른 결제수단"),
|
|
1455
|
+
easyPayProvider: easyPayProviderResponseSchema.nullable().optional().default(null).describe("주문서에서 고른 간편결제사. 간편결제가 아니면 null. 서버는 항상 싣는다(값이 추가될 수 있어 문자열)"),
|
|
1553
1456
|
approvedMethod: pgPaymentMethodSchema.nullable().describe("PG가 보고한 실제 결제수단"),
|
|
1457
|
+
approvedEasyPayProvider: easyPayProviderResponseSchema.nullable().optional().default(null).describe("PG가 보고한 실제 간편결제사. 모르거나 간편결제가 아니면 null. 서버는 항상 싣는다(값이 추가될 수 있어 문자열)"),
|
|
1554
1458
|
amount: z.number().int(),
|
|
1555
1459
|
environment: pgEnvironmentSchema,
|
|
1556
1460
|
pgTransactionId: z.string().nullable(),
|
|
@@ -1588,6 +1492,206 @@ const paymentListQuerySchema = z.object({
|
|
|
1588
1492
|
size: z.string().optional().describe("페이지 크기 (기본 20, 최대 100)")
|
|
1589
1493
|
});
|
|
1590
1494
|
//#endregion
|
|
1495
|
+
//#region src/schemas/order.ts
|
|
1496
|
+
const orderSummarySchema = z.object({
|
|
1497
|
+
orderId: z.string(),
|
|
1498
|
+
ordererName: z.string(),
|
|
1499
|
+
itemCount: z.number().int(),
|
|
1500
|
+
totalAmount: z.number().int(),
|
|
1501
|
+
representativeStatus: orderItemStatusSchema,
|
|
1502
|
+
orderedAt: z.string(),
|
|
1503
|
+
testPayment: z.boolean().describe("테스트 결제(샌드박스 결제) 주문인가. true면 실제로 돈이 오가지 않았어요. 상품을 발송하지 않도록 주의하세요")
|
|
1504
|
+
});
|
|
1505
|
+
const shippingAddressSchema = z.object({
|
|
1506
|
+
receiverName: z.string(),
|
|
1507
|
+
phone: z.string(),
|
|
1508
|
+
zipCode: z.string(),
|
|
1509
|
+
address1: z.string(),
|
|
1510
|
+
address2: z.string().nullish(),
|
|
1511
|
+
deliveryMemo: z.string().nullish(),
|
|
1512
|
+
entranceCode: z.string().nullish()
|
|
1513
|
+
});
|
|
1514
|
+
const orderItemSchema = z.object({
|
|
1515
|
+
orderItemId: z.string(),
|
|
1516
|
+
orderId: z.string(),
|
|
1517
|
+
status: orderItemStatusSchema,
|
|
1518
|
+
claimStatus: z.enum([
|
|
1519
|
+
"CANCEL_REQUESTED",
|
|
1520
|
+
"RETURN_REQUESTED",
|
|
1521
|
+
"EXCHANGE_REQUESTED"
|
|
1522
|
+
]).nullable(),
|
|
1523
|
+
productId: z.string(),
|
|
1524
|
+
productName: z.string(),
|
|
1525
|
+
optionId: z.string().nullable(),
|
|
1526
|
+
optionName: z.string().nullable(),
|
|
1527
|
+
sellerCode: z.string().nullable(),
|
|
1528
|
+
quantity: z.number().int(),
|
|
1529
|
+
unitPrice: z.number().int(),
|
|
1530
|
+
discountAmount: z.number().int(),
|
|
1531
|
+
totalPrice: z.number().int(),
|
|
1532
|
+
hold: z.object({
|
|
1533
|
+
reason: z.string(),
|
|
1534
|
+
expectedDispatchDate: z.string()
|
|
1535
|
+
}).nullable(),
|
|
1536
|
+
autoDecisionDate: z.string().nullable(),
|
|
1537
|
+
sellerMemo: z.string().nullable(),
|
|
1538
|
+
orderedAt: z.string(),
|
|
1539
|
+
lastChangedAt: z.string(),
|
|
1540
|
+
lastChangedType: changeTypeSchema,
|
|
1541
|
+
testPayment: z.boolean().describe("소속 주문이 테스트 결제(샌드박스 결제) 주문인가. true면 실제로 돈이 오가지 않았어요")
|
|
1542
|
+
});
|
|
1543
|
+
const orderSchema = z.object({
|
|
1544
|
+
orderId: z.string(),
|
|
1545
|
+
orderedAt: z.string(),
|
|
1546
|
+
orderer: z.object({
|
|
1547
|
+
name: z.string(),
|
|
1548
|
+
phone: z.string(),
|
|
1549
|
+
email: z.email().optional()
|
|
1550
|
+
}),
|
|
1551
|
+
shippingAddress: shippingAddressSchema,
|
|
1552
|
+
payment: z.object({
|
|
1553
|
+
method: z.enum([
|
|
1554
|
+
"CARD",
|
|
1555
|
+
"BANK_TRANSFER",
|
|
1556
|
+
"VIRTUAL_ACCOUNT",
|
|
1557
|
+
"MOBILE",
|
|
1558
|
+
"POINT",
|
|
1559
|
+
"MIXED"
|
|
1560
|
+
]).describe("method는 호환용이며 간편결제를 CARD로 표시한다. 실제 수단은 approvedMethod를 본다"),
|
|
1561
|
+
approvedMethod: z.string().nullable().optional().default(null).describe("실제 결제수단. method는 호환용이며 간편결제를 CARD로 표시한다. 실제 수단은 approvedMethod를 본다. 현재 값은 `pgPaymentMethodSchema`(`PgPaymentMethod`: CARD·BANK_TRANSFER·VIRTUAL_ACCOUNT·MOBILE·EASY_PAY)이고 매출 리포트·스토어프론트·환불 원장과 같은 값이다. 값이 추가될 수 있어 문자열로 받는다. PG가 알려 주지 않았으면 요청 수단, 시도 기록이 없는 오래된 주문은 null. 서버는 항상 싣는다"),
|
|
1562
|
+
easyPayProvider: easyPayProviderResponseSchema.nullable().optional().default(null).describe("승인된 간편결제사. `approvedMethod`가 `EASY_PAY`일 때만 값이 있고, PG가 알려 주지 않았으면 요청한 간편결제사다. 그 밖의 결제수단과 간편결제 이전 주문은 null. 서버는 항상 싣는다. 현재 값은 `NAVERPAY`·`KAKAOPAY`·`TOSSPAY`·`PAYCO`이고 값이 추가될 수 있어 문자열로 받는다"),
|
|
1563
|
+
productAmount: z.number().int(),
|
|
1564
|
+
deliveryFee: z.number().int(),
|
|
1565
|
+
discountAmount: z.number().int(),
|
|
1566
|
+
totalAmount: z.number().int(),
|
|
1567
|
+
paidAt: z.string().nullable()
|
|
1568
|
+
}),
|
|
1569
|
+
testPayment: z.boolean().describe("테스트 결제(샌드박스 결제) 주문인가. true면 실제로 돈이 오가지 않았어요. 상품을 발송하지 않도록 주의하세요"),
|
|
1570
|
+
items: z.array(orderItemSchema)
|
|
1571
|
+
});
|
|
1572
|
+
/** 주문 목록 응답 — `GET /v1/orders` */
|
|
1573
|
+
const orderSummaryPageSchema = pageSchema(orderSummarySchema);
|
|
1574
|
+
/** 주문상품 변경 목록 응답 — `GET /v1/order-items` */
|
|
1575
|
+
const orderItemPageSchema = pageSchema(orderItemSchema);
|
|
1576
|
+
const testPaymentQuery = z.enum(["true", "false"]).optional().describe("테스트 결제(샌드박스 결제) 필터. `true`면 테스트 결제만, `false`면 실결제만, 생략하면 전부예요");
|
|
1577
|
+
const pageQuery = { page: z.string().optional().describe("페이지 번호 (1부터, 기본 1)") };
|
|
1578
|
+
/**
|
|
1579
|
+
* `GET /v1/orders` 쿼리 — OpenAPI 문서용 형태(값은 쿼리 문자열). 검증 규칙은 서버가 적용한다:
|
|
1580
|
+
* `orderedFrom` 누락 400 `MISSING_PARAMETER`, 날짜 형식 오류 400 `INVALID_PARAMETER`, 31일 초과 400 `RANGE_TOO_WIDE`,
|
|
1581
|
+
* `testPayment`가 `true`·`false`가 아니면 400 `INVALID_PARAMETER`
|
|
1582
|
+
*/
|
|
1583
|
+
const orderListQuerySchema = z.object({
|
|
1584
|
+
orderedFrom: z.string().describe("조회 시작 시각 (ISO 8601 날짜 또는 일시, 포함). 필수"),
|
|
1585
|
+
orderedTo: z.string().optional().describe("조회 끝 시각 (ISO 8601, 포함). 생략하면 orderedFrom부터 31일. 기간은 최대 31일"),
|
|
1586
|
+
status: orderItemStatusSchema.optional().describe("주문상품 상태 필터 — 이 상태의 주문상품이 하나라도 있는 주문"),
|
|
1587
|
+
keyword: z.string().optional().describe("주문번호(일치)·주문자명·수령인명(포함) 검색"),
|
|
1588
|
+
testPayment: testPaymentQuery,
|
|
1589
|
+
...pageQuery,
|
|
1590
|
+
size: z.string().optional().describe("페이지 크기 (기본 20, 최대 100)")
|
|
1591
|
+
});
|
|
1592
|
+
/**
|
|
1593
|
+
* `GET /v1/order-items` 쿼리 — OpenAPI 문서용 형태. `lastChangedFrom` 누락 400 `MISSING_PARAMETER`, 형식 오류 400
|
|
1594
|
+
* `INVALID_PARAMETER`, 24시간 초과 400 `RANGE_TOO_WIDE`, `testPayment` 값 오류 400 `INVALID_PARAMETER`
|
|
1595
|
+
*/
|
|
1596
|
+
const orderItemListQuerySchema = z.object({
|
|
1597
|
+
lastChangedFrom: z.string().describe("마지막 변경 시각 조회 시작 (ISO 8601, 포함). 필수"),
|
|
1598
|
+
lastChangedTo: z.string().optional().describe("마지막 변경 시각 조회 끝 (ISO 8601, 포함). 생략하면 시작부터 24시간. 기간은 최대 24시간"),
|
|
1599
|
+
lastChangedType: changeTypeSchema.optional().describe("마지막 변경 유형 필터"),
|
|
1600
|
+
testPayment: testPaymentQuery,
|
|
1601
|
+
...pageQuery,
|
|
1602
|
+
size: z.string().optional().describe("페이지 크기 (기본 100, 최대 300)")
|
|
1603
|
+
});
|
|
1604
|
+
const deliveryMethodSchema = z.enum([
|
|
1605
|
+
"COURIER",
|
|
1606
|
+
"DIRECT",
|
|
1607
|
+
"QUICK",
|
|
1608
|
+
"NOTHING"
|
|
1609
|
+
]);
|
|
1610
|
+
const dispatchRequestSchema = z.object({
|
|
1611
|
+
deliveryMethod: deliveryMethodSchema,
|
|
1612
|
+
carrierCode: z.string().optional(),
|
|
1613
|
+
trackingNumber: z.string().optional(),
|
|
1614
|
+
dispatchedAt: z.string().optional()
|
|
1615
|
+
}).refine((value) => value.deliveryMethod === "DIRECT" || value.deliveryMethod === "NOTHING" ? true : !!value.carrierCode && !!value.trackingNumber, { message: "COURIER/QUICK 발송은 carrierCode와 trackingNumber가 필수입니다" });
|
|
1616
|
+
const deliveryInfoSchema = z.object({
|
|
1617
|
+
orderItemId: z.string(),
|
|
1618
|
+
deliveryMethod: deliveryMethodSchema,
|
|
1619
|
+
carrierCode: z.string().nullable(),
|
|
1620
|
+
carrierName: z.string().nullable(),
|
|
1621
|
+
trackingNumber: z.string().nullable(),
|
|
1622
|
+
trackingUrl: z.url().nullable(),
|
|
1623
|
+
status: z.enum([
|
|
1624
|
+
"DISPATCHED",
|
|
1625
|
+
"DELIVERING",
|
|
1626
|
+
"DELIVERED"
|
|
1627
|
+
]),
|
|
1628
|
+
dispatchedAt: z.string(),
|
|
1629
|
+
deliveredAt: z.string().nullable()
|
|
1630
|
+
});
|
|
1631
|
+
/** `GET /v1/order-items/{orderItemId}/delivery` 응답 — 배송 정보 + 배송 추적 이벤트 */
|
|
1632
|
+
const deliveryStatusSchema = deliveryInfoSchema.extend({ trackingEvents: z.array(z.object({
|
|
1633
|
+
status: z.string(),
|
|
1634
|
+
location: z.string(),
|
|
1635
|
+
occurredAt: z.string()
|
|
1636
|
+
})).optional() });
|
|
1637
|
+
/** `PUT /v1/order-items/{orderItemId}/dispatch/tracking` 응답 — 바뀐 송장 */
|
|
1638
|
+
const trackingUpdateResultSchema = z.object({
|
|
1639
|
+
orderItemId: z.string(),
|
|
1640
|
+
carrierCode: z.string(),
|
|
1641
|
+
trackingNumber: z.string()
|
|
1642
|
+
});
|
|
1643
|
+
const carrierSchema = z.object({
|
|
1644
|
+
carrierCode: z.string(),
|
|
1645
|
+
name: z.string(),
|
|
1646
|
+
trackingUrlTemplate: z.string()
|
|
1647
|
+
});
|
|
1648
|
+
const holdOrderItemRequestSchema = z.object({
|
|
1649
|
+
reason: z.enum([
|
|
1650
|
+
"OUT_OF_STOCK",
|
|
1651
|
+
"CUSTOMER_REQUEST",
|
|
1652
|
+
"CUSTOMS",
|
|
1653
|
+
"ETC"
|
|
1654
|
+
]),
|
|
1655
|
+
detail: z.string().max(500).optional(),
|
|
1656
|
+
expectedDispatchDate: z.string()
|
|
1657
|
+
});
|
|
1658
|
+
const cancelBySellerRequestSchema = z.object({
|
|
1659
|
+
reason: z.enum([
|
|
1660
|
+
"OUT_OF_STOCK",
|
|
1661
|
+
"PRICE_ERROR",
|
|
1662
|
+
"DELIVERY_IMPOSSIBLE",
|
|
1663
|
+
"ETC"
|
|
1664
|
+
]),
|
|
1665
|
+
detail: z.string().max(500).optional()
|
|
1666
|
+
});
|
|
1667
|
+
/** `POST /v1/order-items/{orderItemId}/cancel` 응답 — 셀러 직권취소 환불 결과 */
|
|
1668
|
+
const cancelBySellerResultSchema = z.object({
|
|
1669
|
+
orderItemId: z.string(),
|
|
1670
|
+
refundAmount: z.number().int(),
|
|
1671
|
+
refundedAt: z.string()
|
|
1672
|
+
});
|
|
1673
|
+
/** `PUT /v1/order-items/{orderItemId}/memo` 응답 — 빈 문자열로 저장하면 메모가 지워져 `null`이다 */
|
|
1674
|
+
const orderItemMemoResultSchema = z.object({
|
|
1675
|
+
orderItemId: z.string(),
|
|
1676
|
+
sellerMemo: z.string().nullable()
|
|
1677
|
+
});
|
|
1678
|
+
/** `POST /v1/order-items/{orderItemId}/purchase-decision/request` 응답 */
|
|
1679
|
+
const purchaseDecisionRequestResultSchema = z.object({
|
|
1680
|
+
orderItemId: z.string(),
|
|
1681
|
+
requestedAt: z.string()
|
|
1682
|
+
});
|
|
1683
|
+
/** `POST /v1/order-items/{orderItemId}/purchase-decision/extend` 응답 — 연장은 최대 2회 */
|
|
1684
|
+
const purchaseDecisionExtendResultSchema = z.object({
|
|
1685
|
+
orderItemId: z.string(),
|
|
1686
|
+
autoDecisionDate: z.string(),
|
|
1687
|
+
extendCount: z.number().int().max(2)
|
|
1688
|
+
});
|
|
1689
|
+
/**
|
|
1690
|
+
* `GET /v1/orders/{orderId}/address-change-requests` 응답 — 배송지 변경 요청 플로우는 아직 제공하지 않아
|
|
1691
|
+
* 현재는 항상 빈 배열이다
|
|
1692
|
+
*/
|
|
1693
|
+
const addressChangeRequestListSchema = z.array(z.record(z.string(), z.unknown())).describe("배송지 변경 요청 목록 (현재 항상 빈 배열)");
|
|
1694
|
+
//#endregion
|
|
1591
1695
|
//#region src/schemas/product.ts
|
|
1592
1696
|
const productStatusSchema = z.enum([
|
|
1593
1697
|
"SALE",
|
|
@@ -2277,7 +2381,17 @@ get: (params) => storeHttp.request("GET", "/sales-report", salesReportSchema, {
|
|
|
2277
2381
|
/** `GET /v1/analytics/products` — 상품별 노출·조회·장바구니·구매 */
|
|
2278
2382
|
products: (params) => storeHttp.request("GET", "/analytics/products", analyticsProductsSchema, { query: analyticsProductsQuerySchema.parse(params) }),
|
|
2279
2383
|
/** `GET /v1/analytics/sources` — 채널·소스·캠페인·기기별 세션과 구매 */
|
|
2280
|
-
sources: (params) => storeHttp.request("GET", "/analytics/sources", analyticsSourcesSchema, { query: analyticsSourcesQuerySchema.parse(params) })
|
|
2384
|
+
sources: (params) => storeHttp.request("GET", "/analytics/sources", analyticsSourcesSchema, { query: analyticsSourcesQuerySchema.parse(params) }),
|
|
2385
|
+
/** `GET /v1/analytics/realtime` — 최근 5분 방문자·세션·페이지(원본 이벤트 기준, 봇 제외) */
|
|
2386
|
+
realtime: () => storeHttp.request("GET", "/analytics/realtime", analyticsRealtimeSchema),
|
|
2387
|
+
/** `GET /v1/analytics/devices` — 기기별 세션 퍼널 */
|
|
2388
|
+
devices: (params) => storeHttp.request("GET", "/analytics/devices", analyticsDevicesSchema, { query: analyticsRangeQuerySchema.parse(params) }),
|
|
2389
|
+
/** `GET /v1/analytics/pages` — 첫 페이지(진입·반송)와 이탈 페이지 */
|
|
2390
|
+
pages: (params) => storeHttp.request("GET", "/analytics/pages", analyticsPagesSchema, { query: analyticsPagesQuerySchema.parse(params) }),
|
|
2391
|
+
/** `GET /v1/analytics/search` — 검색어별 검색·결과 0개·검색 후 구매 */
|
|
2392
|
+
search: (params) => storeHttp.request("GET", "/analytics/search", analyticsSearchSchema, { query: analyticsSearchQuerySchema.parse(params) }),
|
|
2393
|
+
/** `GET /v1/analytics/checkout` — 결제 세션의 결과별 수(결제 단계 이탈 이유) */
|
|
2394
|
+
checkout: (params) => storeHttp.request("GET", "/analytics/checkout", analyticsCheckoutSchema, { query: analyticsRangeQuerySchema.parse(params) })
|
|
2281
2395
|
},
|
|
2282
2396
|
/**
|
|
2283
2397
|
* 결제 내역 — 스코프 `settlement:r`. 결제 건(세션) 단위이고 주문 목록과 다르다. 주문이 만들어지지 않은
|
|
@@ -2812,4 +2926,4 @@ function createStoreSession(options) {
|
|
|
2812
2926
|
};
|
|
2813
2927
|
}
|
|
2814
2928
|
//#endregion
|
|
2815
|
-
export { ApiError, MAX_ANALYTICS_ALLOWED_ORIGINS, MAX_OPTION_GROUPS, MAX_VALUES_PER_GROUP, MAX_VARIANTS, PAYMENT_ROUTING_EXCLUSION_CODES, PORTONE_CHANNEL_NAME_MAX_LENGTH, PORTONE_MAX_CHANNELS, PORTONE_MIN_CHANNELS, RESERVED_STORE_CODES, STORE_CODE_PATTERN, STORE_ROLE_SCOPES, STORE_SCOPE_RESOURCES, STORE_SESSION_KEYS, TOSS_WIDGET_CLIENT_KEY_PATTERN, TOSS_WIDGET_KEY_MESSAGE, TOSS_WIDGET_SECRET_KEY_PATTERN, VARIANT_STOCK_EXCLUSIVE_MESSAGE, WEBHOOK_DEFAULT_TOLERANCE_SEC, WEBHOOK_DELIVERY_ID_HEADER, WEBHOOK_EVENT_ID_HEADER, WEBHOOK_EVENT_TYPE_HEADER, WEBHOOK_HEADERS, WEBHOOK_SIGNATURE_HEADER, WEBHOOK_USER_AGENT, addressChangeRequestListSchema, addressTypeSchema, analyticsChannelSchema, analyticsFunnelStepSchema, analyticsOriginSchema, analyticsOverviewSchema, analyticsProductRowSchema, analyticsProductSortSchema, analyticsProductsQuerySchema, analyticsProductsSchema, analyticsRangeQuerySchema, analyticsSourceGroupBySchema, analyticsSourceRowSchema, analyticsSourcesQuerySchema, analyticsSourcesSchema, analyticsTotalsSchema, apiClientListQuerySchema, apiClientSchema, apiClientSecretRotatedSchema, apiClientStatusSchema, apiClientTypeSchema, apiLogErrorSchema, apiLogListQuerySchema, apiLogPageSchema, apiLogPrincipalSchema, apiLogPrincipalTypeSchema, apiLogSchema, apiLogStatusFilterSchema, apiLogSummarySchema, apiTokenCreateRequestSchema, apiTokenCreatedSchema, apiTokenSchema, approveClaimResultSchema, buildAuthorizeUrl, buildQuery, bulkResultSchema, cancelBySellerRequestSchema, cancelBySellerResultSchema, carrierSchema, categoryAttributeSchema, categoryCreateRequestSchema, categoryDeleteQuerySchema, categoryDeleteStrategySchema, categoryListQuerySchema, categoryPatchRequestSchema, categoryProductSortSchema, categorySchema, categorySearchResultSchema, categoryTreeNodeSchema, categoryWithPathSchema, changeTypeSchema, claimDetailSchema, claimHoldResultSchema, claimListQuerySchema, claimReasonSchema, claimSchema, claimStatusSchema, claimTypeSchema, claimWebhookEventDataSchema, claimWebhookEventSchema, clientCredentialsTokenResponseSchema, createPkcePair, createStoreClient, createStoreSession, customerAddressSchema, customerDetailSchema, customerInquiryCategorySchema, customerInquiryListQuerySchema, customerListQuerySchema, customerOrderSchema, customerSortSchema, customerStatsSchema, customerSummarySchema, customerWithdrawalBlockedDetailsSchema, deliveryInfoSchema, deliveryMethodSchema, deliveryStatusSchema, deliveryTypeSchema, discountRequestSchema, discountSchema, dispatchRequestSchema,
|
|
2929
|
+
export { ApiError, MAX_ANALYTICS_ALLOWED_ORIGINS, MAX_OPTION_GROUPS, MAX_VALUES_PER_GROUP, MAX_VARIANTS, PAYMENT_ROUTING_EXCLUSION_CODES, PORTONE_CHANNEL_NAME_MAX_LENGTH, PORTONE_MAX_CHANNELS, PORTONE_MIN_CHANNELS, RESERVED_STORE_CODES, STORE_CODE_PATTERN, STORE_ROLE_SCOPES, STORE_SCOPE_RESOURCES, STORE_SESSION_KEYS, TOSS_WIDGET_CLIENT_KEY_PATTERN, TOSS_WIDGET_KEY_MESSAGE, TOSS_WIDGET_SECRET_KEY_PATTERN, VARIANT_STOCK_EXCLUSIVE_MESSAGE, WEBHOOK_DEFAULT_TOLERANCE_SEC, WEBHOOK_DELIVERY_ID_HEADER, WEBHOOK_EVENT_ID_HEADER, WEBHOOK_EVENT_TYPE_HEADER, WEBHOOK_HEADERS, WEBHOOK_SIGNATURE_HEADER, WEBHOOK_USER_AGENT, addressChangeRequestListSchema, addressTypeSchema, analyticsChannelSchema, analyticsCheckoutOutcomeSchema, analyticsCheckoutSchema, analyticsDeviceRowSchema, analyticsDevicesSchema, analyticsFunnelStepSchema, analyticsOriginSchema, analyticsOverviewSchema, analyticsPagesQuerySchema, analyticsPagesSchema, analyticsProductRowSchema, analyticsProductSortSchema, analyticsProductsQuerySchema, analyticsProductsSchema, analyticsRangeQuerySchema, analyticsRealtimeSchema, analyticsSearchQuerySchema, analyticsSearchSchema, analyticsSourceGroupBySchema, analyticsSourceRowSchema, analyticsSourcesQuerySchema, analyticsSourcesSchema, analyticsTotalsSchema, apiClientListQuerySchema, apiClientSchema, apiClientSecretRotatedSchema, apiClientStatusSchema, apiClientTypeSchema, apiLogErrorSchema, apiLogListQuerySchema, apiLogPageSchema, apiLogPrincipalSchema, apiLogPrincipalTypeSchema, apiLogSchema, apiLogStatusFilterSchema, apiLogSummarySchema, apiTokenCreateRequestSchema, apiTokenCreatedSchema, apiTokenSchema, approveClaimResultSchema, buildAuthorizeUrl, buildQuery, bulkResultSchema, cancelBySellerRequestSchema, cancelBySellerResultSchema, carrierSchema, categoryAttributeSchema, categoryCreateRequestSchema, categoryDeleteQuerySchema, categoryDeleteStrategySchema, categoryListQuerySchema, categoryPatchRequestSchema, categoryProductSortSchema, categorySchema, categorySearchResultSchema, categoryTreeNodeSchema, categoryWithPathSchema, changeTypeSchema, claimDetailSchema, claimHoldResultSchema, claimListQuerySchema, claimReasonSchema, claimSchema, claimStatusSchema, claimTypeSchema, claimWebhookEventDataSchema, claimWebhookEventSchema, clientCredentialsTokenResponseSchema, createPkcePair, createStoreClient, createStoreSession, customerAddressSchema, customerDetailSchema, customerInquiryCategorySchema, customerInquiryListQuerySchema, customerListQuerySchema, customerOrderSchema, customerSortSchema, customerStatsSchema, customerSummarySchema, customerWithdrawalBlockedDetailsSchema, deliveryInfoSchema, deliveryMethodSchema, deliveryStatusSchema, deliveryTypeSchema, discountRequestSchema, discountSchema, dispatchRequestSchema, easyPayProviderResponseSchema, easyPayProviderSchema, eventTypeSchema, exchangeAuthorizationCode, exchangeStoreTokenViaOAuth, holdOrderItemRequestSchema, inquiryListQuerySchema, inquirySchema, inquiryWebhookEventDataSchema, inquiryWebhookEventSchema, invitationListQuerySchema, invitationSchema, isReservedStoreCode, isStoreScope, isWebOrigin, liveGateConditionCodeSchema, liveGateConditionSchema, liveGateErrorDetailsSchema, liveGateSchema, loginProviderSchema, loginProviderStatusSchema, loginProviderTestSchema, loginSettingsSchema, maskedSecretSchema, myAccountSchema, myStoreSchema, oauthClientRegistrationRequestSchema, oauthClientRegistrationResponseSchema, oauthTokenResponseSchema, optionGroupRequestSchema, optionGroupSchema, optionModelRequestSchema, optionModelSchema, optionValueRequestSchema, optionValueSchema, orderItemListQuerySchema, orderItemMemoResultSchema, orderItemPageSchema, orderItemSchema, orderItemStatusSchema, orderListQuerySchema, orderSchema, orderSummaryPageSchema, orderSummarySchema, orderWebhookEventDataSchema, orderWebhookEventSchema, pageInfoSchema, pageQueryShape, pageSchema, paymentAttemptRecordSchema, paymentAttemptStatusSchema, paymentCredentialSetSchema, paymentListQuerySchema, paymentProviderSchema, paymentProviderVerificationSchema, paymentRecordDetailSchema, paymentRecordPageSchema, paymentRecordSchema, paymentRecordStatusSchema, paymentRefundRecordSchema, paymentSettingsSchema, pgEnvironmentSchema, pgPaymentMethodSchema, pgProviderSchema, pgVerificationResultSchema, portOneChannelSchema, portOneCredentialsInputSchema, productCreateRequestSchema, productImageUploadResultSchema, productListQuerySchema, productOutOfStockWebhookEventDataSchema, productOutOfStockWebhookEventSchema, productPatchRequestSchema, productSchema, productSortSchema, productStatusSchema, productSummarySchema, productVariantRequestSchema, productVariantSchema, purchaseDecisionExtendResultSchema, purchaseDecisionRequestResultSchema, refreshUserToken, rejectClaimRequestSchema, reviewListQuerySchema, reviewReportResultSchema, reviewSchema, reviewSortSchema, reviewWebhookEventDataSchema, reviewWebhookEventSchema, salesReportGroupBySchema, salesReportQuerySchema, salesReportRowSchema, salesReportSchema, salesTotalsSchema, saveLoginProviderRequestSchema, scopeAccessSchema, sellerAddressListQuerySchema, sellerAddressRequestSchema, sellerAddressSchema, sellerCustomerInquirySchema, settlementDetailQuerySchema, settlementDetailSchema, settlementListQuerySchema, settlementStatusSchema, settlementSummarySchema, settlementWithDetailsSchema, shippingAddressSchema, storeCodeSchema, storeMemberRoleUpdatedSchema, storeMemberSchema, storeRoleSchema, storeSchema, storeScopeResourceSchema, storeTokenResponseSchema, tossPaymentsCredentialsInputSchema, trackingUpdateResultSchema, updateLoginProviderRequestSchema, updateLoginSettingsRequestSchema, updatePaymentProviderRequestSchema, updatePaymentSettingsRequestSchema, updateStoreRequestSchema, uploadRequestSchema, uploadTicketSchema, upsertPortOneProviderRequestSchema, upsertTossPaymentsProviderRequestSchema, userTokenResponseSchema, variantStockRequestSchema, variantStockSchema, verifyPaymentProviderRequestSchema, webhookCreatedSchema, webhookDeliveryErrorCodeSchema, webhookDeliveryListQuerySchema, webhookDeliverySchema, webhookDeliveryStatusSchema, webhookEventSchema, webhookRedeliverFailedResultSchema, webhookRequestSchema, webhookSchema, webhookSecretRotatedSchema, webhookStatusSchema, webhookTestRequestSchema, webhookTestResultSchema, withdrawCustomerRequestSchema };
|