@sayren/storefront-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/auth/index.d.mts +22 -4
- package/dist/auth/index.mjs +42 -3
- package/dist/checkout-JFk3b8RG.mjs +189 -0
- package/dist/{client-Do9-LG5X.mjs → client-DwqExvZN.mjs} +114 -180
- package/dist/{http-CqAR0_w4.d.mts → http-BbFHVGBf.d.mts} +22 -1
- package/dist/index-BRXStiK2.d.mts +1998 -0
- package/dist/index.d.mts +3 -1530
- package/dist/index.mjs +3 -2
- package/dist/payments/index.d.mts +166 -0
- package/dist/payments/index.mjs +310 -0
- package/package.json +7 -2
- package/src/auth/index.ts +49 -2
- package/src/client.ts +51 -46
- package/src/payments/index.ts +541 -0
- package/src/schemas/auth.ts +25 -2
- package/src/schemas/catalog.ts +15 -4
- package/src/schemas/checkout.ts +148 -54
- package/src/schemas/inquiry.ts +8 -0
- package/src/schemas/member.ts +8 -0
- package/src/schemas/order.ts +19 -1
- package/src/schemas/review.ts +16 -0
- package/src/schemas/store.ts +1 -1
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { a as ANALYTICS_VISITOR_HEADER, r as ANALYTICS_SESSION_HEADER } from "./analytics-CgD70OqH.mjs";
|
|
2
|
+
import { a as createCheckoutRequestSchema, b as startPaymentRequestSchema, d as paymentMethodSchema, g as paymentStatusSchema, h as paymentStartSchema, i as checkoutSessionSchema, o as easyPayProviderResponseSchema, v as retryPaymentRequestSchema } from "./checkout-JFk3b8RG.mjs";
|
|
2
3
|
import { z } from "zod";
|
|
3
4
|
//#region src/http.ts
|
|
4
5
|
/** 표준 엔벨로프의 $.error 상세 */
|
|
@@ -178,11 +179,11 @@ const socialProviderSchema = z.enum([
|
|
|
178
179
|
]);
|
|
179
180
|
/** `POST /auth/idp/{provider}/authorize` 본문 — PKCE(S256)와 state는 SDK가 만든다 */
|
|
180
181
|
const idpAuthorizeRequestSchema = z.object({
|
|
181
|
-
/** 로그인을 마치고 돌아올
|
|
182
|
+
/** 로그인을 마치고 돌아올 스토어프론트 주소. 스토어프론트 도메인 목록 안이어야 한다 */
|
|
182
183
|
redirectUri: z.url(),
|
|
183
184
|
/** base64url(SHA-256(codeVerifier)) */
|
|
184
185
|
codeChallenge: z.string().regex(/^[A-Za-z0-9_-]{43}$/),
|
|
185
|
-
/**
|
|
186
|
+
/** 스토어프론트가 만든 값 — 돌아올 때 그대로 붙어 온다. 세션에 저장해 두고 비교한다 */
|
|
186
187
|
state: z.string().min(16).max(128)
|
|
187
188
|
});
|
|
188
189
|
const idpAuthorizeResponseSchema = z.object({
|
|
@@ -195,6 +196,23 @@ const idpTokenRequestSchema = z.object({
|
|
|
195
196
|
/** 비회원 장바구니 토큰 — 주면 회원 장바구니로 합친다 */
|
|
196
197
|
cartToken: z.string().optional()
|
|
197
198
|
});
|
|
199
|
+
/** `GET /me/identities` — 구매자의 로그인 수단(비밀번호 여부와 연결된 소셜 계정) */
|
|
200
|
+
const memberIdentitiesSchema = z.object({
|
|
201
|
+
hasPassword: z.boolean(),
|
|
202
|
+
/** 셀러 자체 회원 연동(구매자 위임)으로 들어온 구매자 — 그 로그인도 로그인 수단으로 센다 */
|
|
203
|
+
hasExternalAuth: z.boolean(),
|
|
204
|
+
identities: z.array(z.object({
|
|
205
|
+
provider: socialProviderSchema,
|
|
206
|
+
/** 공급자가 알려 준 이메일(참고값). 없을 수 있다 */
|
|
207
|
+
email: z.string().nullable(),
|
|
208
|
+
linkedAt: z.string()
|
|
209
|
+
}))
|
|
210
|
+
});
|
|
211
|
+
/** `POST /me/identities/{provider}` 본문 — 연결 흐름에서 돌아온 1회용 code와 PKCE verifier */
|
|
212
|
+
const linkIdentityRequestSchema = z.object({
|
|
213
|
+
code: z.string().min(1),
|
|
214
|
+
codeVerifier: z.string().regex(/^[A-Za-z0-9._~-]{43,128}$/)
|
|
215
|
+
});
|
|
198
216
|
//#endregion
|
|
199
217
|
//#region src/schemas/cart.ts
|
|
200
218
|
const cartItemSchema = z.object({
|
|
@@ -232,6 +250,38 @@ const updateCartItemRequestSchema = z.object({
|
|
|
232
250
|
optionId: z.string().optional()
|
|
233
251
|
}).refine((value) => Object.values(value).some((v) => v !== void 0), { message: "최소 1개 필드가 필요합니다" });
|
|
234
252
|
//#endregion
|
|
253
|
+
//#region src/schemas/common.ts
|
|
254
|
+
const pageInfoSchema = z.object({
|
|
255
|
+
page: z.number().int(),
|
|
256
|
+
size: z.number().int(),
|
|
257
|
+
totalElements: z.number().int(),
|
|
258
|
+
totalPages: z.number().int()
|
|
259
|
+
});
|
|
260
|
+
function pageSchema(item) {
|
|
261
|
+
return pageInfoSchema.extend({ contents: z.array(item) });
|
|
262
|
+
}
|
|
263
|
+
const orderItemStatusSchema = z.enum([
|
|
264
|
+
"PAYMENT_WAITING",
|
|
265
|
+
"PAID",
|
|
266
|
+
"CONFIRMED",
|
|
267
|
+
"DISPATCHED",
|
|
268
|
+
"DELIVERING",
|
|
269
|
+
"DELIVERED",
|
|
270
|
+
"PURCHASE_DECIDED",
|
|
271
|
+
"CANCELED"
|
|
272
|
+
]);
|
|
273
|
+
const claimStatusSchema = z.enum([
|
|
274
|
+
"REQUESTED",
|
|
275
|
+
"HELD",
|
|
276
|
+
"COLLECTING",
|
|
277
|
+
"COLLECTED",
|
|
278
|
+
"REDELIVERING",
|
|
279
|
+
"APPROVED",
|
|
280
|
+
"REJECTED",
|
|
281
|
+
"COMPLETED",
|
|
282
|
+
"WITHDRAWN"
|
|
283
|
+
]);
|
|
284
|
+
//#endregion
|
|
235
285
|
//#region src/schemas/catalog.ts
|
|
236
286
|
const categoryNodeSchema = z.lazy(() => z.object({
|
|
237
287
|
categoryId: z.string(),
|
|
@@ -243,9 +293,9 @@ const productCardSchema = z.object({
|
|
|
243
293
|
productId: z.string(),
|
|
244
294
|
name: z.string(),
|
|
245
295
|
thumbnailUrl: z.url(),
|
|
246
|
-
salePrice: z.number().int(),
|
|
247
|
-
discountedPrice: z.number().int().nullable(),
|
|
248
|
-
discountRate: z.number().int().nullable(),
|
|
296
|
+
salePrice: z.number().int().describe("판매가. 원(KRW) 단위 정수"),
|
|
297
|
+
discountedPrice: z.number().int().nullable().describe("즉시 할인 적용가. 원 단위. 할인이 없으면 null"),
|
|
298
|
+
discountRate: z.number().int().nullable().describe("할인율(%). 할인이 없으면 null"),
|
|
249
299
|
freeShipping: z.boolean(),
|
|
250
300
|
averageRating: z.number(),
|
|
251
301
|
reviewCount: z.number().int(),
|
|
@@ -312,145 +362,8 @@ const productFacetsSchema = z.object({
|
|
|
312
362
|
max: z.number().int()
|
|
313
363
|
}).optional()
|
|
314
364
|
});
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
const createCheckoutRequestSchema = z.object({
|
|
318
|
-
cartItemIds: z.array(z.string()).min(1).optional(),
|
|
319
|
-
directItem: z.object({
|
|
320
|
-
productId: z.string(),
|
|
321
|
-
optionId: z.string().optional(),
|
|
322
|
-
quantity: z.number().int().min(1)
|
|
323
|
-
}).optional()
|
|
324
|
-
}).refine((value) => value.cartItemIds ? !value.directItem : !!value.directItem, { message: "cartItemIds와 directItem 중 하나만 전달해야 합니다" });
|
|
325
|
-
const checkoutSessionSchema = z.object({
|
|
326
|
-
checkoutId: z.string(),
|
|
327
|
-
items: z.array(z.object({
|
|
328
|
-
productId: z.string(),
|
|
329
|
-
productName: z.string(),
|
|
330
|
-
/** variantId. 옵션 없는 상품은 default variant id */
|
|
331
|
-
optionId: z.string().nullable(),
|
|
332
|
-
optionName: z.string().nullable(),
|
|
333
|
-
quantity: z.number().int(),
|
|
334
|
-
unitPrice: z.number().int(),
|
|
335
|
-
totalPrice: z.number().int()
|
|
336
|
-
})),
|
|
337
|
-
amounts: z.object({
|
|
338
|
-
productAmount: z.number().int(),
|
|
339
|
-
deliveryFee: z.number().int(),
|
|
340
|
-
totalAmount: z.number().int()
|
|
341
|
-
}),
|
|
342
|
-
expiresAt: z.string(),
|
|
343
|
-
testPayment: z.boolean().describe("지금 결제하면 테스트 결제(샌드박스)인가. true면 실제로 돈이 나가지 않아요 — 주문서에 테스트 결제 안내를 표시해요. 결제 요청 시점에 스토어 결제 설정으로 다시 정해지니 최종 값은 결제 요청 응답의 `testPayment`예요")
|
|
344
|
-
});
|
|
345
|
-
const paymentMethodSchema = z.enum([
|
|
346
|
-
"CARD",
|
|
347
|
-
"BANK_TRANSFER",
|
|
348
|
-
"VIRTUAL_ACCOUNT",
|
|
349
|
-
"MOBILE",
|
|
350
|
-
"EASY_PAY"
|
|
351
|
-
]);
|
|
352
|
-
const shippingAddressInputSchema = z.object({
|
|
353
|
-
addressId: z.string().optional(),
|
|
354
|
-
receiverName: z.string().min(1, "수령인명을 입력해주세요").max(50),
|
|
355
|
-
phone: z.string().regex(/^01[0-9]{8,9}$/, "연락처 형식이 아닙니다 (예: 01012345678)"),
|
|
356
|
-
zipCode: z.string().regex(/^[0-9]{5}$/, "우편번호는 5자리 숫자입니다"),
|
|
357
|
-
address1: z.string().min(1, "기본 주소를 입력해주세요"),
|
|
358
|
-
address2: z.string().optional(),
|
|
359
|
-
deliveryMemo: z.string().max(100).optional(),
|
|
360
|
-
entranceCode: z.string().max(20).optional()
|
|
361
|
-
});
|
|
362
|
-
const guestInfoSchema = z.object({
|
|
363
|
-
name: z.string().min(1),
|
|
364
|
-
phone: z.string().regex(/^01[0-9]{8,9}$/),
|
|
365
|
-
email: z.email(),
|
|
366
|
-
orderPassword: z.string().min(6, "주문 조회 비밀번호는 6자 이상이어야 합니다")
|
|
367
|
-
});
|
|
368
|
-
const requestPaymentRequestSchema = z.object({
|
|
369
|
-
shippingAddress: shippingAddressInputSchema,
|
|
370
|
-
paymentMethod: paymentMethodSchema,
|
|
371
|
-
guest: guestInfoSchema.optional()
|
|
372
|
-
});
|
|
373
|
-
/**
|
|
374
|
-
* 결제창 파라미터. 스토어프론트가 쓰는 계약 값은 `popupUrl` 하나다(결제 팝업을 연다).
|
|
375
|
-
*
|
|
376
|
-
* 나머지는 결제 팝업 내부 값이라 선택 필드로만 타입을 준다(`attemptId`·`provider`·`mock`, 그리고
|
|
377
|
-
* 토스 `clientKey`·`orderId`…, 포트원 `storeId`·`channelKey`… 같은 PG별 결제창 값). 공개 값뿐이며
|
|
378
|
-
* 시크릿은 어떤 키에도 없다. 서버가 키를 추가·변경해도 파싱이 깨지지 않도록 모르는 키는 그대로 통과시킨다.
|
|
379
|
-
*/
|
|
380
|
-
const pgParamsSchema = z.looseObject({
|
|
381
|
-
popupUrl: z.string().describe("결제 팝업 진입 URL. `window.open`으로 띄운다"),
|
|
382
|
-
attemptId: z.string().optional().describe("첫 결제 시도 id(`att_…`). PG에 보내는 주문번호(토스 `orderId`, 포트원 `paymentId`)다. 팝업 내부 값"),
|
|
383
|
-
provider: z.string().optional().describe("첫 결제 시도의 PG (`pgProvider`와 같다). 팝업 내부 값"),
|
|
384
|
-
mock: z.boolean().optional().describe("모의 결제 여부. true면 결제 팝업이 PG SDK 대신 모의 결제 UI를 띄운다. 팝업 내부 값"),
|
|
385
|
-
environment: z.string().optional().describe("첫 결제 시도의 결제 환경 (`TEST` 샌드박스 · `LIVE` 실결제). 팝업 내부 값")
|
|
386
|
-
});
|
|
387
|
-
const paymentParamsSchema = z.object({
|
|
388
|
-
paymentId: z.string(),
|
|
389
|
-
pgProvider: z.string().describe("첫 결제 시도의 PG. 현재 값은 `tosspayments`·`portone`이다. PG가 추가될 수 있어 문자열로 받는다"),
|
|
390
|
-
pgParams: pgParamsSchema,
|
|
391
|
-
expiresAt: z.string(),
|
|
392
|
-
testPayment: z.boolean().describe("테스트 결제(샌드박스) 여부. true면 실제로 돈이 나가지 않는다 — 결제 화면에 테스트 결제 안내를 표시한다")
|
|
393
|
-
});
|
|
394
|
-
const confirmPaymentRequestSchema = z.object({
|
|
395
|
-
pgToken: z.string().min(1).describe("PG 승인 키 (토스 `paymentKey`, 포트원 `txId`)"),
|
|
396
|
-
attemptId: z.string().min(1).optional().describe("승인할 결제 시도 id (결제창이 돌려준 주문번호). 생략하면 현재 시도")
|
|
397
|
-
});
|
|
398
|
-
const confirmPaymentResultSchema = z.object({
|
|
399
|
-
orderId: z.string(),
|
|
400
|
-
status: z.literal("PAID"),
|
|
401
|
-
totalAmount: z.number().int(),
|
|
402
|
-
paidAt: z.string()
|
|
403
|
-
});
|
|
404
|
-
/**
|
|
405
|
-
* 결제 상태 조회의 현재 상태 값 — 응답 스키마는 서버가 상태를 추가해도 파싱이 깨지지 않게 문자열로 받는다
|
|
406
|
-
* (`pgProvider`와 같은 방식). 화면 분기는 이 목록으로 하고 모르는 값은 확인 중으로 다룬다.
|
|
407
|
-
*/
|
|
408
|
-
const PAYMENT_STATUS_VALUES = [
|
|
409
|
-
"pending",
|
|
410
|
-
"processing",
|
|
411
|
-
"completed",
|
|
412
|
-
"failed",
|
|
413
|
-
"expired"
|
|
414
|
-
];
|
|
415
|
-
const paymentStatusSchema = z.object({
|
|
416
|
-
paymentId: z.string(),
|
|
417
|
-
status: z.string().describe("결제 상태. 현재 값은 `pending` 결제 대기 · `processing` 승인 확인 중 · `completed` 결제 완료(주문 생성) · `failed` 실패 · `expired` 만료예요. 상태가 추가될 수 있어 문자열로 받아요 — 모르는 값은 `processing`처럼 다루고 계속 조회하세요"),
|
|
418
|
-
orderId: z.string().nullable().describe("결제가 완료됐으면 주문 번호, 그 외에는 null"),
|
|
419
|
-
testPayment: z.boolean().describe("테스트 결제(샌드박스)인가. true면 실제로 돈이 나가지 않았어요"),
|
|
420
|
-
expiresAt: z.string().describe("결제 요청 만료 시각")
|
|
421
|
-
});
|
|
422
|
-
//#endregion
|
|
423
|
-
//#region src/schemas/common.ts
|
|
424
|
-
const pageInfoSchema = z.object({
|
|
425
|
-
page: z.number().int(),
|
|
426
|
-
size: z.number().int(),
|
|
427
|
-
totalElements: z.number().int(),
|
|
428
|
-
totalPages: z.number().int()
|
|
429
|
-
});
|
|
430
|
-
function pageSchema(item) {
|
|
431
|
-
return pageInfoSchema.extend({ contents: z.array(item) });
|
|
432
|
-
}
|
|
433
|
-
const orderItemStatusSchema = z.enum([
|
|
434
|
-
"PAYMENT_WAITING",
|
|
435
|
-
"PAID",
|
|
436
|
-
"CONFIRMED",
|
|
437
|
-
"DISPATCHED",
|
|
438
|
-
"DELIVERING",
|
|
439
|
-
"DELIVERED",
|
|
440
|
-
"PURCHASE_DECIDED",
|
|
441
|
-
"CANCELED"
|
|
442
|
-
]);
|
|
443
|
-
const claimStatusSchema = z.enum([
|
|
444
|
-
"REQUESTED",
|
|
445
|
-
"HELD",
|
|
446
|
-
"COLLECTING",
|
|
447
|
-
"COLLECTED",
|
|
448
|
-
"REDELIVERING",
|
|
449
|
-
"APPROVED",
|
|
450
|
-
"REJECTED",
|
|
451
|
-
"COMPLETED",
|
|
452
|
-
"WITHDRAWN"
|
|
453
|
-
]);
|
|
365
|
+
/** `GET /products` 응답 — 상품 카드 페이지와 검색 패싯 */
|
|
366
|
+
const productPageSchema = pageSchema(productCardSchema).extend({ facets: productFacetsSchema.optional() });
|
|
454
367
|
//#endregion
|
|
455
368
|
//#region src/schemas/claim.ts
|
|
456
369
|
const claimTypeSchema = z.enum([
|
|
@@ -538,6 +451,11 @@ const createInquiryRequestSchema = z.object({
|
|
|
538
451
|
content: z.string().min(1).max(1e3),
|
|
539
452
|
secret: z.boolean().default(false)
|
|
540
453
|
});
|
|
454
|
+
/** `POST /products/{productId}/inquiries` 응답 */
|
|
455
|
+
const createInquiryResultSchema = z.object({
|
|
456
|
+
inquiryId: z.string(),
|
|
457
|
+
createdAt: z.string()
|
|
458
|
+
});
|
|
541
459
|
//#endregion
|
|
542
460
|
//#region src/schemas/member.ts
|
|
543
461
|
const memberSchema = z.object({
|
|
@@ -574,6 +492,11 @@ const memberAddressRequestSchema = z.object({
|
|
|
574
492
|
address2: z.string().optional(),
|
|
575
493
|
isDefault: z.boolean().default(false)
|
|
576
494
|
});
|
|
495
|
+
/** `POST /me/wishlist` 응답 — 이미 찜한 상품이어도 같은 응답이다 */
|
|
496
|
+
const wishlistAddResultSchema = z.object({
|
|
497
|
+
productId: z.string(),
|
|
498
|
+
wished: z.literal(true)
|
|
499
|
+
});
|
|
577
500
|
//#endregion
|
|
578
501
|
//#region src/schemas/order.ts
|
|
579
502
|
const myOrderItemSchema = z.object({
|
|
@@ -609,6 +532,7 @@ const myOrderSchema = z.object({
|
|
|
609
532
|
shippingAddress: orderShippingAddressSchema,
|
|
610
533
|
payment: z.object({
|
|
611
534
|
method: paymentMethodSchema.describe("실제 결제수단(PG가 보고한 수단, 모르면 주문서에서 고른 수단). 결제창에서 바뀔 수 있다(카드 결제창의 간편결제 탭 등)"),
|
|
535
|
+
easyPayProvider: easyPayProviderResponseSchema.nullable().optional().default(null).describe("간편결제사. `method`가 `EASY_PAY`일 때만 값이 있고, PG가 알려 주지 않았으면 주문서에서 고른 간편결제사다. 그 밖의 결제수단과 간편결제 이전 주문은 null. 서버는 항상 싣는다. 현재 값은 `NAVERPAY`·`KAKAOPAY`·`TOSSPAY`·`PAYCO`이고 값이 추가될 수 있어 문자열로 받는다"),
|
|
612
536
|
totalAmount: z.number().int(),
|
|
613
537
|
paidAt: z.string().nullable(),
|
|
614
538
|
receiptUrl: z.url().nullable()
|
|
@@ -630,6 +554,12 @@ const deliveryTrackingSchema = z.object({
|
|
|
630
554
|
occurredAt: z.string()
|
|
631
555
|
}))
|
|
632
556
|
});
|
|
557
|
+
/** `POST /me/order-items/{orderItemId}/purchase-decision` 응답 */
|
|
558
|
+
const purchaseDecisionResultSchema = z.object({
|
|
559
|
+
orderItemId: z.string(),
|
|
560
|
+
status: z.literal("PURCHASE_DECIDED"),
|
|
561
|
+
decidedAt: z.string()
|
|
562
|
+
});
|
|
633
563
|
//#endregion
|
|
634
564
|
//#region src/schemas/review.ts
|
|
635
565
|
const publicReviewSchema = z.object({
|
|
@@ -672,10 +602,17 @@ const updateReviewRequestSchema = z.object({
|
|
|
672
602
|
content: z.string().min(10).max(2e3).optional(),
|
|
673
603
|
images: z.array(z.url()).max(5).optional()
|
|
674
604
|
}).refine((value) => Object.values(value).some((v) => v !== void 0), { message: "최소 1개 필드가 필요합니다" });
|
|
605
|
+
/** `GET /products/{productId}/reviews` 응답 — 리뷰 페이지와 평점 분포 */
|
|
606
|
+
const reviewPageSchema = pageSchema(publicReviewSchema).extend({ summary: reviewSummarySchema.optional() });
|
|
607
|
+
/** `PUT /me/reviews/{reviewId}` 응답 */
|
|
608
|
+
const updateReviewResultSchema = z.object({
|
|
609
|
+
reviewId: z.string(),
|
|
610
|
+
updatedAt: z.string()
|
|
611
|
+
});
|
|
675
612
|
//#endregion
|
|
676
613
|
//#region src/schemas/store.ts
|
|
677
614
|
/**
|
|
678
|
-
* 스토어 공개 설정 — `GET /store`.
|
|
615
|
+
* 스토어 공개 설정 — `GET /store`. 스토어프론트가 화면을 그릴 때 읽는 값만 담는다.
|
|
679
616
|
*/
|
|
680
617
|
const storefrontStoreSchema = z.object({
|
|
681
618
|
storeCode: z.string(),
|
|
@@ -700,8 +637,6 @@ const storefrontStoreSchema = z.object({
|
|
|
700
637
|
});
|
|
701
638
|
//#endregion
|
|
702
639
|
//#region src/client.ts
|
|
703
|
-
const productPageSchema = pageSchema(productCardSchema).extend({ facets: productFacetsSchema.optional() });
|
|
704
|
-
const reviewPageSchema = pageSchema(publicReviewSchema).extend({ summary: reviewSummarySchema.optional() });
|
|
705
640
|
function createStorefrontClient(options) {
|
|
706
641
|
const { session } = options;
|
|
707
642
|
const accessTokenSource = options.accessToken ?? options.auth?.accessToken ?? (session ? () => session.accessToken : void 0);
|
|
@@ -757,7 +692,15 @@ function createStorefrontClient(options) {
|
|
|
757
692
|
/** 소셜 로그인 마무리 — 돌아온 1회용 code + codeVerifier를 구매자 토큰으로 바꾼다 */
|
|
758
693
|
idpToken: (body) => http.request("POST", "/auth/idp/token", tokenPairSchema, { body: idpTokenRequestSchema.parse(body) }),
|
|
759
694
|
/** 구매자 탈퇴 — 로그인 상태(accessToken)에서 비밀번호로 본인 확인. 성공하면 토큰은 모두 무효 */
|
|
760
|
-
withdraw: (body) => http.requestVoid("POST", "/auth/withdraw", { body: withdrawRequestSchema.parse(body) })
|
|
695
|
+
withdraw: (body) => http.requestVoid("POST", "/auth/withdraw", { body: withdrawRequestSchema.parse(body) }),
|
|
696
|
+
/** 로그인 수단 — 비밀번호 여부와 연결된 소셜 계정(로그인 필요) */
|
|
697
|
+
identities: () => http.request("GET", "/me/identities", memberIdentitiesSchema),
|
|
698
|
+
/** 소셜 계정 연결 시작(로그인 필요) — 공급자 로그인 주소를 받는다. 본문은 `idpAuthorize`와 같다 */
|
|
699
|
+
linkIdentityAuthorize: (provider, body) => http.request("POST", path`/me/identities/${provider}/authorize`, idpAuthorizeResponseSchema, { body: idpAuthorizeRequestSchema.parse(body) }),
|
|
700
|
+
/** 소셜 계정 연결 마무리 — 돌아온 code + codeVerifier로 이 구매자에 연결한다 */
|
|
701
|
+
linkIdentity: (provider, body) => http.request("POST", path`/me/identities/${provider}`, memberIdentitiesSchema, { body: linkIdentityRequestSchema.parse(body) }),
|
|
702
|
+
/** 소셜 계정 연결 해제 — 마지막 로그인 수단이면 409 `LAST_LOGIN_METHOD` */
|
|
703
|
+
unlinkIdentity: (provider) => http.request("DELETE", path`/me/identities/${provider}`, memberIdentitiesSchema)
|
|
761
704
|
},
|
|
762
705
|
store: {
|
|
763
706
|
/** 스토어 공개 설정 — 이름·고객센터·비회원 주문 허용 여부 */
|
|
@@ -779,43 +722,34 @@ get: () => http.request("GET", "/store", storefrontStoreSchema) },
|
|
|
779
722
|
checkout: {
|
|
780
723
|
create: (body) => http.request("POST", "/checkout", checkoutSessionSchema, { body: createCheckoutRequestSchema.parse(body) }),
|
|
781
724
|
/**
|
|
782
|
-
*
|
|
783
|
-
*
|
|
725
|
+
* `POST /checkout/{checkoutId}/payment` — 결제 시작. 배송지와 결제 옵션(`paymentOptions` 항목 또는 직접 쓴 옵션)으로
|
|
726
|
+
* 결제 세션·첫 시도를 만들고 결제 서비스 주소(`payUrl`)를 돌려준다. 그 주소를 열어 결제를 진행하는 것은
|
|
727
|
+
* `@sayren/storefront-sdk/payments`의 `createPayments().start()`다 — 이 메서드는 값만 받는다.
|
|
784
728
|
*
|
|
785
|
-
*
|
|
786
|
-
* - 409 `
|
|
787
|
-
* -
|
|
729
|
+
* 에러(`ApiError.code`):
|
|
730
|
+
* - 409 `PAYMENT_OPTION_UNAVAILABLE`: 이 스토어에서 쓸 수 없는 옵션. `details.paymentOptions`에 지금 목록
|
|
731
|
+
* - 409 `PAYMENT_NOT_CONFIGURED`: 사용 중인 PG가 없다
|
|
732
|
+
* - 400 `RETURN_URL_NOT_ALLOWED`: `returnUrl`이 https가 아니거나(테스트 결제의 localhost는 예외),
|
|
733
|
+
* 스토어가 결제 도메인을 등록했는데 그 안이 아니다. 등록하지 않았으면 https 주소는 모두 받는다
|
|
734
|
+
* - 503 `PAYMENT_PROVIDER_UNAVAILABLE`: 고른 PG의 결제창을 준비하지 못했다(다른 옵션으로 다시 시도)
|
|
788
735
|
*/
|
|
789
|
-
|
|
736
|
+
startPayment: (checkoutId, body) => http.request("POST", path`/checkout/${checkoutId}/payment`, paymentStartSchema, { body: startPaymentRequestSchema.parse(body) })
|
|
737
|
+
},
|
|
738
|
+
payments: {
|
|
790
739
|
/**
|
|
791
|
-
*
|
|
792
|
-
* `
|
|
740
|
+
* `GET /storefront/v1/payments/{paymentId}` — 결제 상태 조회. 복귀 화면에서 결과가 확인 중(`processing`)이면
|
|
741
|
+
* `expiresAt`까지 폴링한다. `completed`면 `orderId`로 완료 화면, `failed`·`expired`면 실패 안내다.
|
|
742
|
+
* TTL이 지난 `pending`은 `expired`로 보고된다. `testPayment`는 완료면 주문 플래그, 아니면 세션 환경이다.
|
|
793
743
|
*
|
|
794
|
-
*
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
*
|
|
799
|
-
*
|
|
800
|
-
* 409 `PAYMENT_RESULT_UNKNOWN`은 결과 확인 중이라 재시도하면 안 된다. 그 밖의 409:
|
|
801
|
-
* `ATTEMPT_NOT_CURRENT`·`INVALID_ATTEMPT_STATE`·`PAYMENT_SESSION_OUTDATED`·`PG_AMOUNT_MISMATCH`.
|
|
802
|
-
* 503 `PG_MERCHANT_MISMATCH`: 승인 시도의 가맹점과 현재 저장된 자격 증명의 가맹점이 다르다.
|
|
744
|
+
* 에러: 404 `PAYMENT_NOT_FOUND`(없음·다른 스토어) · 410 `STORE_CLOSED` · 503 `STORE_SUSPENDED`
|
|
745
|
+
*/
|
|
746
|
+
getStatus: (paymentId) => http.request("GET", path`/payments/${paymentId}`, paymentStatusSchema),
|
|
747
|
+
/**
|
|
748
|
+
* `POST /payments/{paymentId}/attempts` — 같은 결제에서 다른 결제 옵션으로 다시 시도한다. 새 시도의 결제창 값을
|
|
749
|
+
* 돌려준다. 승인 중이거나 결과 확인 중이면 409 `PAYMENT_IN_PROGRESS`다.
|
|
803
750
|
*/
|
|
804
|
-
|
|
805
|
-
pgToken,
|
|
806
|
-
attemptId: options?.attemptId
|
|
807
|
-
}) })
|
|
751
|
+
retry: (paymentId, body) => http.request("POST", path`/payments/${paymentId}/attempts`, paymentStartSchema, { body: retryPaymentRequestSchema.parse(body) })
|
|
808
752
|
},
|
|
809
|
-
payments: {
|
|
810
|
-
/**
|
|
811
|
-
* `GET /storefront/v1/payments/{paymentId}` — 결제 상태 조회. 결제 팝업이 결과(postMessage)를 알리지 못하고 닫혔을 때
|
|
812
|
-
* 부모 창이 `expiresAt`까지 폴링해 결과를 확인한다. `completed`면 `orderId`로 완료 화면, `processing`이면 계속 폴링,
|
|
813
|
-
* `pending`이면 기존 안내, `failed`·`expired`면 실패 안내다. TTL이 지난 `pending`은 `expired`로 보고된다.
|
|
814
|
-
* `testPayment`는 완료면 주문 플래그, 아니면 세션 환경이다.
|
|
815
|
-
*
|
|
816
|
-
* 에러: 404 `PAYMENT_NOT_FOUND`(없음·다른 스토어) · 410 `STORE_CLOSED` · 503 `STORE_SUSPENDED`
|
|
817
|
-
*/
|
|
818
|
-
getStatus: (paymentId) => http.request("GET", path`/payments/${paymentId}`, paymentStatusSchema) },
|
|
819
753
|
myOrders: {
|
|
820
754
|
list: (params) => http.request("GET", "/me/orders", pageSchema(myOrderSchema), { query: params }),
|
|
821
755
|
get: (orderId) => http.request("GET", path`/me/orders/${orderId}`, myOrderSchema),
|
|
@@ -854,4 +788,4 @@ getStatus: (paymentId) => http.request("GET", path`/payments/${paymentId}`, paym
|
|
|
854
788
|
};
|
|
855
789
|
}
|
|
856
790
|
//#endregion
|
|
857
|
-
export {
|
|
791
|
+
export { signupRequestSchema as $, createClaimResultSchema as A, pageInfoSchema as B, publicInquirySchema as C, claimReasonSchema as D, customerInquirySchema as E, productFacetsSchema as F, updateCartItemRequestSchema as G, addCartItemRequestSchema as H, productPageSchema as I, idpAuthorizeResponseSchema as J, anonymousSessionSchema as K, productSortSchema as L, categoryNodeSchema as M, productCardSchema as N, claimTypeSchema as O, productDetailSchema as P, memberIdentitiesSchema as Q, claimStatusSchema as R, createInquiryResultSchema as S, customerInquiryCategorySchema as T, cartItemSchema as U, pageSchema as V, cartSchema as W, linkIdentityRequestSchema as X, idpTokenRequestSchema as Y, loginRequestSchema as Z, memberAddressSchema as _, publicReviewSchema as a, buildQuery as at, wishlistAddResultSchema as b, updateReviewRequestSchema as c, deliveryTrackingSchema as d, socialProviderSchema as et, myOrderItemSchema as f, memberAddressRequestSchema as g, purchaseDecisionResultSchema as h, createReviewResultSchema as i, ApiError as it, myClaimSchema as j, createClaimRequestSchema as k, updateReviewResultSchema as l, orderShippingAddressSchema as m, storefrontStoreSchema as n, withdrawRequestSchema as nt, reviewPageSchema as o, toApiError as ot, myOrderSchema as p, idpAuthorizeRequestSchema as q, createReviewRequestSchema as r, withdrawalBlockedDetailsSchema as rt, reviewSummarySchema as s, unwrapData as st, createStorefrontClient as t, tokenPairSchema as tt, writableReviewSchema as u, memberSchema as v, createCustomerInquiryRequestSchema as w, createInquiryRequestSchema as x, updateProfileRequestSchema as y, orderItemStatusSchema as z };
|
|
@@ -75,6 +75,27 @@ declare const idpTokenRequestSchema: z.ZodObject<{
|
|
|
75
75
|
cartToken: z.ZodOptional<z.ZodString>;
|
|
76
76
|
}, z.core.$strip>;
|
|
77
77
|
type IdpTokenRequest = z.infer<typeof idpTokenRequestSchema>;
|
|
78
|
+
/** `GET /me/identities` — 구매자의 로그인 수단(비밀번호 여부와 연결된 소셜 계정) */
|
|
79
|
+
declare const memberIdentitiesSchema: z.ZodObject<{
|
|
80
|
+
hasPassword: z.ZodBoolean;
|
|
81
|
+
hasExternalAuth: z.ZodBoolean;
|
|
82
|
+
identities: z.ZodArray<z.ZodObject<{
|
|
83
|
+
provider: z.ZodEnum<{
|
|
84
|
+
kakao: "kakao";
|
|
85
|
+
naver: "naver";
|
|
86
|
+
google: "google";
|
|
87
|
+
}>;
|
|
88
|
+
email: z.ZodNullable<z.ZodString>;
|
|
89
|
+
linkedAt: z.ZodString;
|
|
90
|
+
}, z.core.$strip>>;
|
|
91
|
+
}, z.core.$strip>;
|
|
92
|
+
type MemberIdentities = z.infer<typeof memberIdentitiesSchema>;
|
|
93
|
+
/** `POST /me/identities/{provider}` 본문 — 연결 흐름에서 돌아온 1회용 code와 PKCE verifier */
|
|
94
|
+
declare const linkIdentityRequestSchema: z.ZodObject<{
|
|
95
|
+
code: z.ZodString;
|
|
96
|
+
codeVerifier: z.ZodString;
|
|
97
|
+
}, z.core.$strip>;
|
|
98
|
+
type LinkIdentityRequest = z.infer<typeof linkIdentityRequestSchema>;
|
|
78
99
|
//#endregion
|
|
79
100
|
//#region src/http.d.ts
|
|
80
101
|
declare class ApiError extends Error {
|
|
@@ -92,4 +113,4 @@ type TokenSource = string | null | undefined | (() => string | null | undefined)
|
|
|
92
113
|
type Query = Record<string, string | number | boolean | undefined>;
|
|
93
114
|
declare function buildQuery(query?: Query): string;
|
|
94
115
|
//#endregion
|
|
95
|
-
export {
|
|
116
|
+
export { signupRequestSchema as C, withdrawalBlockedDetailsSchema as D, withdrawRequestSchema as E, memberIdentitiesSchema as S, tokenPairSchema as T, idpAuthorizeRequestSchema as _, AnonymousSession as a, linkIdentityRequestSchema as b, LinkIdentityRequest as c, SignupRequest as d, SocialProvider as f, anonymousSessionSchema as g, WithdrawalBlockedDetails as h, buildQuery as i, LoginRequest as l, WithdrawRequest as m, Query as n, IdpAuthorizeRequest as o, TokenPair as p, TokenSource as r, IdpTokenRequest as s, ApiError as t, MemberIdentities as u, idpAuthorizeResponseSchema as v, socialProviderSchema as w, loginRequestSchema as x, idpTokenRequestSchema as y };
|