connectbase-client 5.3.1 → 5.4.1

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/CHANGELOG.md CHANGED
@@ -3,6 +3,51 @@
3
3
  본 SDK 의 모든 주요 변경사항을 [Keep a Changelog](https://keepachangelog.com/ko/1.1.0/) 형식으로 기록합니다.
4
4
  버전은 [Semantic Versioning](https://semver.org/lang/ko/) 을 따릅니다.
5
5
 
6
+ ## [5.4.1] - 2026-07-31
7
+
8
+ ### Docs — 함수 안에서 `postponeBilling()` 을 쓰는 방법 (`subscription:manage`)
9
+
10
+ **동작 변경 없음.** 실행 코드는 5.4.0 과 동일하고 JSDoc/타입 선언의 주석만 바뀐다.
11
+
12
+ 5.4.0 문서가 "서버 전용 = `cb_sk_*` 필요" 로만 안내해서, 결정 코드가 ConnectBase Functions 안에
13
+ 있는 앱은 시크릿 키를 함수 시크릿에 심는 수밖에 없어 보였다 — 시크릿을 자동화 컨텍스트로 흘리지
14
+ 않는다는 기존 정책과 어긋난다 (platform-issue 019fb299). 백엔드에 `subscription:manage` 관리
15
+ 스코프가 생겨 `ctx.cbAdmin.subscription.postponeBilling()` / `update({ next_billing_date })` 가
16
+ 시크릿 키 없이 동작하므로, JSDoc·README 에 그 경로를 명시했다.
17
+
18
+ - 허용 경로 2가지를 나란히 문서화: 내 서버(`cb_sk_*`) / 함수(`management_scopes:
19
+ ["subscription:manage"]` + `ctx.cbAdmin`).
20
+ - `update()` 는 `next_billing_date` **가 있을 때만** 그 권한을 요구한다는 점 명시.
21
+ - 403 사유 문구를 두 경로 모두 언급하도록 정정.
22
+
23
+ ## [5.4.0] - 2026-07-30
24
+
25
+ ### Added — 다음 결제일 미루기 `subscription.postponeBilling()` (기간 얹어 주기)
26
+
27
+ 구독 중인 고객에게 기간을 얹어 줄 방법이 없었다 (platform-issue 019fb22d). 기간권·선물 코드·
28
+ CS 보상("불편을 드려 한 달 무료")은 "구독은 유지한 채 N일 공짜"인데, 기존 수단 중 어느 것도
29
+ 그걸 표현하지 못했다 — `pause()` 는 무기한 정지라 N일 개념이 없고 Dodo 는 미지원, `changePlan()`
30
+ 은 가격을 바꾸는 연산이라 proration 이 미뤄 준 기간을 상쇄한다. 앱들은 "구독 종료 뒤부터 N일"로
31
+ 쌓는 우회를 썼고, 돈은 매달 그대로 나가서 사용자 체감이 "달라진 게 없다" 였다.
32
+
33
+ - `subscription.postponeBilling(subId, { days })` — 서버가 **현재 결제일을 PG 에서 직접 읽어**
34
+ 더한다. 앱마다 "조회 → 더하기 → 쓰기" 를 다시 구현하지 않아도 되고, 갱신 직전에 호출해도
35
+ 방금 갱신된 주기 위에 얹힌다.
36
+ - `{ next_billing_date }` 로 절대 날짜 지정도 가능(RFC3339 또는 `YYYY-MM-DD` = 00:00 UTC).
37
+ - `subscription.update()` 에 `next_billing_date` 추가 — 다른 필드와 한 번에 바꿀 때.
38
+
39
+ **서버 전용(`cb_sk_*` 필요)** — 무상 기간 지급은 머천트 결정이라 브라우저 퍼블릭 키만으로는
40
+ 403 이다(그러면 클라이언트가 자기 구독을 무한히 미룰 수 있다).
41
+
42
+ **프로바이더 지원 범위** — 청구 스케줄의 주인이 달라 갈린다. Dodo/Paddle 은 PG 의 결제일 변경
43
+ API 로 옮기고(Paddle 은 이동 구간에 청구·크레딧 없음), toss/stripe 는 ConnectBase 스케줄러가
44
+ 청구하므로 즉시 반영된다. payapp/paypal 은 PG 가 청구를 소유하면서 결제일 변경 수단을 주지 않아
45
+ 400 `next_billing_date_unsupported` 다 — 로컬만 미루면 원래 날짜에 그대로 출금되므로("미뤘다고
46
+ 믿는 출금") 조용히 처리하지 않고 거절한다.
47
+
48
+ 해지 예약된 구독은 409 `subscription_scheduled_to_end` — 종료일이 정해져 있어 결제일을 미뤄도
49
+ 기간이 늘지 않기 때문에, 성공을 돌려주고 아무 것도 바꾸지 않는 침묵 no-op 을 만들지 않는다.
50
+
6
51
  ## [5.1.1] - 2026-07-30
7
52
 
8
53
  ### Docs — README 에 Server-side (Admin) 섹션 신설
package/README.md CHANGED
@@ -1309,6 +1309,43 @@ console.log(detail.status)
1309
1309
  await cb.subscription.cancel(subscription.id)
1310
1310
  ```
1311
1311
 
1312
+ **기간 얹어 주기 (기간권·선물 코드·CS 보상)** — 요금제·금액은 그대로 두고 다음 결제일만 미룹니다.
1313
+ 무상 기간 지급은 머천트 결정이라 **서버에서만** 호출할 수 있습니다. 브라우저 퍼블릭 키 단독
1314
+ 호출은 403 입니다. 서버 경로는 둘입니다:
1315
+
1316
+ - **내 서버**: `publicKey`(앱 식별) + `secretKey`(`cb_sk_*`, 관리자 권한)로 초기화한 클라이언트
1317
+ - **ConnectBase Functions**: `service_role: true` + `management_scopes: ["subscription:manage"]`
1318
+ 로 만든 함수에서 `ctx.cbAdmin.subscription.*` — 시크릿 키를 함수 시크릿에 넣지 마세요
1319
+
1320
+ ```typescript
1321
+ // 서버사이드 — 선물 코드를 검증한 뒤 지급
1322
+ const cb = new ConnectBase({
1323
+ publicKey: process.env.CB_PUBLIC_KEY,
1324
+ secretKey: process.env.CB_SECRET_KEY,
1325
+ })
1326
+
1327
+ // 31일 선물권 등록 → 다음 결제일이 31일 뒤로 (= 한 달 공짜)
1328
+ const extended = await cb.subscription.postponeBilling(subscription.id, {
1329
+ days: 31,
1330
+ reason: 'gift-code:ABC123',
1331
+ })
1332
+ console.log(extended.next_billing_at)
1333
+ ```
1334
+
1335
+ ```javascript
1336
+ // ConnectBase Functions — 시크릿 키 없이 관리 스코프로 (management_scopes: ["subscription:manage"])
1337
+ export async function handler(payload, ctx) {
1338
+ if (!ctx.cbAdmin) throw new Error('service_role not enabled')
1339
+ const sub = await ctx.cbAdmin.subscription.get(payload.subscription_id)
1340
+ if (sub.customer_email !== payload.email) throw new Error('not your subscription')
1341
+ return ctx.cbAdmin.subscription.postponeBilling(sub.id, { days: 31, reason: `gift:${payload.code}` })
1342
+ }
1343
+ ```
1344
+
1345
+ 서버가 현재 결제일을 PG 에서 직접 읽어 더하므로, 갱신 직전에 호출해도 방금 갱신된 주기 위에
1346
+ 얹힙니다. payapp/paypal 은 PG 가 결제일 변경 API 를 주지 않아 400 `next_billing_date_unsupported`
1347
+ 입니다 (로컬만 미루면 원래 날짜에 그대로 출금되므로 조용히 처리하지 않습니다).
1348
+
1312
1349
  ### Support (End-user Issue Reporting)
1313
1350
 
1314
1351
  End-user 가 앱 운영자에게 직접 버그·질문·요청을 발행하는 채널. 운영자 콘솔의 inbox 에 들어가며, AI 가 자동으로 요약·긴급도·카테고리를 분류한다 (운영자가 AI config 등록 시).