@zucker-framework/payment 1.0.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/LICENSE +201 -0
- package/NOTICE +22 -0
- package/THIRD_PARTY_NOTICES +4 -0
- package/dist/index.d.mts +283 -0
- package/dist/index.d.ts +283 -0
- package/dist/index.js +594 -0
- package/dist/index.mjs +560 -0
- package/package.json +40 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
import { EventEmitter2 } from '@nestjs/event-emitter';
|
|
2
|
+
import { Type, DynamicModule, InjectionToken } from '@nestjs/common';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* 支付网关接口 — 不绑定任何具体支付商。
|
|
6
|
+
* 用户通过注入 Stripe/PayPal/微信支付适配器来使用。
|
|
7
|
+
*/
|
|
8
|
+
interface PaymentProvider {
|
|
9
|
+
id: string;
|
|
10
|
+
name: string;
|
|
11
|
+
/** 创建支付意图/订单 */
|
|
12
|
+
createPaymentIntent(params: CreatePaymentParams): Promise<PaymentIntent>;
|
|
13
|
+
/** 确认支付 */
|
|
14
|
+
confirmPayment(intentId: string): Promise<PaymentResult>;
|
|
15
|
+
/** 退款 */
|
|
16
|
+
refund(paymentId: string, amount?: number, reason?: string): Promise<RefundResult>;
|
|
17
|
+
/** 查询支付状态 */
|
|
18
|
+
getPaymentStatus(intentId: string): Promise<PaymentStatus>;
|
|
19
|
+
/** 处理 Webhook */
|
|
20
|
+
handleWebhook(payload: unknown, signature: string): Promise<WebhookEvent>;
|
|
21
|
+
}
|
|
22
|
+
interface CreatePaymentParams {
|
|
23
|
+
amount: number;
|
|
24
|
+
currency: string;
|
|
25
|
+
description?: string;
|
|
26
|
+
metadata?: Record<string, string>;
|
|
27
|
+
customerId?: string;
|
|
28
|
+
returnUrl?: string;
|
|
29
|
+
cancelUrl?: string;
|
|
30
|
+
}
|
|
31
|
+
interface PaymentIntent {
|
|
32
|
+
id: string;
|
|
33
|
+
clientSecret?: string;
|
|
34
|
+
status: PaymentStatus;
|
|
35
|
+
amount: number;
|
|
36
|
+
currency: string;
|
|
37
|
+
redirectUrl?: string;
|
|
38
|
+
}
|
|
39
|
+
type PaymentStatus = 'pending' | 'processing' | 'succeeded' | 'failed' | 'cancelled' | 'refunded';
|
|
40
|
+
interface PaymentResult {
|
|
41
|
+
id: string;
|
|
42
|
+
status: PaymentStatus;
|
|
43
|
+
amount: number;
|
|
44
|
+
currency: string;
|
|
45
|
+
paidAt?: Date;
|
|
46
|
+
}
|
|
47
|
+
interface RefundResult {
|
|
48
|
+
id: string;
|
|
49
|
+
paymentId: string;
|
|
50
|
+
amount: number;
|
|
51
|
+
status: 'pending' | 'succeeded' | 'failed';
|
|
52
|
+
reason?: string;
|
|
53
|
+
}
|
|
54
|
+
interface WebhookEvent {
|
|
55
|
+
type: string;
|
|
56
|
+
data: Record<string, unknown>;
|
|
57
|
+
}
|
|
58
|
+
interface SubscriptionPlan {
|
|
59
|
+
id: string;
|
|
60
|
+
name: string;
|
|
61
|
+
amount: number;
|
|
62
|
+
currency: string;
|
|
63
|
+
interval: 'day' | 'week' | 'month' | 'year';
|
|
64
|
+
intervalCount: number;
|
|
65
|
+
trialDays?: number;
|
|
66
|
+
features?: string[];
|
|
67
|
+
}
|
|
68
|
+
interface Subscription {
|
|
69
|
+
id: string;
|
|
70
|
+
planId: string;
|
|
71
|
+
customerId: string;
|
|
72
|
+
status: 'active' | 'past_due' | 'cancelled' | 'trialing' | 'paused';
|
|
73
|
+
currentPeriodStart: Date;
|
|
74
|
+
currentPeriodEnd: Date;
|
|
75
|
+
cancelAtPeriodEnd: boolean;
|
|
76
|
+
}
|
|
77
|
+
interface SubscriptionProvider {
|
|
78
|
+
createSubscription(customerId: string, planId: string): Promise<Subscription>;
|
|
79
|
+
cancelSubscription(subscriptionId: string, immediately?: boolean): Promise<Subscription>;
|
|
80
|
+
getSubscription(subscriptionId: string): Promise<Subscription>;
|
|
81
|
+
listSubscriptions(customerId: string): Promise<Subscription[]>;
|
|
82
|
+
changePlan(subscriptionId: string, newPlanId: string): Promise<Subscription>;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* 支付服务 — 管理多个 PaymentProvider 的注册和路由。
|
|
87
|
+
*
|
|
88
|
+
* 使用方式:
|
|
89
|
+
* paymentService.register(stripeProvider);
|
|
90
|
+
* paymentService.register(wechatPayProvider);
|
|
91
|
+
* await paymentService.createPaymentIntent('stripe', params);
|
|
92
|
+
*/
|
|
93
|
+
declare class PaymentService {
|
|
94
|
+
private readonly logger;
|
|
95
|
+
private readonly providers;
|
|
96
|
+
/** 注册支付提供商 */
|
|
97
|
+
register(provider: PaymentProvider): void;
|
|
98
|
+
/** 注销支付提供商 */
|
|
99
|
+
unregister(providerId: string): boolean;
|
|
100
|
+
/** 获取已注册的提供商列表 */
|
|
101
|
+
listProviders(): PaymentProvider[];
|
|
102
|
+
/** 获取指定提供商 */
|
|
103
|
+
getProvider(providerId: string): PaymentProvider;
|
|
104
|
+
/** 创建支付意图 */
|
|
105
|
+
createPaymentIntent(providerId: string, params: CreatePaymentParams): Promise<PaymentIntent>;
|
|
106
|
+
/** 确认支付 */
|
|
107
|
+
confirmPayment(providerId: string, intentId: string): Promise<PaymentResult>;
|
|
108
|
+
/** 退款 */
|
|
109
|
+
refund(providerId: string, paymentId: string, amount?: number, reason?: string): Promise<RefundResult>;
|
|
110
|
+
/** 查询支付状态 */
|
|
111
|
+
getPaymentStatus(providerId: string, intentId: string): Promise<PaymentStatus>;
|
|
112
|
+
/** 处理 Webhook */
|
|
113
|
+
handleWebhook(providerId: string, payload: unknown, signature: string): Promise<WebhookEvent>;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
type OrderStatus = 'created' | 'paying' | 'paid' | 'failed' | 'refunding' | 'refunded' | 'cancelled';
|
|
117
|
+
interface Order {
|
|
118
|
+
id: string;
|
|
119
|
+
providerId: string;
|
|
120
|
+
paymentIntentId?: string;
|
|
121
|
+
paymentId?: string;
|
|
122
|
+
amount: number;
|
|
123
|
+
currency: string;
|
|
124
|
+
status: OrderStatus;
|
|
125
|
+
metadata?: Record<string, string>;
|
|
126
|
+
createdAt: Date;
|
|
127
|
+
updatedAt: Date;
|
|
128
|
+
paidAt?: Date;
|
|
129
|
+
refundedAt?: Date;
|
|
130
|
+
}
|
|
131
|
+
interface CreateOrderParams {
|
|
132
|
+
orderId: string;
|
|
133
|
+
providerId: string;
|
|
134
|
+
payment: CreatePaymentParams;
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* 订单管理服务 — 创建订单 -> 支付 -> 完成/退款。
|
|
138
|
+
*
|
|
139
|
+
* 提供内存订单存储(生产环境应替换为数据库持久化)。
|
|
140
|
+
*/
|
|
141
|
+
declare class OrderService {
|
|
142
|
+
private readonly paymentService;
|
|
143
|
+
private readonly logger;
|
|
144
|
+
private readonly orders;
|
|
145
|
+
constructor(paymentService: PaymentService);
|
|
146
|
+
/** 创建订单并发起支付 */
|
|
147
|
+
createOrder(params: CreateOrderParams): Promise<Order>;
|
|
148
|
+
/** 确认订单支付 */
|
|
149
|
+
confirmOrder(orderId: string): Promise<PaymentResult>;
|
|
150
|
+
/** 订单退款 */
|
|
151
|
+
refundOrder(orderId: string, amount?: number, reason?: string): Promise<RefundResult>;
|
|
152
|
+
/** 取消订单 */
|
|
153
|
+
cancelOrder(orderId: string): Order;
|
|
154
|
+
/** 查询订单 */
|
|
155
|
+
getOrder(orderId: string): Order;
|
|
156
|
+
/** 列出所有订单 */
|
|
157
|
+
listOrders(): Order[];
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/** 挽回邮件发送接口 — 由业务项目实现 */
|
|
161
|
+
interface RecoveryMailSender {
|
|
162
|
+
sendRecoveryEmail(params: RecoveryEmailParams): Promise<void>;
|
|
163
|
+
}
|
|
164
|
+
interface RecoveryEmailParams {
|
|
165
|
+
to: string;
|
|
166
|
+
userName: string;
|
|
167
|
+
orderId: string;
|
|
168
|
+
orderNumber?: string;
|
|
169
|
+
amount: number;
|
|
170
|
+
currency: string;
|
|
171
|
+
errorReason: string;
|
|
172
|
+
retryUrl: string;
|
|
173
|
+
expireHours: number;
|
|
174
|
+
}
|
|
175
|
+
/** 用户信息查询接口 — 由业务项目实现 */
|
|
176
|
+
interface RecoveryUserLookup {
|
|
177
|
+
getUser(userId: string): Promise<{
|
|
178
|
+
email?: string;
|
|
179
|
+
name?: string;
|
|
180
|
+
} | null>;
|
|
181
|
+
}
|
|
182
|
+
/** 重试链接生成接口 — 由业务项目实现或使用默认 */
|
|
183
|
+
interface RecoveryUrlGenerator {
|
|
184
|
+
generateRetryUrl(order: Order): Promise<string | null>;
|
|
185
|
+
}
|
|
186
|
+
declare const RECOVERY_MAIL_SENDER = "RECOVERY_MAIL_SENDER";
|
|
187
|
+
declare const RECOVERY_USER_LOOKUP = "RECOVERY_USER_LOOKUP";
|
|
188
|
+
declare const RECOVERY_URL_GENERATOR = "RECOVERY_URL_GENERATOR";
|
|
189
|
+
interface RecoveryOptions {
|
|
190
|
+
/** 最大挽回次数(默认 3) */
|
|
191
|
+
maxAttempts?: number;
|
|
192
|
+
/** 重试链接有效期(小时,默认 48) */
|
|
193
|
+
retryLinkExpireHours?: number;
|
|
194
|
+
/** 前端基础 URL(用于默认重试链接生成) */
|
|
195
|
+
frontendUrl?: string;
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* 付款失败挽回服务
|
|
199
|
+
*
|
|
200
|
+
* 流程:Webhook 失败 → handleFailedPayment() → 生成重试链接 → 发挽回邮件
|
|
201
|
+
*
|
|
202
|
+
* 依赖注入(均为可选,未注入时仅日志记录):
|
|
203
|
+
* - RECOVERY_MAIL_SENDER: 邮件发送实现
|
|
204
|
+
* - RECOVERY_USER_LOOKUP: 用户信息查询
|
|
205
|
+
* - RECOVERY_URL_GENERATOR: 自定义重试链接生成
|
|
206
|
+
*/
|
|
207
|
+
declare class PaymentRecoveryService {
|
|
208
|
+
private readonly orderService;
|
|
209
|
+
private readonly paymentService;
|
|
210
|
+
private readonly mailSender?;
|
|
211
|
+
private readonly userLookup?;
|
|
212
|
+
private readonly urlGenerator?;
|
|
213
|
+
private readonly eventEmitter?;
|
|
214
|
+
private readonly logger;
|
|
215
|
+
private readonly options;
|
|
216
|
+
/** 内存挽回计数(生产环境建议由业务项目持久化) */
|
|
217
|
+
private readonly recoveryAttempts;
|
|
218
|
+
constructor(orderService: OrderService, paymentService: PaymentService, mailSender?: RecoveryMailSender | undefined, userLookup?: RecoveryUserLookup | undefined, urlGenerator?: RecoveryUrlGenerator | undefined, eventEmitter?: EventEmitter2);
|
|
219
|
+
/** 设置挽回选项 */
|
|
220
|
+
configure(options: RecoveryOptions): void;
|
|
221
|
+
/**
|
|
222
|
+
* 处理付款失败 — 核心挽回入口
|
|
223
|
+
*/
|
|
224
|
+
handleFailedPayment(orderId: string, errorCode?: string, errorMessage?: string): Promise<void>;
|
|
225
|
+
/**
|
|
226
|
+
* 重试失败订单 — 将 failed → created 并重新发起支付
|
|
227
|
+
*/
|
|
228
|
+
retryOrder(orderId: string): Promise<Order>;
|
|
229
|
+
/** 获取订单挽回记录 */
|
|
230
|
+
getRecoveryAttempts(orderId: string): {
|
|
231
|
+
count: number;
|
|
232
|
+
lastAt: Date;
|
|
233
|
+
} | undefined;
|
|
234
|
+
private generateRetryUrl;
|
|
235
|
+
}
|
|
236
|
+
/** Stripe 错误码 → 用户友好中文描述 */
|
|
237
|
+
declare function friendlyErrorReason(errorCode?: string, errorMessage?: string): string;
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* 支付系统事件常量及接口
|
|
241
|
+
*/
|
|
242
|
+
declare const PaymentEvents: {
|
|
243
|
+
readonly ORDER_CREATED: "payment.order.created";
|
|
244
|
+
readonly ORDER_PAID: "payment.order.paid";
|
|
245
|
+
readonly ORDER_FAILED: "payment.order.failed";
|
|
246
|
+
readonly ORDER_CANCELED: "payment.order.canceled";
|
|
247
|
+
readonly ORDER_REFUNDED: "payment.order.refunded";
|
|
248
|
+
readonly PAYMENT_RECOVERY_SENT: "payment.recovery.sent";
|
|
249
|
+
};
|
|
250
|
+
type PaymentEventType = (typeof PaymentEvents)[keyof typeof PaymentEvents];
|
|
251
|
+
interface OrderFailedEvent {
|
|
252
|
+
orderId: string;
|
|
253
|
+
orderNumber?: string;
|
|
254
|
+
userId?: string;
|
|
255
|
+
amount: number;
|
|
256
|
+
currency: string;
|
|
257
|
+
providerId: string;
|
|
258
|
+
errorCode?: string;
|
|
259
|
+
errorMessage?: string;
|
|
260
|
+
}
|
|
261
|
+
interface PaymentRecoverySentEvent {
|
|
262
|
+
orderId: string;
|
|
263
|
+
userId?: string;
|
|
264
|
+
email: string;
|
|
265
|
+
retryUrl: string;
|
|
266
|
+
attemptNumber: number;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
declare const PAYMENT_PROVIDERS = "PAYMENT_PROVIDERS";
|
|
270
|
+
interface PaymentModuleOptions {
|
|
271
|
+
providers?: PaymentProvider[];
|
|
272
|
+
}
|
|
273
|
+
interface PaymentModuleAsyncOptions {
|
|
274
|
+
imports?: Array<Type | DynamicModule>;
|
|
275
|
+
useFactory: (...args: unknown[]) => PaymentModuleOptions | Promise<PaymentModuleOptions>;
|
|
276
|
+
inject?: InjectionToken[];
|
|
277
|
+
}
|
|
278
|
+
declare class ZuckerPaymentModule {
|
|
279
|
+
static forRoot(options?: PaymentModuleOptions): DynamicModule;
|
|
280
|
+
static forRootAsync(options: PaymentModuleAsyncOptions): DynamicModule;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
export { type CreateOrderParams, type CreatePaymentParams, type Order, type OrderFailedEvent, OrderService, type OrderStatus, PAYMENT_PROVIDERS, type PaymentEventType, PaymentEvents, type PaymentIntent, type PaymentModuleAsyncOptions, type PaymentModuleOptions, type PaymentProvider, type PaymentRecoverySentEvent, PaymentRecoveryService, type PaymentResult, PaymentService, type PaymentStatus, RECOVERY_MAIL_SENDER, RECOVERY_URL_GENERATOR, RECOVERY_USER_LOOKUP, type RecoveryEmailParams, type RecoveryMailSender, type RecoveryOptions, type RecoveryUrlGenerator, type RecoveryUserLookup, type RefundResult, type Subscription, type SubscriptionPlan, type SubscriptionProvider, type WebhookEvent, ZuckerPaymentModule, friendlyErrorReason };
|