@sayren/store-sdk 0.30.3 → 0.30.5
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 +506 -437
- package/dist/index.mjs +43 -16
- package/package.json +1 -1
- package/src/client.ts +19 -2
- package/src/schemas/audit.ts +12 -0
- package/src/schemas/claim.ts +5 -0
- package/src/schemas/commerce-flow.ts +41 -9
- package/src/schemas/order.ts +15 -1
- package/src/schemas/payment.ts +16 -1
- package/src/schemas/points.ts +3 -1
package/dist/index.mjs
CHANGED
|
@@ -92,6 +92,7 @@ const writePreviewSchema = z.object({
|
|
|
92
92
|
type: z.string(),
|
|
93
93
|
id: z.string().nullable()
|
|
94
94
|
}),
|
|
95
|
+
targetName: z.string().nullable().optional().describe("대상 이름(상품명·쿠폰명·흐름 이름·구매자 이름 등). 읽을 수 없으면 null"),
|
|
95
96
|
changes: z.array(z.object({
|
|
96
97
|
field: z.string().describe("바뀌는 필드"),
|
|
97
98
|
before: z.unknown().describe("현재 값. 새로 만드는 요청이거나 읽을 수 없으면 null"),
|
|
@@ -119,6 +120,7 @@ const approvalRequestSchema = z.object({
|
|
|
119
120
|
approvalId: z.string().describe("승인 요청 ID"),
|
|
120
121
|
status: approvalStatusSchema,
|
|
121
122
|
operationId: z.string().describe("보류된 오퍼레이션 ID"),
|
|
123
|
+
operationName: z.string().nullable().optional().describe("작업 이름(예: 흐름 게시, 구매자 적립금 지급·차감). API 문서의 요약과 같다. 모르면 null"),
|
|
122
124
|
method: z.string().describe("HTTP 메서드"),
|
|
123
125
|
path: z.string().describe("요청 경로와 쿼리"),
|
|
124
126
|
body: z.unknown().describe("요청 본문. 승인하면 이 본문 그대로 실행한다. 없으면 null"),
|
|
@@ -930,7 +932,8 @@ const approveClaimResultSchema = z.object({
|
|
|
930
932
|
couponChargeAmount: z.number().int().optional().default(0).describe("환불액에서 뺀 쿠폰 조건 미달 차감. 남은 주문상품이 쿠폰 조건을 잃었을 때만 0보다 크다. 서버는 항상 싣는다"),
|
|
931
933
|
couponChargeRefundAmount: z.number().int().optional().default(0).describe("환불액에 더한, 앞선 환불에서 뺀 쿠폰 차감을 되돌린 몫. 서버는 항상 싣는다"),
|
|
932
934
|
pointRefundAmount: z.number().int().optional().default(0).describe("돌려준 적립금 (원, #93) — 결제에 쓴 적립금 중 이번 취소·반품 수량의 몫이다. 현금 환불(`refundAmount`)과 별개다. 차감은 현금에서 먼저 빼고 모자란 몫만 여기서 뺀다. 적립금을 쓰지 않은 주문과 이 필드가 없는 이전 응답·이벤트는 0으로 읽는다"),
|
|
933
|
-
refundedAt: z.string()
|
|
935
|
+
refundedAt: z.string(),
|
|
936
|
+
refundHeld: z.boolean().optional().default(false).describe("결제 환불을 대기로 남겼다(`holdRefund`, #115). 결제 상세에서 환불 처리한다")
|
|
934
937
|
});
|
|
935
938
|
//#endregion
|
|
936
939
|
//#region src/schemas/fulfillment.ts
|
|
@@ -1441,7 +1444,7 @@ const POINT_ADJUSTMENT_MAX = 1e7;
|
|
|
1441
1444
|
const pointAdjustmentRequestSchema = z.object({
|
|
1442
1445
|
amount: z.number().int().min(-1e7).max(POINT_ADJUSTMENT_MAX).refine((value) => value !== 0, "0원은 조정할 수 없습니다").describe("지급은 양수, 차감은 음수(원)"),
|
|
1443
1446
|
reason: z.string().trim().min(1).max(200).describe("사유(필수). 구매자에게는 보이지 않는다"),
|
|
1444
|
-
expiresAt: z.iso.datetime({ offset: true }).optional().describe("지급분의 소멸 시각. 생략하면 정책 유효
|
|
1447
|
+
expiresAt: z.iso.datetime({ offset: true }).optional().describe("지급분의 소멸 시각. 생략하면 정책 유효 기간(`expiryDays`)으로 정한다. **정책 유효 기간이 없으면 지급에 필수다**(없으면 400 `POINT_EXPIRY_REQUIRED`). 차감에는 주지 않는다")
|
|
1445
1448
|
}).refine((value) => !(value.amount < 0 && value.expiresAt), {
|
|
1446
1449
|
message: "차감에는 소멸 시각을 줄 수 없습니다",
|
|
1447
1450
|
path: ["expiresAt"]
|
|
@@ -2735,15 +2738,15 @@ const flowPresetSummarySchema = z.object({
|
|
|
2735
2738
|
description: z.string(),
|
|
2736
2739
|
availability: z.enum(["AVAILABLE", "BLOCKED"]).describe("BLOCKED면 의존 이슈(dependsOn)가 끝나야 설치할 수 있다"),
|
|
2737
2740
|
dependsOn: z.array(z.string()),
|
|
2738
|
-
requires: flowDocumentSchema.describe("
|
|
2739
|
-
variables: z.array(flowDocumentSchema).describe("
|
|
2741
|
+
requires: flowDocumentSchema.describe("흐름 설정(진행 단위·이행 방식)"),
|
|
2742
|
+
variables: z.array(flowDocumentSchema).describe("늘 빈 목록이다 — 프리셋은 빈 흐름을 편집한 그래프이고 값은 노드 설정 안에 있다(#115)")
|
|
2740
2743
|
});
|
|
2741
2744
|
const commerceFlowSummarySchema = z.object({
|
|
2742
2745
|
flowId: z.string(),
|
|
2743
2746
|
key: z.string().describe("상점 안 유일한 키"),
|
|
2744
2747
|
name: z.string(),
|
|
2745
|
-
progression: z.enum(["ITEM", "ORDER_GROUP"]),
|
|
2746
|
-
fulfillmentMethods: z.array(z.string()),
|
|
2748
|
+
progression: z.enum(["ITEM", "ORDER_GROUP"]).describe("진행 단위 — 지금 게시 버전의 값(초안 `definition.requires.progression`을 게시 때 고정한다). 주문상품은 주문 시점 버전의 값을 따른다"),
|
|
2749
|
+
fulfillmentMethods: z.array(z.string()).describe("이행 방식 — 지금 게시 버전의 `definition.requires.fulfillmentMethods`"),
|
|
2747
2750
|
presetKey: z.string().nullable().describe("설치한 프리셋(설치 뒤 연결되지 않는다)"),
|
|
2748
2751
|
presetVersion: z.number().int().nullable(),
|
|
2749
2752
|
activeVersion: z.number().int().nullable().describe("게시된 버전. 새 주문이 따른다"),
|
|
@@ -2795,12 +2798,12 @@ const createCommerceFlowRequestSchema = z.object({
|
|
|
2795
2798
|
key: z.string().regex(/^[a-z][a-z0-9-]{1,48}$/).describe("상점 안 유일한 키(소문자·숫자·하이픈)"),
|
|
2796
2799
|
name: z.string().min(1).max(60).optional(),
|
|
2797
2800
|
presetKey: z.string().optional().describe("설치할 프리셋. 없으면 빈 플로우"),
|
|
2798
|
-
variables: z.record(z.string(), z.unknown()).optional().describe("
|
|
2801
|
+
variables: z.record(z.string(), z.unknown()).optional().describe("쓰지 않는다(무시). 값은 그래프의 노드 설정 안에 있다(#115)")
|
|
2799
2802
|
});
|
|
2800
2803
|
const saveFlowDraftRequestSchema = z.object({
|
|
2801
2804
|
graph: flowDocumentSchema,
|
|
2802
|
-
definition: flowDocumentSchema.optional(),
|
|
2803
|
-
variables: z.record(z.string(), z.unknown()).optional()
|
|
2805
|
+
definition: flowDocumentSchema.optional().describe("흐름 설정 `requires`(progression·fulfillmentMethods)와 행동 입력 칸 `actionInputs`"),
|
|
2806
|
+
variables: z.record(z.string(), z.unknown()).optional().describe("쓰지 않는다(무시). 값은 그래프의 노드 설정 안에 있다(#115)")
|
|
2804
2807
|
});
|
|
2805
2808
|
const flowIssueSchema = z.object({
|
|
2806
2809
|
code: z.string(),
|
|
@@ -2923,7 +2926,21 @@ const flowNodeTypesSchema = z.object({
|
|
|
2923
2926
|
version: z.number().int(),
|
|
2924
2927
|
effect: z.string().describe("local 같은 트랜잭션 · afterCommit 커밋 뒤 · external 트랜잭션 밖"),
|
|
2925
2928
|
configSchema: z.record(z.string(), z.unknown())
|
|
2926
|
-
}))
|
|
2929
|
+
})),
|
|
2930
|
+
platformActions: z.array(z.object({
|
|
2931
|
+
key: z.string(),
|
|
2932
|
+
side: z.enum(["buyer", "seller"]),
|
|
2933
|
+
label: z.string(),
|
|
2934
|
+
mode: z.enum([
|
|
2935
|
+
"INSTANT",
|
|
2936
|
+
"REQUEST",
|
|
2937
|
+
"VIEW"
|
|
2938
|
+
]),
|
|
2939
|
+
subflow: z.string().optional().describe("켜면 붙는 클레임 하위 흐름"),
|
|
2940
|
+
window: z.boolean().describe("기간(within, 단계 진입 뒤 N일)을 둘 수 있다"),
|
|
2941
|
+
fee: z.boolean().describe("수수료(deduct)를 둘 수 있다"),
|
|
2942
|
+
listed: z.boolean().describe("권한 표에 행으로 보인다")
|
|
2943
|
+
})).optional().default([]).describe("노드 권한 표에 켤 수 있는 플랫폼 행동(#115) — 편집기는 이 목록으로 행을 그린다")
|
|
2927
2944
|
});
|
|
2928
2945
|
//#endregion
|
|
2929
2946
|
//#region src/schemas/promotion.ts
|
|
@@ -4573,6 +4590,7 @@ const paymentRecordSchema = z.object({
|
|
|
4573
4590
|
status: paymentRecordStatusSchema,
|
|
4574
4591
|
amount: z.number().int().describe("결제 금액"),
|
|
4575
4592
|
refundedAmount: z.number().int().describe("환불 완료 금액 합계. 실패한 환불은 빼고 센다"),
|
|
4593
|
+
heldRefundAmount: z.number().int().optional().default(0).describe("환불 대기 금액 합계(#115) — 주문만 취소하고 아직 환불하지 않은 몫. 결제 상세에서 환불 처리한다"),
|
|
4576
4594
|
provider: pgProviderSchema.nullable().describe("승인한 PG. 승인 전에 끝났으면 마지막 시도의 PG"),
|
|
4577
4595
|
method: pgPaymentMethodSchema.nullable().describe("실제 결제수단. 모르면 요청 수단"),
|
|
4578
4596
|
easyPayProvider: easyPayProviderResponseSchema.nullable().optional().default(null).describe("간편결제사. `method`가 `EASY_PAY`일 때만 값이 있고, PG가 알려 주지 않았으면 요청한 간편결제사다. 그 밖의 결제수단과 간편결제 이전 결제는 null. 서버는 항상 싣는다. 현재 값은 `NAVERPAY`·`KAKAOPAY`·`TOSSPAY`·`PAYCO`이고 값이 추가될 수 있어 문자열로 받는다"),
|
|
@@ -4613,7 +4631,7 @@ const paymentRefundRecordSchema = z.object({
|
|
|
4613
4631
|
pointRefundAmount: z.number().int().optional().default(0).describe("같은 환불에서 돌려준 적립금 (#93). 적립금을 쓰지 않은 결제는 0"),
|
|
4614
4632
|
reason: z.string().describe("환불 사유 코드"),
|
|
4615
4633
|
kind: z.string().describe("환불 원인 — SELLER_CANCEL·CLAIM·COMPENSATION·DUPLICATE. 새 값이 추가될 수 있다"),
|
|
4616
|
-
status: z.string().describe("SUCCEEDED·FAILED"),
|
|
4634
|
+
status: z.string().describe("SUCCEEDED 환불됨 · FAILED 실패 · HELD 환불 대기(주문만 취소, #115) · PROCESSING 처리 중. 합계(`refundedAmount`)는 SUCCEEDED만 센다"),
|
|
4617
4635
|
failMessage: z.string().nullable(),
|
|
4618
4636
|
requestedAt: z.string(),
|
|
4619
4637
|
completedAt: z.string().nullable()
|
|
@@ -4634,6 +4652,7 @@ const paymentListQuerySchema = z.object({
|
|
|
4634
4652
|
method: z.string().optional().describe("실제 결제수단 필터"),
|
|
4635
4653
|
keyword: z.string().optional().describe("결제 id·주문 id·PG 거래 id·시도 id·PG 주문번호(일치), 구매자명(포함)"),
|
|
4636
4654
|
includeTest: z.string().optional().describe("테스트 결제 포함 여부 (`true`·`false`. 기본 false — 실결제만)"),
|
|
4655
|
+
refundHeld: z.string().optional().describe("`true`면 환불 대기가 있는 결제만(#115)"),
|
|
4637
4656
|
page: z.string().optional().describe("페이지 번호 (1부터)"),
|
|
4638
4657
|
size: z.string().optional().describe("페이지 크기 (기본 20, 최대 100)")
|
|
4639
4658
|
});
|
|
@@ -4867,7 +4886,8 @@ const cancelBySellerRequestSchema = z.object({
|
|
|
4867
4886
|
"ETC"
|
|
4868
4887
|
]),
|
|
4869
4888
|
detail: z.string().max(500).optional(),
|
|
4870
|
-
quantity: z.number().int().min(1).optional().describe("취소할 수량. 생략하면 남은 수량 전체다. 남은 수량보다 크면 400 `INVALID_QUANTITY`. 일부만 취소하면 주문상품은 상태를 유지한 채 `canceledQuantity`가 늘고, 전 수량이 소진되면 `CANCELED`가 된다")
|
|
4889
|
+
quantity: z.number().int().min(1).optional().describe("취소할 수량. 생략하면 남은 수량 전체다. 남은 수량보다 크면 400 `INVALID_QUANTITY`. 일부만 취소하면 주문상품은 상태를 유지한 채 `canceledQuantity`가 늘고, 전 수량이 소진되면 `CANCELED`가 된다"),
|
|
4890
|
+
holdRefund: z.boolean().optional().describe("true면 주문만 취소하고 결제 환불은 대기로 남긴다(#115). 정산·재고·적립금 반환은 그대로 하고, PG 환불은 결제 상세의 `POST /v1/payments/refunds/{refundId}/process`로 따로 한다. 생략하면 취소와 함께 환불한다")
|
|
4871
4891
|
});
|
|
4872
4892
|
/**
|
|
4873
4893
|
* 제공 처리 요청 (이슈 #48) — `POST /v1/order-items/{orderItemId}/fulfill`. 배송 없는 주문상품(`MANUAL`)을
|
|
@@ -4890,7 +4910,8 @@ const cancelBySellerResultSchema = z.object({
|
|
|
4890
4910
|
couponChargeAmount: z.number().int().optional().default(0).describe("쿠폰 조건 미달 차감. 판매자 취소는 차감하지 않으므로 늘 0이다. 서버는 항상 싣는다"),
|
|
4891
4911
|
couponChargeRefundAmount: z.number().int().optional().default(0).describe("환불액에 더한, 앞선 환불에서 뺀 쿠폰 차감을 되돌린 몫. 서버는 항상 싣는다"),
|
|
4892
4912
|
pointRefundAmount: z.number().int().optional().default(0).describe("돌려준 적립금 (원, #93) — 결제에 쓴 적립금 중 이번 취소·반품 수량의 몫이다. 현금 환불(`refundAmount`)과 별개다. 차감은 현금에서 먼저 빼고 모자란 몫만 여기서 뺀다. 적립금을 쓰지 않은 주문과 이 필드가 없는 이전 응답·이벤트는 0으로 읽는다"),
|
|
4893
|
-
refundedAt: z.string()
|
|
4913
|
+
refundedAt: z.string().describe("환불을 요청한 시각. `refundHeld`면 취소 시각이고 환불은 아직 하지 않았다"),
|
|
4914
|
+
refundHeld: z.boolean().optional().default(false).describe("결제 환불을 대기로 남겼다(`holdRefund`). 결제 상세에서 환불 처리한다")
|
|
4894
4915
|
});
|
|
4895
4916
|
/** `PUT /v1/order-items/{orderItemId}/memo` 응답 — 빈 문자열로 저장하면 메모가 지워져 `null`이다 */
|
|
4896
4917
|
const orderItemMemoResultSchema = z.object({
|
|
@@ -7139,8 +7160,12 @@ function createStoreClient(options) {
|
|
|
7139
7160
|
status: Array.isArray(params?.status) ? params.status.join(",") : params?.status
|
|
7140
7161
|
} }),
|
|
7141
7162
|
get: (claimId) => storeHttp.request("GET", path`/claims/${claimId}`, claimDetailSchema),
|
|
7142
|
-
|
|
7143
|
-
|
|
7163
|
+
/** `holdRefund`(#115)면 승인만 하고 결제 환불은 대기로 남긴다 — `payments.processRefund`로 따로 환불한다 */
|
|
7164
|
+
approve: (claimId, deductAmount, idempotencyKey, options = {}) => storeHttp.request("POST", path`/claims/${claimId}/approve`, approveClaimResultSchema, {
|
|
7165
|
+
body: {
|
|
7166
|
+
...deductAmount !== void 0 ? { deductAmount } : {},
|
|
7167
|
+
...options.holdRefund ? { holdRefund: true } : {}
|
|
7168
|
+
},
|
|
7144
7169
|
headers: idempotency(idempotencyKey)
|
|
7145
7170
|
}),
|
|
7146
7171
|
reject: (claimId, body) => storeHttp.requestVoid("POST", path`/claims/${claimId}/reject`, { body: rejectClaimRequestSchema.parse(body) }),
|
|
@@ -7285,7 +7310,9 @@ get: (params) => storeHttp.request("GET", "/sales-report", salesReportSchema, {
|
|
|
7285
7310
|
*/
|
|
7286
7311
|
list: (params = {}) => storeHttp.request("GET", "/payments", paymentRecordPageSchema, { query: params }),
|
|
7287
7312
|
/** `GET /v1/payments/{paymentId}` — 시도·환불 이력 포함. 404 `PAYMENT_NOT_FOUND` */
|
|
7288
|
-
get: (paymentId) => storeHttp.request("GET", path`/payments/${paymentId}`, paymentRecordDetailSchema)
|
|
7313
|
+
get: (paymentId) => storeHttp.request("GET", path`/payments/${paymentId}`, paymentRecordDetailSchema),
|
|
7314
|
+
/** `POST /v1/payments/refunds/{refundId}/process` — 대기 환불(`HELD`)을 PG로 환불한다(#115). 409 `REFUND_NOT_HELD` */
|
|
7315
|
+
processRefund: (refundId) => storeHttp.request("POST", path`/payments/refunds/${refundId}/process`, paymentRefundRecordSchema)
|
|
7289
7316
|
},
|
|
7290
7317
|
/**
|
|
7291
7318
|
* 결제(PG) 설정 — **상점 플랫폼 OWNER 전용**. ADMIN·STAFF·PAT·M2M·3rd-party 앱 토큰은 스코프가 있어도
|
package/package.json
CHANGED
package/src/client.ts
CHANGED
|
@@ -193,6 +193,7 @@ import {
|
|
|
193
193
|
paymentProviderVerificationSchema,
|
|
194
194
|
paymentRecordDetailSchema,
|
|
195
195
|
paymentRecordPageSchema,
|
|
196
|
+
paymentRefundRecordSchema,
|
|
196
197
|
paymentSettingsSchema,
|
|
197
198
|
pgEnvironmentSchema,
|
|
198
199
|
pgProviderSchema,
|
|
@@ -972,9 +973,18 @@ export function createStoreClient(options: StoreClientOptions) {
|
|
|
972
973
|
}),
|
|
973
974
|
get: (claimId: string) =>
|
|
974
975
|
storeHttp.request("GET", path`/claims/${claimId}`, claimDetailSchema),
|
|
975
|
-
|
|
976
|
+
/** `holdRefund`(#115)면 승인만 하고 결제 환불은 대기로 남긴다 — `payments.processRefund`로 따로 환불한다 */
|
|
977
|
+
approve: (
|
|
978
|
+
claimId: string,
|
|
979
|
+
deductAmount?: number,
|
|
980
|
+
idempotencyKey?: string,
|
|
981
|
+
options: { holdRefund?: boolean } = {},
|
|
982
|
+
) =>
|
|
976
983
|
storeHttp.request("POST", path`/claims/${claimId}/approve`, approveClaimResultSchema, {
|
|
977
|
-
body:
|
|
984
|
+
body: {
|
|
985
|
+
...(deductAmount !== undefined ? { deductAmount } : {}),
|
|
986
|
+
...(options.holdRefund ? { holdRefund: true } : {}),
|
|
987
|
+
},
|
|
978
988
|
headers: idempotency(idempotencyKey),
|
|
979
989
|
}),
|
|
980
990
|
reject: (claimId: string, body: RejectClaimRequest) =>
|
|
@@ -1289,6 +1299,13 @@ export function createStoreClient(options: StoreClientOptions) {
|
|
|
1289
1299
|
/** `GET /v1/payments/{paymentId}` — 시도·환불 이력 포함. 404 `PAYMENT_NOT_FOUND` */
|
|
1290
1300
|
get: (paymentId: string) =>
|
|
1291
1301
|
storeHttp.request("GET", path`/payments/${paymentId}`, paymentRecordDetailSchema),
|
|
1302
|
+
/** `POST /v1/payments/refunds/{refundId}/process` — 대기 환불(`HELD`)을 PG로 환불한다(#115). 409 `REFUND_NOT_HELD` */
|
|
1303
|
+
processRefund: (refundId: string) =>
|
|
1304
|
+
storeHttp.request(
|
|
1305
|
+
"POST",
|
|
1306
|
+
path`/payments/refunds/${refundId}/process`,
|
|
1307
|
+
paymentRefundRecordSchema,
|
|
1308
|
+
),
|
|
1292
1309
|
},
|
|
1293
1310
|
|
|
1294
1311
|
/**
|
package/src/schemas/audit.ts
CHANGED
|
@@ -155,6 +155,11 @@ export const writePreviewSchema = z.object({
|
|
|
155
155
|
method: z.string(),
|
|
156
156
|
path: z.string(),
|
|
157
157
|
target: z.object({ type: z.string(), id: z.string().nullable() }),
|
|
158
|
+
targetName: z
|
|
159
|
+
.string()
|
|
160
|
+
.nullable()
|
|
161
|
+
.optional()
|
|
162
|
+
.describe("대상 이름(상품명·쿠폰명·흐름 이름·구매자 이름 등). 읽을 수 없으면 null"),
|
|
158
163
|
changes: z
|
|
159
164
|
.array(
|
|
160
165
|
z.object({
|
|
@@ -195,6 +200,13 @@ export const approvalRequestSchema = z.object({
|
|
|
195
200
|
approvalId: z.string().describe("승인 요청 ID"),
|
|
196
201
|
status: approvalStatusSchema,
|
|
197
202
|
operationId: z.string().describe("보류된 오퍼레이션 ID"),
|
|
203
|
+
operationName: z
|
|
204
|
+
.string()
|
|
205
|
+
.nullable()
|
|
206
|
+
.optional()
|
|
207
|
+
.describe(
|
|
208
|
+
"작업 이름(예: 흐름 게시, 구매자 적립금 지급·차감). API 문서의 요약과 같다. 모르면 null",
|
|
209
|
+
),
|
|
198
210
|
method: z.string().describe("HTTP 메서드"),
|
|
199
211
|
path: z.string().describe("요청 경로와 쿼리"),
|
|
200
212
|
body: z.unknown().describe("요청 본문. 승인하면 이 본문 그대로 실행한다. 없으면 null"),
|
package/src/schemas/claim.ts
CHANGED
|
@@ -224,6 +224,11 @@ export const approveClaimResultSchema = z.object({
|
|
|
224
224
|
"차감은 현금에서 먼저 빼고 모자란 몫만 여기서 뺀다. 적립금을 쓰지 않은 주문과 이 필드가 없는 이전 응답·이벤트는 0으로 읽는다",
|
|
225
225
|
),
|
|
226
226
|
refundedAt: z.string(),
|
|
227
|
+
refundHeld: z
|
|
228
|
+
.boolean()
|
|
229
|
+
.optional()
|
|
230
|
+
.default(false)
|
|
231
|
+
.describe("결제 환불을 대기로 남겼다(`holdRefund`, #115). 결제 상세에서 환불 처리한다"),
|
|
227
232
|
});
|
|
228
233
|
|
|
229
234
|
export type ApproveClaimResult = z.infer<typeof approveClaimResultSchema>;
|
|
@@ -203,10 +203,12 @@ export const flowPresetSummarySchema = z.object({
|
|
|
203
203
|
.enum(["AVAILABLE", "BLOCKED"])
|
|
204
204
|
.describe("BLOCKED면 의존 이슈(dependsOn)가 끝나야 설치할 수 있다"),
|
|
205
205
|
dependsOn: z.array(z.string()),
|
|
206
|
-
requires: flowDocumentSchema.describe(
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
206
|
+
requires: flowDocumentSchema.describe("흐름 설정(진행 단위·이행 방식)"),
|
|
207
|
+
variables: z
|
|
208
|
+
.array(flowDocumentSchema)
|
|
209
|
+
.describe(
|
|
210
|
+
"늘 빈 목록이다 — 프리셋은 빈 흐름을 편집한 그래프이고 값은 노드 설정 안에 있다(#115)",
|
|
211
|
+
),
|
|
210
212
|
});
|
|
211
213
|
export type FlowPresetSummary = z.infer<typeof flowPresetSummarySchema>;
|
|
212
214
|
|
|
@@ -214,8 +216,14 @@ export const commerceFlowSummarySchema = z.object({
|
|
|
214
216
|
flowId: z.string(),
|
|
215
217
|
key: z.string().describe("상점 안 유일한 키"),
|
|
216
218
|
name: z.string(),
|
|
217
|
-
progression: z
|
|
218
|
-
|
|
219
|
+
progression: z
|
|
220
|
+
.enum(["ITEM", "ORDER_GROUP"])
|
|
221
|
+
.describe(
|
|
222
|
+
"진행 단위 — 지금 게시 버전의 값(초안 `definition.requires.progression`을 게시 때 고정한다). 주문상품은 주문 시점 버전의 값을 따른다",
|
|
223
|
+
),
|
|
224
|
+
fulfillmentMethods: z
|
|
225
|
+
.array(z.string())
|
|
226
|
+
.describe("이행 방식 — 지금 게시 버전의 `definition.requires.fulfillmentMethods`"),
|
|
219
227
|
presetKey: z.string().nullable().describe("설치한 프리셋(설치 뒤 연결되지 않는다)"),
|
|
220
228
|
presetVersion: z.number().int().nullable(),
|
|
221
229
|
activeVersion: z.number().int().nullable().describe("게시된 버전. 새 주문이 따른다"),
|
|
@@ -290,14 +298,22 @@ export const createCommerceFlowRequestSchema = z.object({
|
|
|
290
298
|
.describe("상점 안 유일한 키(소문자·숫자·하이픈)"),
|
|
291
299
|
name: z.string().min(1).max(60).optional(),
|
|
292
300
|
presetKey: z.string().optional().describe("설치할 프리셋. 없으면 빈 플로우"),
|
|
293
|
-
variables: z
|
|
301
|
+
variables: z
|
|
302
|
+
.record(z.string(), z.unknown())
|
|
303
|
+
.optional()
|
|
304
|
+
.describe("쓰지 않는다(무시). 값은 그래프의 노드 설정 안에 있다(#115)"),
|
|
294
305
|
});
|
|
295
306
|
export type CreateCommerceFlowRequest = z.infer<typeof createCommerceFlowRequestSchema>;
|
|
296
307
|
|
|
297
308
|
export const saveFlowDraftRequestSchema = z.object({
|
|
298
309
|
graph: flowDocumentSchema,
|
|
299
|
-
definition: flowDocumentSchema
|
|
300
|
-
|
|
310
|
+
definition: flowDocumentSchema
|
|
311
|
+
.optional()
|
|
312
|
+
.describe("흐름 설정 `requires`(progression·fulfillmentMethods)와 행동 입력 칸 `actionInputs`"),
|
|
313
|
+
variables: z
|
|
314
|
+
.record(z.string(), z.unknown())
|
|
315
|
+
.optional()
|
|
316
|
+
.describe("쓰지 않는다(무시). 값은 그래프의 노드 설정 안에 있다(#115)"),
|
|
301
317
|
});
|
|
302
318
|
export type SaveFlowDraftRequest = z.infer<typeof saveFlowDraftRequestSchema>;
|
|
303
319
|
|
|
@@ -497,5 +513,21 @@ export const flowNodeTypesSchema = z.object({
|
|
|
497
513
|
configSchema: z.record(z.string(), z.unknown()),
|
|
498
514
|
}),
|
|
499
515
|
),
|
|
516
|
+
platformActions: z
|
|
517
|
+
.array(
|
|
518
|
+
z.object({
|
|
519
|
+
key: z.string(),
|
|
520
|
+
side: z.enum(["buyer", "seller"]),
|
|
521
|
+
label: z.string(),
|
|
522
|
+
mode: z.enum(["INSTANT", "REQUEST", "VIEW"]),
|
|
523
|
+
subflow: z.string().optional().describe("켜면 붙는 클레임 하위 흐름"),
|
|
524
|
+
window: z.boolean().describe("기간(within, 단계 진입 뒤 N일)을 둘 수 있다"),
|
|
525
|
+
fee: z.boolean().describe("수수료(deduct)를 둘 수 있다"),
|
|
526
|
+
listed: z.boolean().describe("권한 표에 행으로 보인다"),
|
|
527
|
+
}),
|
|
528
|
+
)
|
|
529
|
+
.optional()
|
|
530
|
+
.default([])
|
|
531
|
+
.describe("노드 권한 표에 켤 수 있는 플랫폼 행동(#115) — 편집기는 이 목록으로 행을 그린다"),
|
|
500
532
|
});
|
|
501
533
|
export type FlowNodeTypes = z.infer<typeof flowNodeTypesSchema>;
|
package/src/schemas/order.ts
CHANGED
|
@@ -513,6 +513,13 @@ export const cancelBySellerRequestSchema = z.object({
|
|
|
513
513
|
"취소할 수량. 생략하면 남은 수량 전체다. 남은 수량보다 크면 400 `INVALID_QUANTITY`. " +
|
|
514
514
|
"일부만 취소하면 주문상품은 상태를 유지한 채 `canceledQuantity`가 늘고, 전 수량이 소진되면 `CANCELED`가 된다",
|
|
515
515
|
),
|
|
516
|
+
holdRefund: z
|
|
517
|
+
.boolean()
|
|
518
|
+
.optional()
|
|
519
|
+
.describe(
|
|
520
|
+
"true면 주문만 취소하고 결제 환불은 대기로 남긴다(#115). 정산·재고·적립금 반환은 그대로 하고, PG 환불은 결제 상세의 " +
|
|
521
|
+
"`POST /v1/payments/refunds/{refundId}/process`로 따로 한다. 생략하면 취소와 함께 환불한다",
|
|
522
|
+
),
|
|
516
523
|
});
|
|
517
524
|
|
|
518
525
|
export type CancelBySellerRequest = z.infer<typeof cancelBySellerRequestSchema>;
|
|
@@ -583,7 +590,14 @@ export const cancelBySellerResultSchema = z.object({
|
|
|
583
590
|
"돌려준 적립금 (원, #93) — 결제에 쓴 적립금 중 이번 취소·반품 수량의 몫이다. 현금 환불(`refundAmount`)과 별개다. " +
|
|
584
591
|
"차감은 현금에서 먼저 빼고 모자란 몫만 여기서 뺀다. 적립금을 쓰지 않은 주문과 이 필드가 없는 이전 응답·이벤트는 0으로 읽는다",
|
|
585
592
|
),
|
|
586
|
-
refundedAt: z
|
|
593
|
+
refundedAt: z
|
|
594
|
+
.string()
|
|
595
|
+
.describe("환불을 요청한 시각. `refundHeld`면 취소 시각이고 환불은 아직 하지 않았다"),
|
|
596
|
+
refundHeld: z
|
|
597
|
+
.boolean()
|
|
598
|
+
.optional()
|
|
599
|
+
.default(false)
|
|
600
|
+
.describe("결제 환불을 대기로 남겼다(`holdRefund`). 결제 상세에서 환불 처리한다"),
|
|
587
601
|
});
|
|
588
602
|
|
|
589
603
|
export type CancelBySellerResult = z.infer<typeof cancelBySellerResultSchema>;
|
package/src/schemas/payment.ts
CHANGED
|
@@ -610,6 +610,14 @@ export const paymentRecordSchema = z.object({
|
|
|
610
610
|
status: paymentRecordStatusSchema,
|
|
611
611
|
amount: z.number().int().describe("결제 금액"),
|
|
612
612
|
refundedAmount: z.number().int().describe("환불 완료 금액 합계. 실패한 환불은 빼고 센다"),
|
|
613
|
+
heldRefundAmount: z
|
|
614
|
+
.number()
|
|
615
|
+
.int()
|
|
616
|
+
.optional()
|
|
617
|
+
.default(0)
|
|
618
|
+
.describe(
|
|
619
|
+
"환불 대기 금액 합계(#115) — 주문만 취소하고 아직 환불하지 않은 몫. 결제 상세에서 환불 처리한다",
|
|
620
|
+
),
|
|
613
621
|
provider: pgProviderSchema.nullable().describe("승인한 PG. 승인 전에 끝났으면 마지막 시도의 PG"),
|
|
614
622
|
method: pgPaymentMethodSchema.nullable().describe("실제 결제수단. 모르면 요청 수단"),
|
|
615
623
|
easyPayProvider: easyPayProviderResponseSchema
|
|
@@ -707,7 +715,11 @@ export const paymentRefundRecordSchema = z.object({
|
|
|
707
715
|
kind: z
|
|
708
716
|
.string()
|
|
709
717
|
.describe("환불 원인 — SELLER_CANCEL·CLAIM·COMPENSATION·DUPLICATE. 새 값이 추가될 수 있다"),
|
|
710
|
-
status: z
|
|
718
|
+
status: z
|
|
719
|
+
.string()
|
|
720
|
+
.describe(
|
|
721
|
+
"SUCCEEDED 환불됨 · FAILED 실패 · HELD 환불 대기(주문만 취소, #115) · PROCESSING 처리 중. 합계(`refundedAmount`)는 SUCCEEDED만 센다",
|
|
722
|
+
),
|
|
711
723
|
failMessage: z.string().nullable(),
|
|
712
724
|
requestedAt: z.string(),
|
|
713
725
|
completedAt: z.string().nullable(),
|
|
@@ -745,6 +757,7 @@ export const paymentListQuerySchema = z.object({
|
|
|
745
757
|
.string()
|
|
746
758
|
.optional()
|
|
747
759
|
.describe("테스트 결제 포함 여부 (`true`·`false`. 기본 false — 실결제만)"),
|
|
760
|
+
refundHeld: z.string().optional().describe("`true`면 환불 대기가 있는 결제만(#115)"),
|
|
748
761
|
page: z.string().optional().describe("페이지 번호 (1부터)"),
|
|
749
762
|
size: z.string().optional().describe("페이지 크기 (기본 20, 최대 100)"),
|
|
750
763
|
});
|
|
@@ -757,4 +770,6 @@ export interface PaymentListParams extends PageParams {
|
|
|
757
770
|
method?: PgPaymentMethod;
|
|
758
771
|
keyword?: string;
|
|
759
772
|
includeTest?: boolean;
|
|
773
|
+
/** 환불 대기가 있는 결제만(#115) */
|
|
774
|
+
refundHeld?: boolean;
|
|
760
775
|
}
|
package/src/schemas/points.ts
CHANGED
|
@@ -331,7 +331,9 @@ export const pointAdjustmentRequestSchema = z
|
|
|
331
331
|
expiresAt: z.iso
|
|
332
332
|
.datetime({ offset: true })
|
|
333
333
|
.optional()
|
|
334
|
-
.describe(
|
|
334
|
+
.describe(
|
|
335
|
+
"지급분의 소멸 시각. 생략하면 정책 유효 기간(`expiryDays`)으로 정한다. **정책 유효 기간이 없으면 지급에 필수다**(없으면 400 `POINT_EXPIRY_REQUIRED`). 차감에는 주지 않는다",
|
|
336
|
+
),
|
|
335
337
|
})
|
|
336
338
|
.refine((value) => !(value.amount < 0 && value.expiresAt), {
|
|
337
339
|
message: "차감에는 소멸 시각을 줄 수 없습니다",
|