@sayren/store-sdk 0.64.0 → 0.66.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 +167 -26
- package/dist/index.mjs +96 -14
- package/package.json +1 -1
- package/src/client.ts +21 -5
- package/src/schemas/ai.ts +23 -0
- package/src/schemas/app-manifest.ts +1 -0
- package/src/schemas/claim.ts +59 -1
- package/src/schemas/misc.ts +2 -0
- package/src/schemas/order.ts +52 -2
- package/src/schemas/payment.ts +19 -1
- package/src/schemas/webhook-event.ts +38 -2
package/src/schemas/order.ts
CHANGED
|
@@ -690,6 +690,16 @@ export const cancelBySellerRequestSchema = strictRequest(
|
|
|
690
690
|
.describe(
|
|
691
691
|
"환불액에서 뺄 추가 차감(#301, 원). 생략하면 0이다. 현금에서 먼저 빼고 모자란 몫만 돌려줄 적립금에서 뺀다. 환불 원장·`ORDER.CANCELED` 웹훅에 따로 남는다",
|
|
692
692
|
),
|
|
693
|
+
refundAmount: z
|
|
694
|
+
.number()
|
|
695
|
+
.int()
|
|
696
|
+
.min(0)
|
|
697
|
+
.optional()
|
|
698
|
+
.describe(
|
|
699
|
+
"최종 현금 환불액(#365, 원). 생략하면 서버 계산값이다. 배송비 환불 여부·귀책과 무관하게 판매자가 정한다. " +
|
|
700
|
+
"배송비·쿠폰 정산 기록과 적립금 반환은 계산값대로 하고 현금만 이 값이다. 결제 잔액(`availableRefundAmount`)을 넘으면 409 `REFUND_EXCEEDS_BALANCE`. " +
|
|
701
|
+
"`deductAmount`와 함께 주면 400이다. 응답·웹훅의 `calculatedRefundAmount`가 서버 계산값이다",
|
|
702
|
+
),
|
|
693
703
|
restock: z
|
|
694
704
|
.boolean()
|
|
695
705
|
.optional()
|
|
@@ -705,10 +715,43 @@ export const cancelBySellerRequestSchema = strictRequest(
|
|
|
705
715
|
"회원 잔액이 모자라면 있는 만큼만 회수한다(리뷰 적립 회수와 같은 규칙)",
|
|
706
716
|
),
|
|
707
717
|
}),
|
|
708
|
-
)
|
|
718
|
+
).refine((body) => body.refundAmount === undefined || body.deductAmount === undefined, {
|
|
719
|
+
message: "refundAmount와 deductAmount는 함께 줄 수 없습니다",
|
|
720
|
+
path: ["refundAmount"],
|
|
721
|
+
});
|
|
709
722
|
|
|
710
723
|
export type CancelBySellerRequest = z.infer<typeof cancelBySellerRequestSchema>;
|
|
711
724
|
|
|
725
|
+
/**
|
|
726
|
+
* 금액만 환불 요청(#365) — `POST /v1/orders/{orderId}/refunds`. 주문상품 상태·수량·재고·적립금·쿠폰·배송비 정산을 바꾸지 않고
|
|
727
|
+
* 결제에서 금액만 돌려준다. 헤더 `Idempotency-Key`가 필수다
|
|
728
|
+
*/
|
|
729
|
+
export const sellerRefundRequestSchema = strictRequest(
|
|
730
|
+
z.object({
|
|
731
|
+
amount: z
|
|
732
|
+
.number()
|
|
733
|
+
.int()
|
|
734
|
+
.min(1)
|
|
735
|
+
.describe(
|
|
736
|
+
"돌려줄 현금 (원). 결제의 남은 금액(결제 상세 `availableRefundAmount`)을 넘으면 409 `REFUND_EXCEEDS_BALANCE`",
|
|
737
|
+
),
|
|
738
|
+
reason: z
|
|
739
|
+
.string()
|
|
740
|
+
.trim()
|
|
741
|
+
.min(1)
|
|
742
|
+
.max(500)
|
|
743
|
+
.describe("환불 사유. 감사 로그와 결제 상세 환불 이력에 남는다"),
|
|
744
|
+
paymentId: z
|
|
745
|
+
.string()
|
|
746
|
+
.optional()
|
|
747
|
+
.describe(
|
|
748
|
+
"환불할 결제(주문 응답 `payments[].paymentId`). 생략하면 주문의 첫 결제다. 추가 결제가 있는 주문은 이 값으로 고른다",
|
|
749
|
+
),
|
|
750
|
+
}),
|
|
751
|
+
);
|
|
752
|
+
|
|
753
|
+
export type SellerRefundRequest = z.infer<typeof sellerRefundRequestSchema>;
|
|
754
|
+
|
|
712
755
|
/**
|
|
713
756
|
* 제공 처리 요청 (이슈 #48) — `POST /v1/order-items/{orderItemId}/fulfill`. 배송 없는 주문상품(`MANUAL`)을
|
|
714
757
|
* 제공 완료(`DELIVERED`)로 바꾼다.
|
|
@@ -744,7 +787,14 @@ export const cancelBySellerResultSchema = z.object({
|
|
|
744
787
|
.int()
|
|
745
788
|
.describe(
|
|
746
789
|
"실제 환불한 금액 — 수량 비율 상품 실결제 금액(쿠폰 배분을 뺀 금액) + 배송비 환불 − 조건부 무료배송 미달 차감 " +
|
|
747
|
-
"− 쿠폰 조건 미달 차감 + 되돌린 쿠폰 차감(`couponChargeRefundAmount`) − 추가 차감(`deductAmount`)",
|
|
790
|
+
"− 쿠폰 조건 미달 차감 + 되돌린 쿠폰 차감(`couponChargeRefundAmount`) − 추가 차감(`deductAmount`). 판매자가 `refundAmount`를 정했으면 그 값이다",
|
|
791
|
+
),
|
|
792
|
+
calculatedRefundAmount: z
|
|
793
|
+
.number()
|
|
794
|
+
.int()
|
|
795
|
+
.optional()
|
|
796
|
+
.describe(
|
|
797
|
+
"서버가 계산한 현금 환불액(#365). 판매자가 `refundAmount`를 정하지 않았으면 `refundAmount`와 같다. 이 필드가 없는 이전 응답은 `refundAmount`와 같다고 읽는다",
|
|
748
798
|
),
|
|
749
799
|
quantity: z.number().int().describe("취소한 수량"),
|
|
750
800
|
canceledQuantity: z.number().int().describe("취소 후 누적 취소 수량"),
|
package/src/schemas/payment.ts
CHANGED
|
@@ -910,10 +910,21 @@ export const paymentRefundRecordSchema = z.object({
|
|
|
910
910
|
.optional()
|
|
911
911
|
.default(0)
|
|
912
912
|
.describe("같은 환불에서 돌려준 적립금 (#93). 적립금을 쓰지 않은 결제는 0"),
|
|
913
|
+
calculatedAmount: z
|
|
914
|
+
.number()
|
|
915
|
+
.int()
|
|
916
|
+
.nullable()
|
|
917
|
+
.optional()
|
|
918
|
+
.default(null)
|
|
919
|
+
.describe(
|
|
920
|
+
"서버가 계산한 현금 환불액 (#365). 판매자가 최종 금액을 정했으면 `amount`와 다르다. 계산이 없는 환불(결제 오류 보상 등)과 이전 환불은 null이다",
|
|
921
|
+
),
|
|
913
922
|
reason: z.string().describe("환불 사유 코드"),
|
|
914
923
|
kind: z
|
|
915
924
|
.string()
|
|
916
|
-
.describe(
|
|
925
|
+
.describe(
|
|
926
|
+
"환불 원인 — SELLER_CANCEL·CLAIM·SELLER_REFUND(금액만 환불)·COMPENSATION·DUPLICATE. 새 값이 추가될 수 있다",
|
|
927
|
+
),
|
|
917
928
|
status: z
|
|
918
929
|
.string()
|
|
919
930
|
.describe(
|
|
@@ -927,6 +938,13 @@ export type PaymentRefundRecord = z.infer<typeof paymentRefundRecordSchema>;
|
|
|
927
938
|
|
|
928
939
|
export const paymentRecordDetailSchema = paymentRecordSchema.extend({
|
|
929
940
|
refundableAmount: z.number().int().describe("환불 가능 잔액 = 승인 금액 - 환불 완료 금액"),
|
|
941
|
+
availableRefundAmount: z
|
|
942
|
+
.number()
|
|
943
|
+
.int()
|
|
944
|
+
.optional()
|
|
945
|
+
.describe(
|
|
946
|
+
"지금 더 환불할 수 있는 금액 = 승인 금액 - (환불 완료 + 처리 중 + 대기 환불). 이보다 큰 환불은 409 `REFUND_EXCEEDS_BALANCE`다. 승인되지 않은 결제는 0. 이 필드가 없는 이전 api는 `refundableAmount`로 읽는다",
|
|
947
|
+
),
|
|
930
948
|
merchantId: z
|
|
931
949
|
.string()
|
|
932
950
|
.nullable()
|
|
@@ -177,7 +177,14 @@ export const orderCanceledWebhookEventDataSchema = z.object({
|
|
|
177
177
|
.describe(
|
|
178
178
|
"환불액 (원). 수량 비율 상품 실결제 금액(쿠폰 배분을 뺀 금액) + 배송비 환불 − 조건부 무료배송 미달 차감 " +
|
|
179
179
|
"− 쿠폰 조건 미달 차감 + 되돌린 쿠폰 차감(`couponChargeRefundAmount`) − 추가 차감(`deductAmount`)이다. " +
|
|
180
|
-
"결제사 환불 결과는 결제 내역(`GET /v1/payments/{paymentId}`)으로 확인한다",
|
|
180
|
+
"판매자가 `refundAmount`를 정했으면 그 값이다. 결제사 환불 결과는 결제 내역(`GET /v1/payments/{paymentId}`)으로 확인한다",
|
|
181
|
+
),
|
|
182
|
+
calculatedRefundAmount: z
|
|
183
|
+
.number()
|
|
184
|
+
.int()
|
|
185
|
+
.optional()
|
|
186
|
+
.describe(
|
|
187
|
+
"서버가 계산한 환불액 (원, #365). 판매자가 최종 금액을 정하지 않았으면 `refundAmount`와 같다. 이 필드가 없는 이전 이벤트는 `refundAmount`와 같다고 읽는다",
|
|
181
188
|
),
|
|
182
189
|
deliveryFeeRefundAmount: z.number().int().describe("환불액에 포함된 배송비 (원)"),
|
|
183
190
|
deliveryFeeChargeAmount: z
|
|
@@ -257,9 +264,16 @@ export const claimWebhookEventDataSchema = z.object({
|
|
|
257
264
|
.optional()
|
|
258
265
|
.default(null)
|
|
259
266
|
.describe(
|
|
260
|
-
"환불액 (원). 배송비 환불을 포함하고 배송비 차감·추가 차감을 뺀 실제 금액이다. " +
|
|
267
|
+
"환불액 (원). 배송비 환불을 포함하고 배송비 차감·추가 차감을 뺀 실제 금액이다. 판매자가 승인에 최종 금액을 정했으면 그 값이다. " +
|
|
261
268
|
"환불이 확정되지 않은 접수 이벤트는 예상 환불액이고, 교환처럼 환불이 없으면 null이다",
|
|
262
269
|
),
|
|
270
|
+
calculatedRefundAmount: z
|
|
271
|
+
.number()
|
|
272
|
+
.int()
|
|
273
|
+
.optional()
|
|
274
|
+
.describe(
|
|
275
|
+
"서버가 계산한 환불액 (원, #365) — 완료 이벤트(`CLAIM.COMPLETED`)에만 싣는다. 판매자가 최종 금액을 정하지 않았으면 `refundAmount`와 같다. 이 필드가 없는 이벤트는 `refundAmount`와 같다고 읽는다",
|
|
276
|
+
),
|
|
263
277
|
deliveryFeeRefundAmount: z
|
|
264
278
|
.number()
|
|
265
279
|
.int()
|
|
@@ -542,6 +556,27 @@ export const orderPaymentRequestedWebhookEventSchema = z.object({
|
|
|
542
556
|
data: orderPaymentRequestedWebhookEventDataSchema,
|
|
543
557
|
});
|
|
544
558
|
|
|
559
|
+
/**
|
|
560
|
+
* 금액만 환불(#365) — 판매자가 주문상품을 취소하지 않고 결제에서 금액만 돌려주기로 했다. 결제사 환불 결과는 결제 상세
|
|
561
|
+
* (`GET /v1/payments/{paymentId}`의 `refunds[]`, `refundId`)로 확인한다. 개인정보는 싣지 않는다
|
|
562
|
+
*/
|
|
563
|
+
export const orderRefundedWebhookEventDataSchema = z.object({
|
|
564
|
+
orderId: z.string().describe("주문 ID"),
|
|
565
|
+
orderNo: z.string().nullable().describe("주문번호. 번호 체계 이전 주문은 null"),
|
|
566
|
+
paymentId: z.string().describe("환불한 결제"),
|
|
567
|
+
refundId: z.string().describe("환불 이력 id(결제 상세 `refunds[].refundId`)"),
|
|
568
|
+
amount: z.number().int().describe("돌려준 현금 (원)"),
|
|
569
|
+
reason: z.string().describe("판매자가 적은 환불 사유"),
|
|
570
|
+
currency: z.string().describe("주문 통화"),
|
|
571
|
+
testPayment: z.boolean(),
|
|
572
|
+
});
|
|
573
|
+
|
|
574
|
+
export const orderRefundedWebhookEventSchema = z.object({
|
|
575
|
+
...envelopeFields,
|
|
576
|
+
type: z.literal("ORDER.REFUNDED"),
|
|
577
|
+
data: orderRefundedWebhookEventDataSchema,
|
|
578
|
+
});
|
|
579
|
+
|
|
545
580
|
/** 웹훅 요청 본문. `type`으로 판별하며 `data` 형태가 타입별로 다르다 */
|
|
546
581
|
export const webhookEventSchema = z
|
|
547
582
|
.discriminatedUnion("type", [
|
|
@@ -557,6 +592,7 @@ export const webhookEventSchema = z
|
|
|
557
592
|
inventoryChangedWebhookEventSchema,
|
|
558
593
|
orderPaymentAddedWebhookEventSchema,
|
|
559
594
|
orderPaymentRequestedWebhookEventSchema,
|
|
595
|
+
orderRefundedWebhookEventSchema,
|
|
560
596
|
])
|
|
561
597
|
.describe(
|
|
562
598
|
"웹훅 요청 본문 (얇은 이벤트). 개인정보를 싣지 않으며 `data`의 id로 관리 API를 조회한다",
|