@choiceform/shared-auth 0.1.22 → 0.1.24
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/core.d.ts +3 -0
- package/dist/core.d.ts.map +1 -1
- package/dist/core.js +9 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -1
- package/dist/init.d.ts +3 -0
- package/dist/init.d.ts.map +1 -1
- package/dist/services/api-key-service.d.ts +29 -0
- package/dist/services/api-key-service.d.ts.map +1 -0
- package/dist/services/api-key-service.js +140 -0
- package/dist/services/credit-service.d.ts +33 -0
- package/dist/services/credit-service.d.ts.map +1 -0
- package/dist/services/credit-service.js +228 -0
- package/dist/services/index.d.ts +5 -1
- package/dist/services/index.d.ts.map +1 -1
- package/dist/services/index.js +3 -0
- package/dist/services/referral-service.d.ts +4 -47
- package/dist/services/referral-service.d.ts.map +1 -1
- package/dist/services/referral-service.js +81 -25
- package/dist/services/stripe-service.d.ts +39 -0
- package/dist/services/stripe-service.d.ts.map +1 -0
- package/dist/services/stripe-service.js +291 -0
- package/dist/types/api-key.d.ts +174 -0
- package/dist/types/api-key.d.ts.map +1 -0
- package/dist/types/api-key.js +10 -0
- package/dist/types/credit.d.ts +226 -0
- package/dist/types/credit.d.ts.map +1 -0
- package/dist/types/credit.js +12 -0
- package/dist/types/index.d.ts +4 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/referral.d.ts +85 -0
- package/dist/types/referral.d.ts.map +1 -0
- package/dist/types/referral.js +10 -0
- package/dist/types/stripe.d.ts +275 -0
- package/dist/types/stripe.d.ts.map +1 -0
- package/dist/types/stripe.js +10 -0
- package/dist/utils/error-mapper.d.ts +15 -0
- package/dist/utils/error-mapper.d.ts.map +1 -0
- package/dist/utils/error-mapper.js +27 -0
- package/dist/utils/index.d.ts +2 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +2 -0
- package/dist/utils/query-string.d.ts +24 -0
- package/dist/utils/query-string.d.ts.map +1 -0
- package/dist/utils/query-string.js +30 -0
- package/package.json +11 -9
|
@@ -4,60 +4,16 @@
|
|
|
4
4
|
* 提供邀请码相关的业务逻辑:
|
|
5
5
|
* - 提交邀请码
|
|
6
6
|
* - 查询邀请记录
|
|
7
|
+
* - 删除邀请记录
|
|
7
8
|
* - 检查用户是否需要填写邀请码
|
|
8
9
|
* - 提取用户邀请码字段
|
|
9
10
|
*/
|
|
10
11
|
import type { ApiClient } from "../api";
|
|
11
12
|
import type { SessionUser } from "../types";
|
|
12
|
-
|
|
13
|
-
export interface ReferralResponse {
|
|
14
|
-
referral: {
|
|
15
|
-
createdAt: string;
|
|
16
|
-
id: string;
|
|
17
|
-
referreeId: string;
|
|
18
|
-
referrerId: string;
|
|
19
|
-
status: string;
|
|
20
|
-
};
|
|
21
|
-
}
|
|
22
|
-
/** 邀请码 API 错误类型 */
|
|
23
|
-
export type ReferralErrorType = "already_referred" | "not_found" | "unknown";
|
|
24
|
-
/** 删除邀请码 API 错误类型 */
|
|
25
|
-
export type RemoveReferralErrorType = "not_found" | "forbidden" | "unknown";
|
|
26
|
-
/** 提交邀请码的结果 */
|
|
27
|
-
export interface ReferralResult {
|
|
28
|
-
error: ReferralErrorType | undefined;
|
|
29
|
-
success: boolean;
|
|
30
|
-
}
|
|
31
|
-
/** 删除邀请码的结果 */
|
|
32
|
-
export interface RemoveReferralResult {
|
|
33
|
-
error: RemoveReferralErrorType | undefined;
|
|
34
|
-
success: boolean;
|
|
35
|
-
}
|
|
36
|
-
/** 邀请记录 */
|
|
37
|
-
export interface ReferralRecord {
|
|
38
|
-
createdAt: string;
|
|
39
|
-
id: string;
|
|
40
|
-
referree?: {
|
|
41
|
-
email: string | undefined;
|
|
42
|
-
image: string | undefined;
|
|
43
|
-
name: string | undefined;
|
|
44
|
-
};
|
|
45
|
-
referreeId: string;
|
|
46
|
-
referrerId: string;
|
|
47
|
-
status: string;
|
|
48
|
-
}
|
|
49
|
-
/** GET /referral 响应 */
|
|
50
|
-
export interface ListReferralsResponse {
|
|
51
|
-
referrals: ReferralRecord[];
|
|
52
|
-
}
|
|
53
|
-
/** 邀请码检查选项 */
|
|
54
|
-
export interface NeedsReferralOptions {
|
|
55
|
-
/** 跳过检查的角色列表,默认 ["admin"] */
|
|
56
|
-
skipRoles?: string[];
|
|
57
|
-
}
|
|
13
|
+
import type { ListReferralsResult, NeedsReferralOptions, ReferralResult, RemoveReferralResult } from "../types/referral";
|
|
58
14
|
export interface ReferralService {
|
|
59
15
|
/** 查询当前用户的邀请记录 */
|
|
60
|
-
listReferrals: () => Promise<
|
|
16
|
+
listReferrals: () => Promise<ListReferralsResult>;
|
|
61
17
|
/** 删除邀请记录(需要 admin 权限) */
|
|
62
18
|
removeReferral: (referreeId: string) => Promise<RemoveReferralResult>;
|
|
63
19
|
/** 提交邀请码 */
|
|
@@ -80,4 +36,5 @@ export declare function getReferralFields(user: SessionUser | null): {
|
|
|
80
36
|
referralCode: string | undefined;
|
|
81
37
|
referredBy: string | undefined;
|
|
82
38
|
};
|
|
39
|
+
export type { ListReferralsResponse, ListReferralsResult, NeedsReferralOptions, ReferralErrorType, ReferralRecord, ReferralResponse, ReferralResult, RemoveReferralErrorType, RemoveReferralResult, } from "../types/referral";
|
|
83
40
|
//# sourceMappingURL=referral-service.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"referral-service.d.ts","sourceRoot":"","sources":["../../src/services/referral-service.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"referral-service.d.ts","sourceRoot":"","sources":["../../src/services/referral-service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAe,MAAM,QAAQ,CAAA;AACpD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAA;AAC3C,OAAO,KAAK,EAEV,mBAAmB,EACnB,oBAAoB,EAGpB,cAAc,EAEd,oBAAoB,EACrB,MAAM,mBAAmB,CAAA;AAwC1B,MAAM,WAAW,eAAe;IAC9B,kBAAkB;IAClB,aAAa,EAAE,MAAM,OAAO,CAAC,mBAAmB,CAAC,CAAA;IACjD,0BAA0B;IAC1B,cAAc,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,oBAAoB,CAAC,CAAA;IACrE,YAAY;IACZ,kBAAkB,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,cAAc,CAAC,CAAA;CACtE;AAID;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,SAAS,GAAG,eAAe,CA+E3E;AAID;;;;GAIG;AACH,wBAAgB,aAAa,CAC3B,IAAI,EAAE,WAAW,GAAG,IAAI,EACxB,OAAO,CAAC,EAAE,oBAAoB,GAC7B,OAAO,CAST;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,WAAW,GAAG,IAAI;;;EAKzD;AAID,YAAY,EACV,qBAAqB,EACrB,mBAAmB,EACnB,oBAAoB,EACpB,iBAAiB,EACjB,cAAc,EACd,gBAAgB,EAChB,cAAc,EACd,uBAAuB,EACvB,oBAAoB,GACrB,MAAM,mBAAmB,CAAA"}
|
|
@@ -4,54 +4,110 @@
|
|
|
4
4
|
* 提供邀请码相关的业务逻辑:
|
|
5
5
|
* - 提交邀请码
|
|
6
6
|
* - 查询邀请记录
|
|
7
|
+
* - 删除邀请记录
|
|
7
8
|
* - 检查用户是否需要填写邀请码
|
|
8
9
|
* - 提取用户邀请码字段
|
|
9
10
|
*/
|
|
11
|
+
// ===== Constants =====
|
|
12
|
+
const BASE_PATH = "/v1/auth/referral";
|
|
13
|
+
// ===== Helper Functions =====
|
|
14
|
+
/**
|
|
15
|
+
* 将 HTTP 状态码映射为 Referral 错误类型
|
|
16
|
+
*/
|
|
17
|
+
function mapStatusToReferralError(status) {
|
|
18
|
+
switch (status) {
|
|
19
|
+
case 400:
|
|
20
|
+
return "already_referred";
|
|
21
|
+
case 404:
|
|
22
|
+
return "not_found";
|
|
23
|
+
default:
|
|
24
|
+
return "unknown";
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* 将 HTTP 状态码映射为 RemoveReferral 错误类型
|
|
29
|
+
*/
|
|
30
|
+
function mapStatusToRemoveReferralError(status) {
|
|
31
|
+
switch (status) {
|
|
32
|
+
case 403:
|
|
33
|
+
return "forbidden";
|
|
34
|
+
case 404:
|
|
35
|
+
return "not_found";
|
|
36
|
+
default:
|
|
37
|
+
return "unknown";
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
// ===== Service Implementation =====
|
|
10
41
|
/**
|
|
11
42
|
* 创建邀请码服务
|
|
12
43
|
*/
|
|
13
44
|
export function createReferralService(apiClient) {
|
|
45
|
+
/**
|
|
46
|
+
* 提交邀请码
|
|
47
|
+
*/
|
|
14
48
|
async function submitReferralCode(referralCode) {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
49
|
+
try {
|
|
50
|
+
const response = await apiClient.post(BASE_PATH, { referralCode });
|
|
51
|
+
if (response.ok) {
|
|
52
|
+
return { success: true, error: undefined };
|
|
53
|
+
}
|
|
54
|
+
return {
|
|
55
|
+
success: false,
|
|
56
|
+
error: mapStatusToReferralError(response.status),
|
|
57
|
+
};
|
|
22
58
|
}
|
|
23
|
-
|
|
24
|
-
error
|
|
59
|
+
catch {
|
|
60
|
+
return { success: false, error: "unknown" };
|
|
25
61
|
}
|
|
26
|
-
return { success: false, error };
|
|
27
62
|
}
|
|
63
|
+
/**
|
|
64
|
+
* 查询当前用户的邀请记录
|
|
65
|
+
*/
|
|
28
66
|
async function listReferrals() {
|
|
29
67
|
try {
|
|
30
|
-
const response = await apiClient.get(
|
|
68
|
+
const response = await apiClient.get(BASE_PATH);
|
|
31
69
|
if (response.ok) {
|
|
32
|
-
return
|
|
70
|
+
return {
|
|
71
|
+
success: true,
|
|
72
|
+
data: response.data.referrals || [],
|
|
73
|
+
error: undefined,
|
|
74
|
+
};
|
|
33
75
|
}
|
|
34
|
-
return
|
|
76
|
+
return {
|
|
77
|
+
success: false,
|
|
78
|
+
data: [],
|
|
79
|
+
error: mapStatusToReferralError(response.status),
|
|
80
|
+
};
|
|
35
81
|
}
|
|
36
82
|
catch {
|
|
37
|
-
return [];
|
|
83
|
+
return { success: false, data: [], error: "unknown" };
|
|
38
84
|
}
|
|
39
85
|
}
|
|
86
|
+
/**
|
|
87
|
+
* 删除邀请记录(需要 admin 权限)
|
|
88
|
+
*/
|
|
40
89
|
async function removeReferral(referreeId) {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
90
|
+
try {
|
|
91
|
+
const response = await apiClient.post("/v1/auth/delete-referral", {
|
|
92
|
+
referreeId,
|
|
93
|
+
});
|
|
94
|
+
if (response.ok) {
|
|
95
|
+
return { success: true, error: undefined };
|
|
96
|
+
}
|
|
97
|
+
return {
|
|
98
|
+
success: false,
|
|
99
|
+
error: mapStatusToRemoveReferralError(response.status),
|
|
100
|
+
};
|
|
48
101
|
}
|
|
49
|
-
|
|
50
|
-
error
|
|
102
|
+
catch {
|
|
103
|
+
return { success: false, error: "unknown" };
|
|
51
104
|
}
|
|
52
|
-
return { success: false, error };
|
|
53
105
|
}
|
|
54
|
-
return {
|
|
106
|
+
return {
|
|
107
|
+
listReferrals,
|
|
108
|
+
removeReferral,
|
|
109
|
+
submitReferralCode,
|
|
110
|
+
};
|
|
55
111
|
}
|
|
56
112
|
// ===== Utilities =====
|
|
57
113
|
/**
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stripe 服务
|
|
3
|
+
*
|
|
4
|
+
* 提供 Stripe 相关的业务逻辑:
|
|
5
|
+
* - 订阅管理 (升级、取消、恢复)
|
|
6
|
+
* - 产品查询
|
|
7
|
+
* - 价格查询
|
|
8
|
+
* - 计划查询
|
|
9
|
+
* - 账单门户
|
|
10
|
+
*/
|
|
11
|
+
import type { ApiClient } from "../api";
|
|
12
|
+
import type { CancelSubscriptionRequest, CreateBillingPortalRequest, GetStripePlanResult, GetStripePriceResult, GetStripeProductResult, ListStripePlansRequest, ListStripePlansResult, ListStripePricesRequest, ListStripePricesResult, ListStripeProductsRequest, ListStripeProductsResult, RestoreSubscriptionRequest, StripeRedirectResult, StripeResult, UpgradeSubscriptionRequest } from "../types";
|
|
13
|
+
export interface StripeService {
|
|
14
|
+
/** 取消订阅 */
|
|
15
|
+
cancelSubscription: (request: CancelSubscriptionRequest) => Promise<StripeRedirectResult>;
|
|
16
|
+
/** 创建账单门户 */
|
|
17
|
+
createBillingPortal: (request: CreateBillingPortalRequest) => Promise<StripeRedirectResult>;
|
|
18
|
+
/** 获取单个计划 */
|
|
19
|
+
getPlan: (id: string, include?: string) => Promise<GetStripePlanResult>;
|
|
20
|
+
/** 获取单个价格 */
|
|
21
|
+
getPrice: (id: string, include?: string) => Promise<GetStripePriceResult>;
|
|
22
|
+
/** 获取单个产品 */
|
|
23
|
+
getProduct: (id: string, include?: string) => Promise<GetStripeProductResult>;
|
|
24
|
+
/** 列出计划 */
|
|
25
|
+
listPlans: (request?: ListStripePlansRequest) => Promise<ListStripePlansResult>;
|
|
26
|
+
/** 列出价格 */
|
|
27
|
+
listPrices: (request?: ListStripePricesRequest) => Promise<ListStripePricesResult>;
|
|
28
|
+
/** 列出产品 */
|
|
29
|
+
listProducts: (request?: ListStripeProductsRequest) => Promise<ListStripeProductsResult>;
|
|
30
|
+
/** 恢复订阅 */
|
|
31
|
+
restoreSubscription: (request: RestoreSubscriptionRequest) => Promise<StripeResult>;
|
|
32
|
+
/** 升级订阅 */
|
|
33
|
+
upgradeSubscription: (request: UpgradeSubscriptionRequest) => Promise<StripeRedirectResult>;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* 创建 Stripe 服务
|
|
37
|
+
*/
|
|
38
|
+
export declare function createStripeService(apiClient: ApiClient): StripeService;
|
|
39
|
+
//# sourceMappingURL=stripe-service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stripe-service.d.ts","sourceRoot":"","sources":["../../src/services/stripe-service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAe,MAAM,QAAQ,CAAA;AACpD,OAAO,KAAK,EACV,yBAAyB,EACzB,0BAA0B,EAC1B,mBAAmB,EACnB,oBAAoB,EACpB,sBAAsB,EACtB,sBAAsB,EACtB,qBAAqB,EACrB,uBAAuB,EACvB,sBAAsB,EACtB,yBAAyB,EACzB,wBAAwB,EACxB,0BAA0B,EAK1B,oBAAoB,EACpB,YAAY,EACZ,0BAA0B,EAC3B,MAAM,UAAU,CAAA;AAkDjB,MAAM,WAAW,aAAa;IAC5B,WAAW;IACX,kBAAkB,EAAE,CAAC,OAAO,EAAE,yBAAyB,KAAK,OAAO,CAAC,oBAAoB,CAAC,CAAA;IACzF,aAAa;IACb,mBAAmB,EAAE,CAAC,OAAO,EAAE,0BAA0B,KAAK,OAAO,CAAC,oBAAoB,CAAC,CAAA;IAC3F,aAAa;IACb,OAAO,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,mBAAmB,CAAC,CAAA;IACvE,aAAa;IACb,QAAQ,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,oBAAoB,CAAC,CAAA;IACzE,aAAa;IACb,UAAU,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,sBAAsB,CAAC,CAAA;IAC7E,WAAW;IACX,SAAS,EAAE,CAAC,OAAO,CAAC,EAAE,sBAAsB,KAAK,OAAO,CAAC,qBAAqB,CAAC,CAAA;IAC/E,WAAW;IACX,UAAU,EAAE,CAAC,OAAO,CAAC,EAAE,uBAAuB,KAAK,OAAO,CAAC,sBAAsB,CAAC,CAAA;IAClF,WAAW;IACX,YAAY,EAAE,CAAC,OAAO,CAAC,EAAE,yBAAyB,KAAK,OAAO,CAAC,wBAAwB,CAAC,CAAA;IACxF,WAAW;IACX,mBAAmB,EAAE,CAAC,OAAO,EAAE,0BAA0B,KAAK,OAAO,CAAC,YAAY,CAAC,CAAA;IACnF,WAAW;IACX,mBAAmB,EAAE,CAAC,OAAO,EAAE,0BAA0B,KAAK,OAAO,CAAC,oBAAoB,CAAC,CAAA;CAC5F;AAID;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,SAAS,GAAG,aAAa,CA6TvE"}
|
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stripe 服务
|
|
3
|
+
*
|
|
4
|
+
* 提供 Stripe 相关的业务逻辑:
|
|
5
|
+
* - 订阅管理 (升级、取消、恢复)
|
|
6
|
+
* - 产品查询
|
|
7
|
+
* - 价格查询
|
|
8
|
+
* - 计划查询
|
|
9
|
+
* - 账单门户
|
|
10
|
+
*/
|
|
11
|
+
import { buildQueryString } from "../utils/query-string";
|
|
12
|
+
// ===== Constants =====
|
|
13
|
+
const STRIPE_PATH = "/v1/auth/stripe";
|
|
14
|
+
const SUBSCRIPTION_PATH = "/v1/auth/subscription";
|
|
15
|
+
// ===== Helper Functions =====
|
|
16
|
+
/**
|
|
17
|
+
* 将 HTTP 状态码映射为 Stripe 错误类型
|
|
18
|
+
*/
|
|
19
|
+
function mapStatusToError(status) {
|
|
20
|
+
switch (status) {
|
|
21
|
+
case 400:
|
|
22
|
+
return "bad_request";
|
|
23
|
+
case 401:
|
|
24
|
+
return "unauthorized";
|
|
25
|
+
case 403:
|
|
26
|
+
return "forbidden";
|
|
27
|
+
case 404:
|
|
28
|
+
return "not_found";
|
|
29
|
+
case 429:
|
|
30
|
+
return "rate_limited";
|
|
31
|
+
default:
|
|
32
|
+
return "unknown";
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
// ===== Service Implementation =====
|
|
36
|
+
/**
|
|
37
|
+
* 创建 Stripe 服务
|
|
38
|
+
*/
|
|
39
|
+
export function createStripeService(apiClient) {
|
|
40
|
+
// ===== Products =====
|
|
41
|
+
/**
|
|
42
|
+
* 列出产品
|
|
43
|
+
*/
|
|
44
|
+
async function listProducts(request) {
|
|
45
|
+
try {
|
|
46
|
+
const query = buildQueryString({
|
|
47
|
+
active: request?.active,
|
|
48
|
+
livemode: request?.livemode,
|
|
49
|
+
applicationId: request?.applicationId,
|
|
50
|
+
type: request?.type,
|
|
51
|
+
include: request?.include,
|
|
52
|
+
});
|
|
53
|
+
const response = await apiClient.get(`${STRIPE_PATH}/products${query}`);
|
|
54
|
+
if (response.ok) {
|
|
55
|
+
return {
|
|
56
|
+
success: true,
|
|
57
|
+
products: response.data.products || [],
|
|
58
|
+
error: undefined,
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
return {
|
|
62
|
+
success: false,
|
|
63
|
+
products: [],
|
|
64
|
+
error: mapStatusToError(response.status),
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
catch {
|
|
68
|
+
return { success: false, products: [], error: "unknown" };
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* 获取单个产品
|
|
73
|
+
*/
|
|
74
|
+
async function getProduct(id, include) {
|
|
75
|
+
try {
|
|
76
|
+
const query = include ? `?include=${encodeURIComponent(include)}` : "";
|
|
77
|
+
const response = await apiClient.get(`${STRIPE_PATH}/products/${encodeURIComponent(id)}${query}`);
|
|
78
|
+
if (response.ok) {
|
|
79
|
+
return { success: true, product: response.data, error: undefined };
|
|
80
|
+
}
|
|
81
|
+
return {
|
|
82
|
+
success: false,
|
|
83
|
+
product: undefined,
|
|
84
|
+
error: mapStatusToError(response.status),
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
catch {
|
|
88
|
+
return { success: false, product: undefined, error: "unknown" };
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
// ===== Prices =====
|
|
92
|
+
/**
|
|
93
|
+
* 列出价格
|
|
94
|
+
*/
|
|
95
|
+
async function listPrices(request) {
|
|
96
|
+
try {
|
|
97
|
+
const query = buildQueryString({
|
|
98
|
+
active: request?.active,
|
|
99
|
+
livemode: request?.livemode,
|
|
100
|
+
include: request?.include,
|
|
101
|
+
});
|
|
102
|
+
const response = await apiClient.get(`${STRIPE_PATH}/prices${query}`);
|
|
103
|
+
if (response.ok) {
|
|
104
|
+
return {
|
|
105
|
+
success: true,
|
|
106
|
+
prices: response.data.prices || [],
|
|
107
|
+
error: undefined,
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
return {
|
|
111
|
+
success: false,
|
|
112
|
+
prices: [],
|
|
113
|
+
error: mapStatusToError(response.status),
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
catch {
|
|
117
|
+
return { success: false, prices: [], error: "unknown" };
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* 获取单个价格
|
|
122
|
+
*/
|
|
123
|
+
async function getPrice(id, include) {
|
|
124
|
+
try {
|
|
125
|
+
const query = include ? `?include=${encodeURIComponent(include)}` : "";
|
|
126
|
+
const response = await apiClient.get(`${STRIPE_PATH}/prices/${encodeURIComponent(id)}${query}`);
|
|
127
|
+
if (response.ok) {
|
|
128
|
+
return { success: true, price: response.data, error: undefined };
|
|
129
|
+
}
|
|
130
|
+
return {
|
|
131
|
+
success: false,
|
|
132
|
+
price: undefined,
|
|
133
|
+
error: mapStatusToError(response.status),
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
catch {
|
|
137
|
+
return { success: false, price: undefined, error: "unknown" };
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
// ===== Plans =====
|
|
141
|
+
/**
|
|
142
|
+
* 列出计划
|
|
143
|
+
*/
|
|
144
|
+
async function listPlans(request) {
|
|
145
|
+
try {
|
|
146
|
+
const query = buildQueryString({
|
|
147
|
+
active: request?.active,
|
|
148
|
+
livemode: request?.livemode,
|
|
149
|
+
applicationId: request?.applicationId,
|
|
150
|
+
isOneoff: request?.isOneoff,
|
|
151
|
+
include: request?.include,
|
|
152
|
+
});
|
|
153
|
+
const response = await apiClient.get(`${STRIPE_PATH}/plans${query}`);
|
|
154
|
+
if (response.ok) {
|
|
155
|
+
return {
|
|
156
|
+
success: true,
|
|
157
|
+
plans: response.data.plans || [],
|
|
158
|
+
error: undefined,
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
return {
|
|
162
|
+
success: false,
|
|
163
|
+
plans: [],
|
|
164
|
+
error: mapStatusToError(response.status),
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
catch {
|
|
168
|
+
return { success: false, plans: [], error: "unknown" };
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* 获取单个计划
|
|
173
|
+
*/
|
|
174
|
+
async function getPlan(id, include) {
|
|
175
|
+
try {
|
|
176
|
+
const query = include ? `?include=${encodeURIComponent(include)}` : "";
|
|
177
|
+
const response = await apiClient.get(`${STRIPE_PATH}/plans/${encodeURIComponent(id)}${query}`);
|
|
178
|
+
if (response.ok) {
|
|
179
|
+
return { success: true, plan: response.data, error: undefined };
|
|
180
|
+
}
|
|
181
|
+
return {
|
|
182
|
+
success: false,
|
|
183
|
+
plan: undefined,
|
|
184
|
+
error: mapStatusToError(response.status),
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
catch {
|
|
188
|
+
return { success: false, plan: undefined, error: "unknown" };
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
// ===== Subscription Management =====
|
|
192
|
+
/**
|
|
193
|
+
* 升级订阅
|
|
194
|
+
*/
|
|
195
|
+
async function upgradeSubscription(request) {
|
|
196
|
+
try {
|
|
197
|
+
const response = await apiClient.post(`${SUBSCRIPTION_PATH}/upgrade`, request);
|
|
198
|
+
if (response.ok) {
|
|
199
|
+
return {
|
|
200
|
+
success: true,
|
|
201
|
+
url: response.data.url,
|
|
202
|
+
error: undefined,
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
return {
|
|
206
|
+
success: false,
|
|
207
|
+
url: undefined,
|
|
208
|
+
error: mapStatusToError(response.status),
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
catch {
|
|
212
|
+
return { success: false, url: undefined, error: "unknown" };
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* 取消订阅
|
|
217
|
+
*/
|
|
218
|
+
async function cancelSubscription(request) {
|
|
219
|
+
try {
|
|
220
|
+
const response = await apiClient.post(`${SUBSCRIPTION_PATH}/cancel`, request);
|
|
221
|
+
if (response.ok) {
|
|
222
|
+
return {
|
|
223
|
+
success: true,
|
|
224
|
+
url: response.data.url,
|
|
225
|
+
error: undefined,
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
return {
|
|
229
|
+
success: false,
|
|
230
|
+
url: undefined,
|
|
231
|
+
error: mapStatusToError(response.status),
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
catch {
|
|
235
|
+
return { success: false, url: undefined, error: "unknown" };
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* 恢复订阅
|
|
240
|
+
*/
|
|
241
|
+
async function restoreSubscription(request) {
|
|
242
|
+
try {
|
|
243
|
+
const response = await apiClient.post(`${SUBSCRIPTION_PATH}/restore`, request);
|
|
244
|
+
if (response.ok) {
|
|
245
|
+
return { success: true, error: undefined };
|
|
246
|
+
}
|
|
247
|
+
return {
|
|
248
|
+
success: false,
|
|
249
|
+
error: mapStatusToError(response.status),
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
catch {
|
|
253
|
+
return { success: false, error: "unknown" };
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
/**
|
|
257
|
+
* 创建账单门户
|
|
258
|
+
*/
|
|
259
|
+
async function createBillingPortal(request) {
|
|
260
|
+
try {
|
|
261
|
+
const response = await apiClient.post(`${SUBSCRIPTION_PATH}/billing-portal`, request);
|
|
262
|
+
if (response.ok) {
|
|
263
|
+
return {
|
|
264
|
+
success: true,
|
|
265
|
+
url: response.data.url,
|
|
266
|
+
error: undefined,
|
|
267
|
+
};
|
|
268
|
+
}
|
|
269
|
+
return {
|
|
270
|
+
success: false,
|
|
271
|
+
url: undefined,
|
|
272
|
+
error: mapStatusToError(response.status),
|
|
273
|
+
};
|
|
274
|
+
}
|
|
275
|
+
catch {
|
|
276
|
+
return { success: false, url: undefined, error: "unknown" };
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
return {
|
|
280
|
+
cancelSubscription,
|
|
281
|
+
createBillingPortal,
|
|
282
|
+
getPlan,
|
|
283
|
+
getPrice,
|
|
284
|
+
getProduct,
|
|
285
|
+
listPlans,
|
|
286
|
+
listPrices,
|
|
287
|
+
listProducts,
|
|
288
|
+
restoreSubscription,
|
|
289
|
+
upgradeSubscription,
|
|
290
|
+
};
|
|
291
|
+
}
|