@xenterprises/fastify-xstripe 1.1.0 → 1.2.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 +57 -12
- package/README.md +108 -253
- package/index.d.ts +78 -184
- package/package.json +3 -4
- package/src/webhooks/webhooks.js +10 -10
- package/src/xStripe.js +28 -15
- package/.dockerignore +0 -62
- package/.env.example +0 -116
- package/.gitlab-ci.yml +0 -45
- package/API.md +0 -574
- package/CHANGELOG.md +0 -96
- package/EXAMPLES.md +0 -883
- package/MIGRATION.md +0 -374
- package/QUICK_START.md +0 -179
- package/SECURITY.md +0 -465
- package/TESTING.md +0 -357
- package/server/app.js +0 -557
- package/test/handlers.test.js +0 -959
- package/test/xStripe.integration.test.js +0 -409
package/index.d.ts
CHANGED
|
@@ -3,10 +3,10 @@
|
|
|
3
3
|
* TypeScript Type Definitions
|
|
4
4
|
*
|
|
5
5
|
* @module @xenterprises/fastify-xstripe
|
|
6
|
-
* @version 1.
|
|
6
|
+
* @version 1.2.0
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
import { FastifyPluginAsync, FastifyInstance
|
|
9
|
+
import { FastifyPluginAsync, FastifyInstance } from 'fastify';
|
|
10
10
|
import Stripe from 'stripe';
|
|
11
11
|
|
|
12
12
|
/**
|
|
@@ -16,6 +16,10 @@ export type StripeWebhookEvent = Stripe.Event;
|
|
|
16
16
|
|
|
17
17
|
/**
|
|
18
18
|
* Webhook Event Handler Function
|
|
19
|
+
*
|
|
20
|
+
* @param event - The Stripe webhook event object
|
|
21
|
+
* @param fastify - The Fastify instance (access to decorators)
|
|
22
|
+
* @param stripe - The Stripe client instance
|
|
19
23
|
*/
|
|
20
24
|
export type WebhookEventHandler = (
|
|
21
25
|
event: StripeWebhookEvent,
|
|
@@ -72,94 +76,20 @@ export interface DefaultHandlers {
|
|
|
72
76
|
* Plugin Configuration Options
|
|
73
77
|
*/
|
|
74
78
|
export interface XStripePluginOptions {
|
|
75
|
-
/** Stripe API Key (Secret Key) */
|
|
76
|
-
apiKey
|
|
79
|
+
/** Stripe API Key (Secret Key). Required. */
|
|
80
|
+
apiKey: string;
|
|
77
81
|
|
|
78
|
-
/** Stripe Webhook Signing Secret */
|
|
79
|
-
webhookSecret
|
|
82
|
+
/** Stripe Webhook Signing Secret. Required. */
|
|
83
|
+
webhookSecret: string;
|
|
80
84
|
|
|
81
|
-
/** Webhook endpoint path */
|
|
85
|
+
/** Webhook endpoint path. Defaults to "/stripe/webhook". */
|
|
82
86
|
webhookPath?: string;
|
|
83
87
|
|
|
84
|
-
/** Custom event handlers (override defaults) */
|
|
88
|
+
/** Custom event handlers (override defaults). */
|
|
85
89
|
handlers?: Partial<DefaultHandlers>;
|
|
86
90
|
|
|
87
|
-
/**
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
/** Request timeout in milliseconds */
|
|
91
|
-
requestTimeout?: number;
|
|
92
|
-
|
|
93
|
-
/** Enable event logging */
|
|
94
|
-
logEvents?: boolean;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
/**
|
|
98
|
-
* Helper Functions
|
|
99
|
-
*/
|
|
100
|
-
export namespace helpers {
|
|
101
|
-
/**
|
|
102
|
-
* Format amount as currency string
|
|
103
|
-
* @param amount Amount in cents
|
|
104
|
-
* @param currency Currency code (USD, EUR, etc.)
|
|
105
|
-
* @returns Formatted currency string (e.g., "$20.00")
|
|
106
|
-
*/
|
|
107
|
-
function formatAmount(amount: number, currency: string): string;
|
|
108
|
-
|
|
109
|
-
/**
|
|
110
|
-
* Get plan name from subscription
|
|
111
|
-
* @param subscription Subscription object
|
|
112
|
-
* @returns Plan name or product name
|
|
113
|
-
*/
|
|
114
|
-
function getPlanName(subscription: Stripe.Subscription): string;
|
|
115
|
-
|
|
116
|
-
/**
|
|
117
|
-
* Check if subscription is active
|
|
118
|
-
* @param subscription Subscription object
|
|
119
|
-
* @returns True if subscription is active
|
|
120
|
-
*/
|
|
121
|
-
function isActiveSubscription(subscription: Stripe.Subscription): boolean;
|
|
122
|
-
|
|
123
|
-
/**
|
|
124
|
-
* Get customer email from various objects
|
|
125
|
-
* @param obj Stripe object with customer reference
|
|
126
|
-
* @param stripe Stripe client instance
|
|
127
|
-
* @returns Customer email
|
|
128
|
-
*/
|
|
129
|
-
function getCustomerEmail(obj: any, stripe: Stripe): Promise<string>;
|
|
130
|
-
|
|
131
|
-
/**
|
|
132
|
-
* Create idempotent request ID from event
|
|
133
|
-
* @param event Stripe webhook event
|
|
134
|
-
* @returns Idempotency key
|
|
135
|
-
*/
|
|
136
|
-
function createIdempotencyKey(event: StripeWebhookEvent): string;
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
/**
|
|
140
|
-
* xStripe Service Methods (available on fastify.xStripe)
|
|
141
|
-
*/
|
|
142
|
-
export interface XStripeService {
|
|
143
|
-
/**
|
|
144
|
-
* Register custom event handler
|
|
145
|
-
* @param eventType Stripe event type
|
|
146
|
-
* @param handler Event handler function
|
|
147
|
-
*/
|
|
148
|
-
onEvent(eventType: string, handler: WebhookEventHandler): void;
|
|
149
|
-
|
|
150
|
-
/**
|
|
151
|
-
* Get registered handler for event type
|
|
152
|
-
* @param eventType Stripe event type
|
|
153
|
-
* @returns Handler function or undefined
|
|
154
|
-
*/
|
|
155
|
-
getHandler(eventType: string): WebhookEventHandler | undefined;
|
|
156
|
-
|
|
157
|
-
/**
|
|
158
|
-
* Execute event handler
|
|
159
|
-
* @param event Stripe webhook event
|
|
160
|
-
* @returns Promise that resolves when handler completes
|
|
161
|
-
*/
|
|
162
|
-
executeHandler(event: StripeWebhookEvent): Promise<void>;
|
|
91
|
+
/** Stripe API version. Defaults to "2024-11-20.acacia". */
|
|
92
|
+
apiVersion?: string;
|
|
163
93
|
}
|
|
164
94
|
|
|
165
95
|
/**
|
|
@@ -167,101 +97,77 @@ export interface XStripeService {
|
|
|
167
97
|
*/
|
|
168
98
|
declare module 'fastify' {
|
|
169
99
|
interface FastifyInstance {
|
|
170
|
-
/** xStripe service methods */
|
|
171
|
-
xStripe: XStripeService;
|
|
172
|
-
|
|
173
100
|
/** Stripe client instance */
|
|
174
101
|
stripe: Stripe;
|
|
175
102
|
}
|
|
176
103
|
}
|
|
177
104
|
|
|
178
105
|
/**
|
|
179
|
-
*
|
|
106
|
+
* Helper Functions
|
|
180
107
|
*/
|
|
181
|
-
export
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
id: string;
|
|
185
|
-
type: string;
|
|
186
|
-
data: any;
|
|
187
|
-
[key: string]: any;
|
|
188
|
-
};
|
|
189
|
-
}
|
|
108
|
+
export declare namespace helpers {
|
|
109
|
+
/** Extract customer email from various Stripe objects */
|
|
110
|
+
function getCustomerEmail(event: StripeWebhookEvent, stripe: Stripe): string | Promise<string | null> | null;
|
|
190
111
|
|
|
191
|
-
/**
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
status: 'success' | 'error';
|
|
112
|
+
/** Format amount from cents to currency string */
|
|
113
|
+
function formatAmount(cents: number, currency?: string): string;
|
|
114
|
+
|
|
115
|
+
/** Get plan name from subscription */
|
|
116
|
+
function getPlanName(subscription: Stripe.Subscription): string;
|
|
197
117
|
|
|
198
|
-
/**
|
|
199
|
-
|
|
118
|
+
/** Check if subscription is in trial */
|
|
119
|
+
function isInTrial(subscription: Stripe.Subscription): boolean;
|
|
200
120
|
|
|
201
|
-
/**
|
|
202
|
-
|
|
121
|
+
/** Check if subscription is active (including trialing) */
|
|
122
|
+
function isActiveSubscription(subscription: Stripe.Subscription): boolean;
|
|
203
123
|
|
|
204
|
-
/**
|
|
205
|
-
|
|
124
|
+
/** Get days until trial ends */
|
|
125
|
+
function getDaysUntilTrialEnd(subscription: Stripe.Subscription): number | null;
|
|
206
126
|
|
|
207
|
-
/**
|
|
208
|
-
|
|
209
|
-
}
|
|
127
|
+
/** Check if event is a subscription renewal */
|
|
128
|
+
function isRenewal(event: StripeWebhookEvent): boolean;
|
|
210
129
|
|
|
211
|
-
/**
|
|
212
|
-
|
|
213
|
-
*/
|
|
214
|
-
export interface Plan {
|
|
215
|
-
productId: string;
|
|
216
|
-
name: string;
|
|
217
|
-
description?: string;
|
|
218
|
-
images?: string[];
|
|
219
|
-
prices: PriceInfo[];
|
|
220
|
-
metadata?: Record<string, any>;
|
|
221
|
-
}
|
|
130
|
+
/** Get subscription status display text */
|
|
131
|
+
function getSubscriptionStatusText(status: string): string;
|
|
222
132
|
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
amount: number;
|
|
226
|
-
currency: string;
|
|
227
|
-
interval?: string;
|
|
228
|
-
intervalCount?: number;
|
|
229
|
-
trialPeriodDays?: number;
|
|
230
|
-
nickname?: string;
|
|
231
|
-
metadata?: Record<string, any>;
|
|
232
|
-
}
|
|
133
|
+
/** Extract metadata from event */
|
|
134
|
+
function getMetadata(event: StripeWebhookEvent): Record<string, string>;
|
|
233
135
|
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
createdAt: Date;
|
|
246
|
-
}
|
|
136
|
+
/** Check if event is a test event */
|
|
137
|
+
function isTestEvent(event: StripeWebhookEvent): boolean;
|
|
138
|
+
|
|
139
|
+
/** Get human-readable event description */
|
|
140
|
+
function getEventDescription(event: StripeWebhookEvent): string;
|
|
141
|
+
|
|
142
|
+
/** Calculate MRR from subscription (in cents) */
|
|
143
|
+
function calculateMRR(subscription: Stripe.Subscription): number;
|
|
144
|
+
|
|
145
|
+
/** Get payment method type display text */
|
|
146
|
+
function getPaymentMethodType(paymentMethod: Stripe.PaymentMethod | null): string;
|
|
247
147
|
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
148
|
+
/** Extract line items from invoice */
|
|
149
|
+
function getInvoiceLineItems(invoice: Stripe.Invoice): Array<{
|
|
150
|
+
description: string | null;
|
|
151
|
+
amount: number;
|
|
152
|
+
quantity: number | null;
|
|
153
|
+
priceId: string | undefined;
|
|
154
|
+
}>;
|
|
155
|
+
|
|
156
|
+
/** Check if invoice is for subscription vs one-time payment */
|
|
157
|
+
function isSubscriptionInvoice(invoice: Stripe.Invoice): boolean;
|
|
158
|
+
|
|
159
|
+
/** Get next billing date from subscription */
|
|
160
|
+
function getNextBillingDate(subscription: Stripe.Subscription): Date | null;
|
|
161
|
+
|
|
162
|
+
/** Format date from Unix timestamp */
|
|
163
|
+
function formatDate(unixTimestamp: number | null, locale?: string): string | null;
|
|
260
164
|
}
|
|
261
165
|
|
|
262
166
|
/**
|
|
263
167
|
* xStripe Plugin
|
|
264
|
-
*
|
|
168
|
+
*
|
|
169
|
+
* Registers Stripe webhook handling with signature verification and
|
|
170
|
+
* decorates the Fastify instance with a Stripe client.
|
|
265
171
|
*
|
|
266
172
|
* @example
|
|
267
173
|
* ```typescript
|
|
@@ -273,37 +179,25 @@ export interface SubscriptionInfo {
|
|
|
273
179
|
* await fastify.register(xStripe, {
|
|
274
180
|
* apiKey: process.env.STRIPE_API_KEY,
|
|
275
181
|
* webhookSecret: process.env.STRIPE_WEBHOOK_SECRET,
|
|
276
|
-
* webhookPath: '/
|
|
277
|
-
*
|
|
278
|
-
*
|
|
279
|
-
*
|
|
280
|
-
*
|
|
281
|
-
*
|
|
282
|
-
*
|
|
182
|
+
* webhookPath: '/stripe/webhook',
|
|
183
|
+
* handlers: {
|
|
184
|
+
* 'customer.subscription.created': async (event, fastify, stripe) => {
|
|
185
|
+
* const subscription = event.data.object;
|
|
186
|
+
* console.log('New subscription:', subscription.id);
|
|
187
|
+
* },
|
|
188
|
+
* },
|
|
283
189
|
* });
|
|
284
|
-
*
|
|
285
|
-
* // Webhook route automatically registered at webhookPath
|
|
286
|
-
* // POST /webhooks/stripe
|
|
287
|
-
*
|
|
288
|
-
* // Use included API endpoints
|
|
289
|
-
* // GET /plans
|
|
290
|
-
* // GET /plans/:productId
|
|
291
|
-
* // POST /create-checkout-session
|
|
292
|
-
* // POST /create-payment-session
|
|
293
|
-
* // GET /customer/:customerId/subscriptions
|
|
294
|
-
* // POST /subscription/:id/update
|
|
295
|
-
* // GET /customer/:customerId/payment-methods
|
|
296
|
-
* // POST /customer/:customerId/payment-methods
|
|
297
|
-
* // POST /customer/:customerId/payment-methods/:paymentMethodId/default
|
|
298
|
-
* // DELETE /customer/:customerId/payment-methods/:paymentMethodId
|
|
299
190
|
* ```
|
|
300
191
|
*/
|
|
301
192
|
declare const xStripe: FastifyPluginAsync<XStripePluginOptions>;
|
|
302
193
|
|
|
303
194
|
export default xStripe;
|
|
195
|
+
export { xStripe };
|
|
304
196
|
|
|
305
|
-
/**
|
|
306
|
-
* Re-export Stripe types for convenience
|
|
307
|
-
*/
|
|
197
|
+
/** Re-export for convenience */
|
|
308
198
|
export { Stripe };
|
|
309
199
|
export type { StripeWebhookEvent as WebhookEvent };
|
|
200
|
+
|
|
201
|
+
/** Default handlers */
|
|
202
|
+
export { defaultHandlers } from './src/handlers/defaultHandlers.js';
|
|
203
|
+
export { exampleHandlers } from './src/handlers/exampleHandlers.js';
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xenterprises/fastify-xstripe",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.2.0",
|
|
5
5
|
"description": "Fastify plugin for Stripe webhooks with simplified, testable handlers for subscription events.",
|
|
6
6
|
"main": "src/index.js",
|
|
7
7
|
"exports": {
|
|
@@ -12,10 +12,10 @@
|
|
|
12
12
|
"scripts": {
|
|
13
13
|
"start": "fastify start -l info server/app.js",
|
|
14
14
|
"dev": "fastify start -w -l info -P server/app.js",
|
|
15
|
-
"test": "node --test test/handlers.test.js"
|
|
15
|
+
"test": "node --test test/handlers.test.js test/xStripe.integration.test.js"
|
|
16
16
|
},
|
|
17
17
|
"author": "Tim Mushen",
|
|
18
|
-
"license": "
|
|
18
|
+
"license": "UNLICENSED",
|
|
19
19
|
"engines": {
|
|
20
20
|
"node": ">=20.0.0",
|
|
21
21
|
"npm": ">=10.0.0"
|
|
@@ -40,7 +40,6 @@
|
|
|
40
40
|
"devDependencies": {
|
|
41
41
|
"@types/node": "^22.7.4",
|
|
42
42
|
"fastify": "^5.1.0",
|
|
43
|
-
"fastify-plugin": "^5.0.0",
|
|
44
43
|
"typescript": "^5.6.3"
|
|
45
44
|
},
|
|
46
45
|
"dependencies": {
|
package/src/webhooks/webhooks.js
CHANGED
|
@@ -20,8 +20,8 @@ export async function setupWebhooks(fastify, options) {
|
|
|
20
20
|
const sig = request.headers["stripe-signature"];
|
|
21
21
|
|
|
22
22
|
if (!sig) {
|
|
23
|
-
fastify.log.error("Missing stripe-signature header");
|
|
24
|
-
return reply.code(400).send({ error: "Missing stripe-signature header" });
|
|
23
|
+
fastify.log.error("[xStripe] Missing stripe-signature header");
|
|
24
|
+
return reply.code(400).send({ error: "[xStripe] Missing stripe-signature header" });
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
let event;
|
|
@@ -33,12 +33,12 @@ export async function setupWebhooks(fastify, options) {
|
|
|
33
33
|
// Verify webhook signature
|
|
34
34
|
event = stripe.webhooks.constructEvent(rawBody, sig, webhookSecret);
|
|
35
35
|
} catch (err) {
|
|
36
|
-
fastify.log.error(`Webhook signature verification failed: ${err.message}`);
|
|
37
|
-
return reply.code(400).send({ error: `Webhook
|
|
36
|
+
fastify.log.error(`[xStripe] Webhook signature verification failed: ${err.message}`);
|
|
37
|
+
return reply.code(400).send({ error: `[xStripe] Webhook signature verification failed: ${err.message}` });
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
// Log the event
|
|
41
|
-
fastify.log.info(`Received
|
|
41
|
+
fastify.log.info(`[xStripe] Received webhook: ${event.type}`);
|
|
42
42
|
|
|
43
43
|
// Get handler for this event type
|
|
44
44
|
const handler = eventHandlers[event.type];
|
|
@@ -47,9 +47,9 @@ export async function setupWebhooks(fastify, options) {
|
|
|
47
47
|
try {
|
|
48
48
|
// Execute handler
|
|
49
49
|
await handler(event, fastify, stripe);
|
|
50
|
-
fastify.log.info(`Successfully processed ${event.type}`);
|
|
50
|
+
fastify.log.info(`[xStripe] Successfully processed ${event.type}`);
|
|
51
51
|
} catch (err) {
|
|
52
|
-
fastify.log.error(`Error processing ${event.type}: ${err.message}`);
|
|
52
|
+
fastify.log.error(`[xStripe] Error processing ${event.type}: ${err.message}`);
|
|
53
53
|
// Return 200 to acknowledge receipt, even if processing failed
|
|
54
54
|
// This prevents Stripe from retrying immediately
|
|
55
55
|
return reply.code(200).send({
|
|
@@ -59,7 +59,7 @@ export async function setupWebhooks(fastify, options) {
|
|
|
59
59
|
});
|
|
60
60
|
}
|
|
61
61
|
} else {
|
|
62
|
-
fastify.log.warn(`No handler registered for event type: ${event.type}`);
|
|
62
|
+
fastify.log.warn(`[xStripe] No handler registered for event type: ${event.type}`);
|
|
63
63
|
}
|
|
64
64
|
|
|
65
65
|
// Always return 200 to acknowledge receipt
|
|
@@ -67,6 +67,6 @@ export async function setupWebhooks(fastify, options) {
|
|
|
67
67
|
}
|
|
68
68
|
);
|
|
69
69
|
|
|
70
|
-
|
|
71
|
-
|
|
70
|
+
fastify.log.info(`[xStripe] Webhooks enabled at ${webhookPath}`);
|
|
71
|
+
fastify.log.info(`[xStripe] Registered ${Object.keys(eventHandlers).length} event handlers`);
|
|
72
72
|
}
|
package/src/xStripe.js
CHANGED
|
@@ -13,11 +13,27 @@ async function xStripe(fastify, options) {
|
|
|
13
13
|
} = options;
|
|
14
14
|
|
|
15
15
|
// Validate required options
|
|
16
|
-
if (!apiKey) {
|
|
17
|
-
throw new Error("
|
|
16
|
+
if (!apiKey || typeof apiKey !== "string") {
|
|
17
|
+
throw new Error("[xStripe] apiKey is required and must be a string");
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
if (!webhookSecret || typeof webhookSecret !== "string") {
|
|
21
|
+
throw new Error("[xStripe] webhookSecret is required and must be a string");
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
if (typeof webhookPath !== "string") {
|
|
25
|
+
throw new Error("[xStripe] webhookPath must be a string");
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
if (typeof handlers !== "object" || Array.isArray(handlers)) {
|
|
29
|
+
throw new Error("[xStripe] handlers must be a plain object");
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
if (typeof apiVersion !== "string") {
|
|
33
|
+
throw new Error("[xStripe] apiVersion must be a string");
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
fastify.log.info("[xStripe] Initializing Stripe plugin...");
|
|
21
37
|
|
|
22
38
|
// Initialize Stripe client
|
|
23
39
|
const stripe = new Stripe(apiKey, { apiVersion });
|
|
@@ -25,21 +41,18 @@ async function xStripe(fastify, options) {
|
|
|
25
41
|
// Decorate Fastify with Stripe client
|
|
26
42
|
fastify.decorate("stripe", stripe);
|
|
27
43
|
|
|
28
|
-
// Setup webhook handling
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
});
|
|
36
|
-
} else {
|
|
37
|
-
fastify.log.warn("⚠️ Stripe webhook secret not provided. Webhook handling disabled.");
|
|
38
|
-
}
|
|
44
|
+
// Setup webhook handling
|
|
45
|
+
await setupWebhooks(fastify, {
|
|
46
|
+
stripe,
|
|
47
|
+
webhookSecret,
|
|
48
|
+
webhookPath,
|
|
49
|
+
handlers,
|
|
50
|
+
});
|
|
39
51
|
|
|
40
|
-
|
|
52
|
+
fastify.log.info("[xStripe] Ready");
|
|
41
53
|
}
|
|
42
54
|
|
|
43
55
|
export default fp(xStripe, {
|
|
44
56
|
name: "xStripe",
|
|
57
|
+
fastify: ">=5.0.0",
|
|
45
58
|
});
|
package/.dockerignore
DELETED
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
# Git
|
|
2
|
-
.git
|
|
3
|
-
.gitignore
|
|
4
|
-
.gitattributes
|
|
5
|
-
|
|
6
|
-
# Node modules (will be installed in container)
|
|
7
|
-
node_modules
|
|
8
|
-
npm-debug.log*
|
|
9
|
-
yarn-debug.log*
|
|
10
|
-
yarn-error.log*
|
|
11
|
-
lerna-debug.log*
|
|
12
|
-
|
|
13
|
-
# Dependencies
|
|
14
|
-
.npm
|
|
15
|
-
.eslintcache
|
|
16
|
-
*.tsbuildinfo
|
|
17
|
-
|
|
18
|
-
# Temporary files
|
|
19
|
-
.DS_Store
|
|
20
|
-
Thumbs.db
|
|
21
|
-
*.tmp
|
|
22
|
-
.env.local
|
|
23
|
-
.env.*.local
|
|
24
|
-
|
|
25
|
-
# IDE
|
|
26
|
-
.vscode
|
|
27
|
-
.idea
|
|
28
|
-
*.swp
|
|
29
|
-
*.swo
|
|
30
|
-
*.swn
|
|
31
|
-
*~
|
|
32
|
-
|
|
33
|
-
# Test & Coverage
|
|
34
|
-
coverage
|
|
35
|
-
.nyc_output
|
|
36
|
-
test
|
|
37
|
-
*.test.js
|
|
38
|
-
|
|
39
|
-
# Build artifacts (if any)
|
|
40
|
-
dist
|
|
41
|
-
build
|
|
42
|
-
out
|
|
43
|
-
|
|
44
|
-
# Docker files (not needed in image)
|
|
45
|
-
Dockerfile*
|
|
46
|
-
docker-compose*.yml
|
|
47
|
-
.dockerignore
|
|
48
|
-
|
|
49
|
-
# CI/CD
|
|
50
|
-
.github
|
|
51
|
-
.gitlab-ci.yml
|
|
52
|
-
|
|
53
|
-
# Documentation (optional - include if you want docs in image)
|
|
54
|
-
# *.md
|
|
55
|
-
|
|
56
|
-
# Example/demo files
|
|
57
|
-
examples
|
|
58
|
-
demo
|
|
59
|
-
|
|
60
|
-
# Logs
|
|
61
|
-
logs
|
|
62
|
-
*.log
|
package/.env.example
DELETED
|
@@ -1,116 +0,0 @@
|
|
|
1
|
-
# ============================================================================
|
|
2
|
-
# xStripe Fastify Plugin - Environment Configuration
|
|
3
|
-
# ============================================================================
|
|
4
|
-
# This file defines environment variables for the xStripe module.
|
|
5
|
-
# Copy this to .env and update values for your environment.
|
|
6
|
-
# ============================================================================
|
|
7
|
-
|
|
8
|
-
# ============================================================================
|
|
9
|
-
# SERVER CONFIGURATION
|
|
10
|
-
# ============================================================================
|
|
11
|
-
|
|
12
|
-
# Server port (default: 3000)
|
|
13
|
-
PORT=3000
|
|
14
|
-
|
|
15
|
-
# Node environment (development | production | test)
|
|
16
|
-
NODE_ENV=development
|
|
17
|
-
|
|
18
|
-
# Server hostname/domain (used in webhook URLs and responses)
|
|
19
|
-
# Update this to your actual domain in production
|
|
20
|
-
DOMAIN=http://localhost:3000
|
|
21
|
-
|
|
22
|
-
# ============================================================================
|
|
23
|
-
# STRIPE CONFIGURATION - REQUIRED
|
|
24
|
-
# ============================================================================
|
|
25
|
-
|
|
26
|
-
# Stripe API Key (Secret Key)
|
|
27
|
-
# Get from: https://dashboard.stripe.com/apikeys
|
|
28
|
-
# Format: sk_test_... (test mode) or sk_live_... (production)
|
|
29
|
-
# NEVER commit this value - use environment variables only
|
|
30
|
-
STRIPE_API_KEY=sk_test_your_key_here
|
|
31
|
-
|
|
32
|
-
# Stripe Webhook Signing Secret
|
|
33
|
-
# Get from: https://dashboard.stripe.com/webhooks
|
|
34
|
-
# Copy the "Signing secret" for your webhook endpoint
|
|
35
|
-
# Format: whsec_...
|
|
36
|
-
STRIPE_WEBHOOK_SECRET=whsec_your_secret_here
|
|
37
|
-
|
|
38
|
-
# ============================================================================
|
|
39
|
-
# WEBHOOK CONFIGURATION
|
|
40
|
-
# ============================================================================
|
|
41
|
-
|
|
42
|
-
# Webhook endpoint path (relative to domain)
|
|
43
|
-
# Default: /webhooks/stripe
|
|
44
|
-
# STRIPE_WEBHOOK_PATH=/webhooks/stripe
|
|
45
|
-
|
|
46
|
-
# Webhook events to listen for (space or comma-separated)
|
|
47
|
-
# Default: all supported events
|
|
48
|
-
# Examples:
|
|
49
|
-
# customer.created,customer.updated,customer.deleted
|
|
50
|
-
# invoice.created,invoice.finalized,invoice.paid
|
|
51
|
-
# charge.succeeded,charge.failed
|
|
52
|
-
# STRIPE_WEBHOOK_EVENTS=*
|
|
53
|
-
|
|
54
|
-
# ============================================================================
|
|
55
|
-
# LOGGING & MONITORING
|
|
56
|
-
# ============================================================================
|
|
57
|
-
|
|
58
|
-
# Fastify logger level (trace, debug, info, warn, error, fatal)
|
|
59
|
-
LOG_LEVEL=info
|
|
60
|
-
|
|
61
|
-
# Enable webhook event logging
|
|
62
|
-
# LOG_WEBHOOK_EVENTS=true
|
|
63
|
-
|
|
64
|
-
# Enable handler execution logging
|
|
65
|
-
# LOG_HANDLER_EXECUTION=true
|
|
66
|
-
|
|
67
|
-
# ============================================================================
|
|
68
|
-
# ERROR HANDLING & RECOVERY
|
|
69
|
-
# ============================================================================
|
|
70
|
-
|
|
71
|
-
# Retry failed webhook handler executions
|
|
72
|
-
# ENABLE_HANDLER_RETRY=false
|
|
73
|
-
|
|
74
|
-
# Max retry attempts for failed handlers
|
|
75
|
-
# HANDLER_RETRY_MAX_ATTEMPTS=3
|
|
76
|
-
|
|
77
|
-
# Retry delay in milliseconds
|
|
78
|
-
# HANDLER_RETRY_DELAY_MS=5000
|
|
79
|
-
|
|
80
|
-
# ============================================================================
|
|
81
|
-
# SECURITY
|
|
82
|
-
# ============================================================================
|
|
83
|
-
|
|
84
|
-
# Enable HTTPS enforcement (if behind reverse proxy)
|
|
85
|
-
# HTTPS_ONLY=false
|
|
86
|
-
|
|
87
|
-
# Rate limiting: max webhook requests per minute
|
|
88
|
-
# WEBHOOK_RATE_LIMIT_WINDOW=1m
|
|
89
|
-
# WEBHOOK_RATE_LIMIT_MAX=1000
|
|
90
|
-
|
|
91
|
-
# Timeout for webhook handler execution (milliseconds)
|
|
92
|
-
# Default: 30000 (30 seconds)
|
|
93
|
-
# WEBHOOK_HANDLER_TIMEOUT=30000
|
|
94
|
-
|
|
95
|
-
# ============================================================================
|
|
96
|
-
# STRIPE ACCOUNT CONFIGURATION
|
|
97
|
-
# ============================================================================
|
|
98
|
-
|
|
99
|
-
# Stripe API Version (optional - uses account default if not set)
|
|
100
|
-
# Format: YYYY-MM-DD or leave empty
|
|
101
|
-
# STRIPE_API_VERSION=
|
|
102
|
-
|
|
103
|
-
# Enable Stripe CLI webhooks in development
|
|
104
|
-
# Set to true if using: stripe listen --forward-to localhost:3000/webhooks/stripe
|
|
105
|
-
# STRIPE_CLI_MODE=false
|
|
106
|
-
|
|
107
|
-
# ============================================================================
|
|
108
|
-
# DATABASE/STORAGE (optional - for persisting event data)
|
|
109
|
-
# ============================================================================
|
|
110
|
-
|
|
111
|
-
# Database URL for event persistence (optional)
|
|
112
|
-
# Example: postgresql://user:pass@localhost/stripe_events
|
|
113
|
-
# DATABASE_URL=
|
|
114
|
-
|
|
115
|
-
# Enable event persistence
|
|
116
|
-
# PERSIST_WEBHOOK_EVENTS=false
|