@zendfi/sdk 0.1.2 → 0.3.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/README.md +153 -252
- package/dist/chunk-YFOBPGQE.mjs +152 -0
- package/dist/express.d.mts +46 -0
- package/dist/express.d.ts +46 -0
- package/dist/express.js +220 -0
- package/dist/express.mjs +56 -0
- package/dist/index.d.mts +12 -385
- package/dist/index.d.ts +12 -385
- package/dist/index.js +132 -21
- package/dist/index.mjs +44 -76
- package/dist/nextjs.d.mts +37 -0
- package/dist/nextjs.d.ts +37 -0
- package/dist/nextjs.js +227 -0
- package/dist/nextjs.mjs +63 -0
- package/dist/webhook-handler-DG-zic8m.d.mts +390 -0
- package/dist/webhook-handler-DG-zic8m.d.ts +390 -0
- package/package.json +4 -7
package/dist/index.d.ts
CHANGED
|
@@ -1,328 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
* Complete type definitions for the ZendFi API
|
|
4
|
-
*/
|
|
5
|
-
type Environment = 'development' | 'staging' | 'production';
|
|
6
|
-
type Currency = 'USD' | 'EUR' | 'GBP';
|
|
7
|
-
type PaymentToken = 'SOL' | 'USDC' | 'USDT';
|
|
8
|
-
type PaymentStatus = 'pending' | 'confirmed' | 'failed' | 'expired';
|
|
9
|
-
type SubscriptionStatus = 'active' | 'canceled' | 'past_due' | 'paused';
|
|
10
|
-
type InstallmentPlanStatus = 'active' | 'completed' | 'defaulted' | 'cancelled';
|
|
11
|
-
type EscrowStatus = 'pending' | 'funded' | 'released' | 'refunded' | 'disputed' | 'cancelled';
|
|
12
|
-
type InvoiceStatus = 'draft' | 'sent' | 'paid';
|
|
13
|
-
type SplitStatus = 'pending' | 'processing' | 'completed' | 'failed' | 'refunded';
|
|
14
|
-
type WebhookEvent = 'payment.created' | 'payment.confirmed' | 'payment.failed' | 'payment.expired' | 'subscription.created' | 'subscription.activated' | 'subscription.canceled' | 'subscription.payment_failed' | 'split.completed' | 'split.failed' | 'installment.due' | 'installment.paid' | 'installment.late' | 'escrow.funded' | 'escrow.released' | 'escrow.refunded' | 'escrow.disputed' | 'invoice.sent' | 'invoice.paid';
|
|
15
|
-
interface ZendFiConfig {
|
|
16
|
-
apiKey?: string;
|
|
17
|
-
baseURL?: string;
|
|
18
|
-
environment?: Environment;
|
|
19
|
-
timeout?: number;
|
|
20
|
-
retries?: number;
|
|
21
|
-
idempotencyEnabled?: boolean;
|
|
22
|
-
}
|
|
23
|
-
interface SplitRecipient {
|
|
24
|
-
recipient_wallet: string;
|
|
25
|
-
recipient_name?: string;
|
|
26
|
-
percentage?: number;
|
|
27
|
-
fixed_amount_usd?: number;
|
|
28
|
-
split_order?: number;
|
|
29
|
-
}
|
|
30
|
-
interface CreatePaymentRequest {
|
|
31
|
-
amount: number;
|
|
32
|
-
currency?: Currency;
|
|
33
|
-
token?: PaymentToken;
|
|
34
|
-
description?: string;
|
|
35
|
-
customer_email?: string;
|
|
36
|
-
redirect_url?: string;
|
|
37
|
-
metadata?: Record<string, any>;
|
|
38
|
-
split_recipients?: SplitRecipient[];
|
|
39
|
-
}
|
|
40
|
-
/**
|
|
41
|
-
* Payment Link - Shareable checkout links
|
|
42
|
-
*/
|
|
43
|
-
interface CreatePaymentLinkRequest {
|
|
44
|
-
amount: number;
|
|
45
|
-
currency?: string;
|
|
46
|
-
token?: string;
|
|
47
|
-
description?: string;
|
|
48
|
-
max_uses?: number;
|
|
49
|
-
expires_at?: string;
|
|
50
|
-
metadata?: Record<string, any>;
|
|
51
|
-
}
|
|
52
|
-
interface PaymentLink {
|
|
53
|
-
id: string;
|
|
54
|
-
link_code: string;
|
|
55
|
-
payment_url: string;
|
|
56
|
-
hosted_page_url: string;
|
|
57
|
-
amount: number;
|
|
58
|
-
currency: string;
|
|
59
|
-
token: string;
|
|
60
|
-
max_uses?: number;
|
|
61
|
-
uses_count: number;
|
|
62
|
-
expires_at?: string;
|
|
63
|
-
is_active: boolean;
|
|
64
|
-
created_at: string;
|
|
65
|
-
url: string;
|
|
66
|
-
}
|
|
67
|
-
interface Payment {
|
|
68
|
-
id: string;
|
|
69
|
-
merchant_id: string;
|
|
70
|
-
amount_usd?: number;
|
|
71
|
-
amount?: number;
|
|
72
|
-
currency?: string;
|
|
73
|
-
payment_token?: PaymentToken;
|
|
74
|
-
status: PaymentStatus;
|
|
75
|
-
customer_wallet?: string;
|
|
76
|
-
customer_email?: string;
|
|
77
|
-
description?: string;
|
|
78
|
-
checkout_url?: string;
|
|
79
|
-
payment_url?: string;
|
|
80
|
-
qr_code?: string;
|
|
81
|
-
expires_at: string;
|
|
82
|
-
confirmed_at?: string;
|
|
83
|
-
transaction_signature?: string;
|
|
84
|
-
metadata?: Record<string, any>;
|
|
85
|
-
split_ids?: string[];
|
|
86
|
-
created_at?: string;
|
|
87
|
-
updated_at?: string;
|
|
88
|
-
}
|
|
89
|
-
interface ListPaymentsRequest {
|
|
90
|
-
page?: number;
|
|
91
|
-
limit?: number;
|
|
92
|
-
status?: PaymentStatus;
|
|
93
|
-
from_date?: string;
|
|
94
|
-
to_date?: string;
|
|
95
|
-
}
|
|
96
|
-
interface PaginatedResponse<T> {
|
|
97
|
-
data: T[];
|
|
98
|
-
pagination: {
|
|
99
|
-
page: number;
|
|
100
|
-
limit: number;
|
|
101
|
-
total: number;
|
|
102
|
-
total_pages: number;
|
|
103
|
-
};
|
|
104
|
-
}
|
|
105
|
-
interface CreateSubscriptionPlanRequest {
|
|
106
|
-
name: string;
|
|
107
|
-
description?: string;
|
|
108
|
-
amount: number;
|
|
109
|
-
currency?: Currency;
|
|
110
|
-
interval: 'daily' | 'weekly' | 'monthly' | 'yearly';
|
|
111
|
-
interval_count?: number;
|
|
112
|
-
trial_days?: number;
|
|
113
|
-
metadata?: Record<string, any>;
|
|
114
|
-
}
|
|
115
|
-
interface SubscriptionPlan {
|
|
116
|
-
id: string;
|
|
117
|
-
merchant_id: string;
|
|
118
|
-
name: string;
|
|
119
|
-
description?: string;
|
|
120
|
-
amount: number;
|
|
121
|
-
currency: Currency;
|
|
122
|
-
interval: string;
|
|
123
|
-
interval_count: number;
|
|
124
|
-
trial_days: number;
|
|
125
|
-
is_active: boolean;
|
|
126
|
-
metadata?: Record<string, any>;
|
|
127
|
-
created_at: string;
|
|
128
|
-
updated_at: string;
|
|
129
|
-
}
|
|
130
|
-
interface CreateSubscriptionRequest {
|
|
131
|
-
plan_id: string;
|
|
132
|
-
customer_email: string;
|
|
133
|
-
customer_wallet?: string;
|
|
134
|
-
metadata?: Record<string, any>;
|
|
135
|
-
}
|
|
136
|
-
interface Subscription {
|
|
137
|
-
id: string;
|
|
138
|
-
plan_id: string;
|
|
139
|
-
merchant_id: string;
|
|
140
|
-
customer_email: string;
|
|
141
|
-
customer_wallet?: string;
|
|
142
|
-
status: SubscriptionStatus;
|
|
143
|
-
current_period_start: string;
|
|
144
|
-
current_period_end: string;
|
|
145
|
-
trial_end?: string;
|
|
146
|
-
canceled_at?: string;
|
|
147
|
-
metadata?: Record<string, any>;
|
|
148
|
-
created_at: string;
|
|
149
|
-
updated_at: string;
|
|
150
|
-
}
|
|
151
|
-
interface WebhookPayload {
|
|
152
|
-
event: WebhookEvent;
|
|
153
|
-
timestamp: string;
|
|
154
|
-
merchant_id: string;
|
|
155
|
-
data: Payment | Subscription;
|
|
156
|
-
}
|
|
157
|
-
interface VerifyWebhookRequest {
|
|
158
|
-
payload: string | object;
|
|
159
|
-
signature: string;
|
|
160
|
-
secret: string;
|
|
161
|
-
}
|
|
162
|
-
declare class ZendFiError extends Error {
|
|
163
|
-
statusCode?: number | undefined;
|
|
164
|
-
code?: string | undefined;
|
|
165
|
-
details?: any | undefined;
|
|
166
|
-
constructor(message: string, statusCode?: number | undefined, code?: string | undefined, details?: any | undefined);
|
|
167
|
-
}
|
|
168
|
-
declare class AuthenticationError extends ZendFiError {
|
|
169
|
-
constructor(message?: string);
|
|
170
|
-
}
|
|
171
|
-
declare class ValidationError extends ZendFiError {
|
|
172
|
-
constructor(message: string, details?: any);
|
|
173
|
-
}
|
|
174
|
-
declare class NetworkError extends ZendFiError {
|
|
175
|
-
constructor(message: string);
|
|
176
|
-
}
|
|
177
|
-
declare class RateLimitError extends ZendFiError {
|
|
178
|
-
constructor(message?: string);
|
|
179
|
-
}
|
|
180
|
-
/**
|
|
181
|
-
* Installment Plans - Pay over time
|
|
182
|
-
*/
|
|
183
|
-
interface InstallmentScheduleItem {
|
|
184
|
-
installment_number: number;
|
|
185
|
-
due_date: string;
|
|
186
|
-
amount: string;
|
|
187
|
-
status: string;
|
|
188
|
-
payment_id?: string;
|
|
189
|
-
paid_at?: string;
|
|
190
|
-
}
|
|
191
|
-
interface CreateInstallmentPlanRequest {
|
|
192
|
-
customer_wallet: string;
|
|
193
|
-
customer_email?: string;
|
|
194
|
-
total_amount: number;
|
|
195
|
-
installment_count: number;
|
|
196
|
-
first_payment_date?: string;
|
|
197
|
-
payment_frequency_days: number;
|
|
198
|
-
description?: string;
|
|
199
|
-
late_fee_amount?: number;
|
|
200
|
-
grace_period_days?: number;
|
|
201
|
-
metadata?: Record<string, any>;
|
|
202
|
-
}
|
|
203
|
-
interface CreateInstallmentPlanResponse {
|
|
204
|
-
plan_id: string;
|
|
205
|
-
status: string;
|
|
206
|
-
}
|
|
207
|
-
interface InstallmentPlan {
|
|
208
|
-
id?: string;
|
|
209
|
-
plan_id?: string;
|
|
210
|
-
merchant_id?: string;
|
|
211
|
-
customer_wallet?: string;
|
|
212
|
-
customer_email?: string;
|
|
213
|
-
total_amount?: string;
|
|
214
|
-
installment_count?: number;
|
|
215
|
-
amount_per_installment?: string;
|
|
216
|
-
payment_schedule?: InstallmentScheduleItem[];
|
|
217
|
-
paid_count?: number;
|
|
218
|
-
status: InstallmentPlanStatus | string;
|
|
219
|
-
description?: string;
|
|
220
|
-
late_fee_amount?: string;
|
|
221
|
-
grace_period_days?: number;
|
|
222
|
-
metadata?: Record<string, any>;
|
|
223
|
-
created_at?: string;
|
|
224
|
-
updated_at?: string;
|
|
225
|
-
completed_at?: string;
|
|
226
|
-
defaulted_at?: string;
|
|
227
|
-
}
|
|
228
|
-
/**
|
|
229
|
-
* Escrow - Secure fund holding
|
|
230
|
-
*/
|
|
231
|
-
interface ReleaseCondition {
|
|
232
|
-
type: 'manual_approval' | 'time_based' | 'confirmation_required' | 'milestone';
|
|
233
|
-
approver?: string;
|
|
234
|
-
approved?: boolean;
|
|
235
|
-
release_after?: string;
|
|
236
|
-
confirmations_needed?: number;
|
|
237
|
-
confirmed_by?: string[];
|
|
238
|
-
description?: string;
|
|
239
|
-
approved_by?: string;
|
|
240
|
-
}
|
|
241
|
-
interface CreateEscrowRequest {
|
|
242
|
-
buyer_wallet: string;
|
|
243
|
-
seller_wallet: string;
|
|
244
|
-
amount: number;
|
|
245
|
-
currency?: Currency;
|
|
246
|
-
token?: PaymentToken;
|
|
247
|
-
description?: string;
|
|
248
|
-
release_conditions: ReleaseCondition;
|
|
249
|
-
metadata?: Record<string, any>;
|
|
250
|
-
}
|
|
251
|
-
interface Escrow {
|
|
252
|
-
id: string;
|
|
253
|
-
payment_id: string;
|
|
254
|
-
merchant_id: string;
|
|
255
|
-
buyer_wallet: string;
|
|
256
|
-
seller_wallet: string;
|
|
257
|
-
escrow_wallet: string;
|
|
258
|
-
amount: number;
|
|
259
|
-
currency: Currency;
|
|
260
|
-
token: PaymentToken;
|
|
261
|
-
release_conditions: ReleaseCondition;
|
|
262
|
-
status: EscrowStatus;
|
|
263
|
-
payment_url?: string;
|
|
264
|
-
qr_code?: string;
|
|
265
|
-
funded_at?: string;
|
|
266
|
-
released_at?: string;
|
|
267
|
-
refunded_at?: string;
|
|
268
|
-
disputed_at?: string;
|
|
269
|
-
dispute_reason?: string;
|
|
270
|
-
release_transaction_signature?: string;
|
|
271
|
-
refund_transaction_signature?: string;
|
|
272
|
-
metadata?: Record<string, any>;
|
|
273
|
-
created_at: string;
|
|
274
|
-
updated_at: string;
|
|
275
|
-
}
|
|
276
|
-
interface ApproveEscrowRequest {
|
|
277
|
-
approver_wallet: string;
|
|
278
|
-
}
|
|
279
|
-
interface RefundEscrowRequest {
|
|
280
|
-
reason: string;
|
|
281
|
-
}
|
|
282
|
-
interface DisputeEscrowRequest {
|
|
283
|
-
reason: string;
|
|
284
|
-
}
|
|
285
|
-
/**
|
|
286
|
-
* Invoices - Professional billing
|
|
287
|
-
*/
|
|
288
|
-
interface InvoiceLineItem {
|
|
289
|
-
description: string;
|
|
290
|
-
quantity: number;
|
|
291
|
-
unit_price: number;
|
|
292
|
-
}
|
|
293
|
-
interface CreateInvoiceRequest {
|
|
294
|
-
customer_email: string;
|
|
295
|
-
customer_name?: string;
|
|
296
|
-
amount: number;
|
|
297
|
-
token?: PaymentToken;
|
|
298
|
-
description: string;
|
|
299
|
-
line_items?: InvoiceLineItem[];
|
|
300
|
-
due_date?: string;
|
|
301
|
-
metadata?: Record<string, any>;
|
|
302
|
-
}
|
|
303
|
-
interface Invoice {
|
|
304
|
-
id: string;
|
|
305
|
-
invoice_number: string;
|
|
306
|
-
merchant_id: string;
|
|
307
|
-
customer_email: string;
|
|
308
|
-
customer_name?: string;
|
|
309
|
-
amount_usd: number;
|
|
310
|
-
token: PaymentToken;
|
|
311
|
-
description: string;
|
|
312
|
-
line_items?: InvoiceLineItem[];
|
|
313
|
-
status: InvoiceStatus;
|
|
314
|
-
payment_url?: string;
|
|
315
|
-
due_date?: string;
|
|
316
|
-
sent_at?: string;
|
|
317
|
-
paid_at?: string;
|
|
318
|
-
metadata?: Record<string, any>;
|
|
319
|
-
created_at: string;
|
|
320
|
-
updated_at: string;
|
|
321
|
-
}
|
|
1
|
+
import { Z as ZendFiConfig, C as CreatePaymentRequest, P as Payment, L as ListPaymentsRequest, b as PaginatedResponse, c as CreateSubscriptionPlanRequest, S as SubscriptionPlan, d as CreateSubscriptionRequest, e as Subscription, f as CreatePaymentLinkRequest, g as PaymentLink, h as CreateInstallmentPlanRequest, I as InstallmentPlan, i as CreateEscrowRequest, E as Escrow, A as ApproveEscrowRequest, R as RefundEscrowRequest, D as DisputeEscrowRequest, j as CreateInvoiceRequest, k as Invoice, V as VerifyWebhookRequest, l as WebhookPayload } from './webhook-handler-DG-zic8m.js';
|
|
2
|
+
export { q as ApiKeyMode, G as AuthenticationError, M as CreateInstallmentPlanResponse, r as Currency, o as Environment, w as EscrowStatus, v as InstallmentPlanStatus, K as InstallmentScheduleItem, Q as InvoiceLineItem, x as InvoiceStatus, N as NetworkError, t as PaymentStatus, s as PaymentToken, J as RateLimitError, O as ReleaseCondition, B as SplitRecipient, y as SplitStatus, u as SubscriptionStatus, H as ValidationError, z as WebhookEvent, n as WebhookEventHandler, W as WebhookHandlerConfig, a as WebhookHandlers, m as WebhookResult, F as ZendFiError, p as processWebhook } from './webhook-handler-DG-zic8m.js';
|
|
322
3
|
|
|
323
4
|
/**
|
|
324
|
-
* ZendFi SDK Client
|
|
325
|
-
*
|
|
5
|
+
* ZendFi SDK Client.
|
|
6
|
+
* AZero-config TypeScript SDK for crypto payments
|
|
326
7
|
*/
|
|
327
8
|
declare class ZendFiClient {
|
|
328
9
|
private config;
|
|
@@ -368,7 +49,7 @@ declare class ZendFiClient {
|
|
|
368
49
|
*/
|
|
369
50
|
getPaymentLink(linkCode: string): Promise<PaymentLink>;
|
|
370
51
|
/**
|
|
371
|
-
* List all payment links
|
|
52
|
+
* List all payment links for the authenticated merchant
|
|
372
53
|
*/
|
|
373
54
|
listPaymentLinks(): Promise<PaymentLink[]>;
|
|
374
55
|
/**
|
|
@@ -515,6 +196,10 @@ declare class ConfigLoader {
|
|
|
515
196
|
* Load configuration from various sources
|
|
516
197
|
*/
|
|
517
198
|
static load(options?: Partial<ZendFiConfig>): Required<ZendFiConfig>;
|
|
199
|
+
/**
|
|
200
|
+
* Detect mode (test/live) from API key prefix
|
|
201
|
+
*/
|
|
202
|
+
private static detectMode;
|
|
518
203
|
/**
|
|
519
204
|
* Detect environment based on various signals
|
|
520
205
|
*/
|
|
@@ -525,6 +210,8 @@ declare class ConfigLoader {
|
|
|
525
210
|
private static loadApiKey;
|
|
526
211
|
/**
|
|
527
212
|
* Get base URL for API
|
|
213
|
+
* Note: Both test and live modes use the same API endpoint.
|
|
214
|
+
* The backend routes requests to devnet or mainnet based on API key prefix.
|
|
528
215
|
*/
|
|
529
216
|
private static getBaseURL;
|
|
530
217
|
/**
|
|
@@ -608,64 +295,4 @@ declare function verifyExpressWebhook(request: any, secret?: string): Promise<We
|
|
|
608
295
|
*/
|
|
609
296
|
declare function verifyWebhookSignature(payload: string, signature: string, secret: string): boolean;
|
|
610
297
|
|
|
611
|
-
|
|
612
|
-
* ZendFi Webhook Handlers
|
|
613
|
-
* Type-safe webhook handlers with automatic verification and deduplication
|
|
614
|
-
*/
|
|
615
|
-
|
|
616
|
-
/**
|
|
617
|
-
* Webhook handler configuration
|
|
618
|
-
*/
|
|
619
|
-
interface WebhookHandlerConfig {
|
|
620
|
-
/** Your webhook secret from ZendFi dashboard */
|
|
621
|
-
secret: string;
|
|
622
|
-
/** Optional: Path to store processed webhook IDs (for deduplication) */
|
|
623
|
-
onProcessed?: (webhookId: string) => Promise<void>;
|
|
624
|
-
/** Optional: Check if webhook was already processed */
|
|
625
|
-
isProcessed?: (webhookId: string) => Promise<boolean>;
|
|
626
|
-
/** Optional: Custom error handler */
|
|
627
|
-
onError?: (error: Error, event?: WebhookEvent) => void | Promise<void>;
|
|
628
|
-
}
|
|
629
|
-
/**
|
|
630
|
-
* Event handler function type
|
|
631
|
-
*/
|
|
632
|
-
type WebhookEventHandler<T = any> = (data: T, event: WebhookPayload) => void | Promise<void>;
|
|
633
|
-
/**
|
|
634
|
-
* Webhook handlers map - type-safe event handlers
|
|
635
|
-
*/
|
|
636
|
-
type WebhookHandlers = Partial<{
|
|
637
|
-
'payment.created': WebhookEventHandler;
|
|
638
|
-
'payment.confirmed': WebhookEventHandler;
|
|
639
|
-
'payment.failed': WebhookEventHandler;
|
|
640
|
-
'payment.expired': WebhookEventHandler;
|
|
641
|
-
'subscription.created': WebhookEventHandler;
|
|
642
|
-
'subscription.activated': WebhookEventHandler;
|
|
643
|
-
'subscription.canceled': WebhookEventHandler;
|
|
644
|
-
'subscription.payment_failed': WebhookEventHandler;
|
|
645
|
-
'split.completed': WebhookEventHandler;
|
|
646
|
-
'split.failed': WebhookEventHandler;
|
|
647
|
-
'installment.due': WebhookEventHandler;
|
|
648
|
-
'installment.paid': WebhookEventHandler;
|
|
649
|
-
'installment.late': WebhookEventHandler;
|
|
650
|
-
'escrow.funded': WebhookEventHandler;
|
|
651
|
-
'escrow.released': WebhookEventHandler;
|
|
652
|
-
'escrow.refunded': WebhookEventHandler;
|
|
653
|
-
'escrow.disputed': WebhookEventHandler;
|
|
654
|
-
'invoice.sent': WebhookEventHandler;
|
|
655
|
-
'invoice.paid': WebhookEventHandler;
|
|
656
|
-
}>;
|
|
657
|
-
/**
|
|
658
|
-
* Webhook processing result
|
|
659
|
-
*/
|
|
660
|
-
interface WebhookResult {
|
|
661
|
-
success: boolean;
|
|
662
|
-
processed: boolean;
|
|
663
|
-
error?: string;
|
|
664
|
-
event?: WebhookEvent;
|
|
665
|
-
}
|
|
666
|
-
/**
|
|
667
|
-
* Process webhook with handlers
|
|
668
|
-
*/
|
|
669
|
-
declare function processWebhook(payload: WebhookPayload, handlers: WebhookHandlers, config: WebhookHandlerConfig): Promise<WebhookResult>;
|
|
670
|
-
|
|
671
|
-
export { type ApproveEscrowRequest, AuthenticationError, ConfigLoader, type CreateEscrowRequest, type CreateInstallmentPlanRequest, type CreateInstallmentPlanResponse, type CreateInvoiceRequest, type CreatePaymentLinkRequest, type CreatePaymentRequest, type CreateSubscriptionPlanRequest, type CreateSubscriptionRequest, type Currency, type DisputeEscrowRequest, type Environment, type Escrow, type EscrowStatus, type InstallmentPlan, type InstallmentPlanStatus, type InstallmentScheduleItem, type Invoice, type InvoiceLineItem, type InvoiceStatus, type ListPaymentsRequest, NetworkError, type PaginatedResponse, type Payment, type PaymentLink, type PaymentStatus, type PaymentToken, RateLimitError, type RefundEscrowRequest, type ReleaseCondition, type SplitRecipient, type SplitStatus, type Subscription, type SubscriptionPlan, type SubscriptionStatus, ValidationError, type VerifyWebhookRequest, type WebhookEvent, type WebhookEventHandler, type WebhookHandlerConfig, type WebhookHandlers, type WebhookPayload, type WebhookResult, ZendFiClient, type ZendFiConfig, ZendFiError, processWebhook, verifyExpressWebhook, verifyNextWebhook, verifyWebhookSignature, zendfi };
|
|
298
|
+
export { ApproveEscrowRequest, ConfigLoader, CreateEscrowRequest, CreateInstallmentPlanRequest, CreateInvoiceRequest, CreatePaymentLinkRequest, CreatePaymentRequest, CreateSubscriptionPlanRequest, CreateSubscriptionRequest, DisputeEscrowRequest, Escrow, InstallmentPlan, Invoice, ListPaymentsRequest, PaginatedResponse, Payment, PaymentLink, RefundEscrowRequest, Subscription, SubscriptionPlan, VerifyWebhookRequest, WebhookPayload, ZendFiClient, ZendFiConfig, verifyExpressWebhook, verifyNextWebhook, verifyWebhookSignature, zendfi };
|
package/dist/index.js
CHANGED
|
@@ -92,16 +92,30 @@ var ConfigLoader = class {
|
|
|
92
92
|
static load(options) {
|
|
93
93
|
const environment = this.detectEnvironment();
|
|
94
94
|
const apiKey = this.loadApiKey(options?.apiKey);
|
|
95
|
-
const
|
|
95
|
+
const mode = this.detectMode(apiKey);
|
|
96
|
+
const baseURL = this.getBaseURL(environment, mode, options?.baseURL);
|
|
96
97
|
return {
|
|
97
98
|
apiKey,
|
|
98
99
|
baseURL,
|
|
99
100
|
environment,
|
|
101
|
+
mode,
|
|
100
102
|
timeout: options?.timeout ?? 3e4,
|
|
101
103
|
retries: options?.retries ?? 3,
|
|
102
104
|
idempotencyEnabled: options?.idempotencyEnabled ?? true
|
|
103
105
|
};
|
|
104
106
|
}
|
|
107
|
+
/**
|
|
108
|
+
* Detect mode (test/live) from API key prefix
|
|
109
|
+
*/
|
|
110
|
+
static detectMode(apiKey) {
|
|
111
|
+
if (apiKey.startsWith("zfi_test_")) {
|
|
112
|
+
return "test";
|
|
113
|
+
}
|
|
114
|
+
if (apiKey.startsWith("zfi_live_")) {
|
|
115
|
+
return "live";
|
|
116
|
+
}
|
|
117
|
+
return "live";
|
|
118
|
+
}
|
|
105
119
|
/**
|
|
106
120
|
* Detect environment based on various signals
|
|
107
121
|
*/
|
|
@@ -150,8 +164,10 @@ var ConfigLoader = class {
|
|
|
150
164
|
}
|
|
151
165
|
/**
|
|
152
166
|
* Get base URL for API
|
|
167
|
+
* Note: Both test and live modes use the same API endpoint.
|
|
168
|
+
* The backend routes requests to devnet or mainnet based on API key prefix.
|
|
153
169
|
*/
|
|
154
|
-
static getBaseURL(_environment, explicitURL) {
|
|
170
|
+
static getBaseURL(_environment, _mode, explicitURL) {
|
|
155
171
|
if (explicitURL) return explicitURL;
|
|
156
172
|
return process.env.ZENDFI_API_URL || "https://api.zendfi.tech";
|
|
157
173
|
}
|
|
@@ -183,13 +199,17 @@ var ConfigLoader = class {
|
|
|
183
199
|
'Invalid API key format. ZendFi API keys should start with "zfi_test_" or "zfi_live_"'
|
|
184
200
|
);
|
|
185
201
|
}
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
202
|
+
const mode = this.detectMode(apiKey);
|
|
203
|
+
const env = this.detectEnvironment();
|
|
204
|
+
if (mode === "live" && env === "development") {
|
|
205
|
+
console.warn(
|
|
206
|
+
"\u26A0\uFE0F Warning: Using a live API key (zfi_live_) in development environment. This will create real mainnet transactions. Use a test key (zfi_test_) for devnet testing."
|
|
207
|
+
);
|
|
208
|
+
}
|
|
209
|
+
if (mode === "test" && env === "production") {
|
|
210
|
+
console.warn(
|
|
211
|
+
"\u26A0\uFE0F Warning: Using a test API key (zfi_test_) in production environment. This will create devnet transactions only. Use a live key (zfi_live_) for mainnet."
|
|
212
|
+
);
|
|
193
213
|
}
|
|
194
214
|
}
|
|
195
215
|
};
|
|
@@ -230,6 +250,11 @@ var ZendFiClient = class {
|
|
|
230
250
|
constructor(options) {
|
|
231
251
|
this.config = ConfigLoader.load(options);
|
|
232
252
|
ConfigLoader.validateApiKey(this.config.apiKey);
|
|
253
|
+
if (this.config.environment === "development") {
|
|
254
|
+
console.log(
|
|
255
|
+
`\u2713 ZendFi SDK initialized in ${this.config.mode} mode (${this.config.mode === "test" ? "devnet" : "mainnet"})`
|
|
256
|
+
);
|
|
257
|
+
}
|
|
233
258
|
}
|
|
234
259
|
/**
|
|
235
260
|
* Create a new payment
|
|
@@ -323,10 +348,14 @@ var ZendFiClient = class {
|
|
|
323
348
|
};
|
|
324
349
|
}
|
|
325
350
|
/**
|
|
326
|
-
* List all payment links
|
|
351
|
+
* List all payment links for the authenticated merchant
|
|
327
352
|
*/
|
|
328
353
|
async listPaymentLinks() {
|
|
329
|
-
|
|
354
|
+
const response = await this.request("GET", "/api/v1/payment-links");
|
|
355
|
+
return response.map((link) => ({
|
|
356
|
+
...link,
|
|
357
|
+
url: link.hosted_page_url
|
|
358
|
+
}));
|
|
330
359
|
}
|
|
331
360
|
/**
|
|
332
361
|
* Create an installment plan
|
|
@@ -677,6 +706,7 @@ function verifyWebhookSignature(payload, signature, secret) {
|
|
|
677
706
|
}
|
|
678
707
|
|
|
679
708
|
// src/webhook-handler.ts
|
|
709
|
+
var import_crypto2 = require("crypto");
|
|
680
710
|
var processedWebhooks = /* @__PURE__ */ new Set();
|
|
681
711
|
var defaultIsProcessed = async (webhookId) => {
|
|
682
712
|
return processedWebhooks.has(webhookId);
|
|
@@ -694,16 +724,19 @@ var defaultOnProcessed = async (webhookId) => {
|
|
|
694
724
|
function generateWebhookId(payload) {
|
|
695
725
|
return `${payload.merchant_id}:${payload.event}:${payload.timestamp}`;
|
|
696
726
|
}
|
|
697
|
-
async function
|
|
727
|
+
async function processPayload(payload, handlers, config) {
|
|
698
728
|
try {
|
|
699
729
|
const webhookId = generateWebhookId(payload);
|
|
700
|
-
const isProcessed = config.isProcessed || defaultIsProcessed;
|
|
701
|
-
const onProcessed = config.onProcessed || defaultOnProcessed;
|
|
702
|
-
|
|
730
|
+
const isProcessed = config.isProcessed || config.checkDuplicate || defaultIsProcessed;
|
|
731
|
+
const onProcessed = config.onProcessed || config.markProcessed || defaultOnProcessed;
|
|
732
|
+
const dedupEnabled = !!(config.enableDeduplication || config.isProcessed || config.checkDuplicate);
|
|
733
|
+
if (dedupEnabled && await isProcessed(webhookId)) {
|
|
703
734
|
return {
|
|
704
|
-
success:
|
|
735
|
+
success: false,
|
|
705
736
|
processed: false,
|
|
706
|
-
event: payload.event
|
|
737
|
+
event: payload.event,
|
|
738
|
+
error: "Duplicate webhook",
|
|
739
|
+
statusCode: 409
|
|
707
740
|
};
|
|
708
741
|
}
|
|
709
742
|
const handler = handlers[payload.event];
|
|
@@ -711,7 +744,8 @@ async function processWebhook(payload, handlers, config) {
|
|
|
711
744
|
return {
|
|
712
745
|
success: true,
|
|
713
746
|
processed: false,
|
|
714
|
-
event: payload.event
|
|
747
|
+
event: payload.event,
|
|
748
|
+
statusCode: 200
|
|
715
749
|
};
|
|
716
750
|
}
|
|
717
751
|
await handler(payload.data, payload);
|
|
@@ -723,14 +757,91 @@ async function processWebhook(payload, handlers, config) {
|
|
|
723
757
|
};
|
|
724
758
|
} catch (error) {
|
|
725
759
|
const err = error;
|
|
726
|
-
if (config
|
|
727
|
-
await config.onError(err,
|
|
760
|
+
if (config?.onError) {
|
|
761
|
+
await config.onError(err, error?.event);
|
|
762
|
+
}
|
|
763
|
+
return {
|
|
764
|
+
success: false,
|
|
765
|
+
processed: false,
|
|
766
|
+
error: err.message,
|
|
767
|
+
event: error?.event,
|
|
768
|
+
statusCode: 500
|
|
769
|
+
};
|
|
770
|
+
}
|
|
771
|
+
}
|
|
772
|
+
async function processWebhook(a, b, c) {
|
|
773
|
+
if (a && typeof a === "object" && a.event && b && c) {
|
|
774
|
+
return processPayload(a, b, c);
|
|
775
|
+
}
|
|
776
|
+
const opts = a;
|
|
777
|
+
if (!opts || !opts.signature && !opts.body && !opts.handlers) {
|
|
778
|
+
return {
|
|
779
|
+
success: false,
|
|
780
|
+
processed: false,
|
|
781
|
+
error: "Invalid arguments to processWebhook",
|
|
782
|
+
statusCode: 400
|
|
783
|
+
};
|
|
784
|
+
}
|
|
785
|
+
const signature = opts.signature;
|
|
786
|
+
const body = opts.body;
|
|
787
|
+
const handlers = opts.handlers || {};
|
|
788
|
+
const cfg = opts.config || {};
|
|
789
|
+
const secret = cfg.webhookSecret || cfg.secret;
|
|
790
|
+
if (!secret) {
|
|
791
|
+
return {
|
|
792
|
+
success: false,
|
|
793
|
+
processed: false,
|
|
794
|
+
error: "Webhook secret not provided",
|
|
795
|
+
statusCode: 400
|
|
796
|
+
};
|
|
797
|
+
}
|
|
798
|
+
if (!signature || !body) {
|
|
799
|
+
return {
|
|
800
|
+
success: false,
|
|
801
|
+
processed: false,
|
|
802
|
+
error: "Missing signature or body",
|
|
803
|
+
statusCode: 400
|
|
804
|
+
};
|
|
805
|
+
}
|
|
806
|
+
try {
|
|
807
|
+
const sig = typeof signature === "string" && signature.startsWith("sha256=") ? signature.slice("sha256=".length) : String(signature);
|
|
808
|
+
const hmac = (0, import_crypto2.createHmac)("sha256", secret).update(body, "utf8").digest("hex");
|
|
809
|
+
let ok = false;
|
|
810
|
+
try {
|
|
811
|
+
const sigBuf = Buffer.from(sig, "hex");
|
|
812
|
+
const hmacBuf = Buffer.from(hmac, "hex");
|
|
813
|
+
if (sigBuf.length === hmacBuf.length) {
|
|
814
|
+
ok = (0, import_crypto2.timingSafeEqual)(sigBuf, hmacBuf);
|
|
815
|
+
}
|
|
816
|
+
} catch (e) {
|
|
817
|
+
ok = (0, import_crypto2.timingSafeEqual)(Buffer.from(String(sig), "utf8"), Buffer.from(hmac, "utf8"));
|
|
728
818
|
}
|
|
819
|
+
if (!ok) {
|
|
820
|
+
return {
|
|
821
|
+
success: false,
|
|
822
|
+
processed: false,
|
|
823
|
+
error: "Invalid signature",
|
|
824
|
+
statusCode: 401
|
|
825
|
+
};
|
|
826
|
+
}
|
|
827
|
+
const payload = JSON.parse(body);
|
|
828
|
+
const fullConfig = {
|
|
829
|
+
secret,
|
|
830
|
+
isProcessed: cfg.isProcessed,
|
|
831
|
+
onProcessed: cfg.onProcessed,
|
|
832
|
+
onError: cfg.onError,
|
|
833
|
+
// Forward compatibility for alternate names and flags
|
|
834
|
+
enableDeduplication: cfg.enableDeduplication,
|
|
835
|
+
checkDuplicate: cfg.checkDuplicate,
|
|
836
|
+
markProcessed: cfg.markProcessed
|
|
837
|
+
};
|
|
838
|
+
return await processPayload(payload, handlers, fullConfig);
|
|
839
|
+
} catch (err) {
|
|
729
840
|
return {
|
|
730
841
|
success: false,
|
|
731
842
|
processed: false,
|
|
732
843
|
error: err.message,
|
|
733
|
-
|
|
844
|
+
statusCode: 500
|
|
734
845
|
};
|
|
735
846
|
}
|
|
736
847
|
}
|