0
# Configuration
1
2
Stripe's Node.js library provides comprehensive configuration options for authentication, request handling, error management, and advanced features. This documentation covers all configuration aspects from basic setup to advanced customization.
3
4
## Basic Configuration
5
6
### API Key Authentication
7
8
The primary method for authenticating with Stripe:
9
10
```typescript { .api }
11
import Stripe from 'stripe';
12
13
// Basic initialization with API key
14
const stripe = new Stripe('sk_test_...', {
15
apiVersion: '2025-08-27.basil',
16
typescript: true
17
});
18
19
// Environment-based configuration
20
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!, {
21
apiVersion: '2025-08-27.basil',
22
typescript: true
23
});
24
25
// Different keys for different environments
26
const apiKey = process.env.NODE_ENV === 'production'
27
? process.env.STRIPE_LIVE_SECRET_KEY
28
: process.env.STRIPE_TEST_SECRET_KEY;
29
30
const stripe = new Stripe(apiKey!, {
31
apiVersion: '2025-08-27.basil',
32
typescript: true
33
});
34
```
35
36
### Configuration Interface
37
38
Complete configuration options available:
39
40
```typescript { .api }
41
interface StripeConfig {
42
// API Configuration
43
apiVersion?: '2025-08-27.basil'; // Latest stable API version
44
typescript?: true; // Enable TypeScript support
45
46
// Network Configuration
47
maxNetworkRetries?: number; // Default: 1, max: 10
48
timeout?: number; // Request timeout in ms (default: 80000)
49
httpAgent?: HttpAgent; // Custom HTTP agent for proxies
50
httpClient?: HttpClient; // Custom HTTP client implementation
51
52
// Host Configuration
53
host?: string; // API host override (default: api.stripe.com)
54
port?: string | number; // API port override (default: 443)
55
protocol?: 'http' | 'https'; // Protocol override (default: https)
56
57
// Feature Configuration
58
telemetry?: boolean; // Enable/disable telemetry (default: true)
59
appInfo?: AppInfo; // Plugin identification
60
61
// Account Configuration
62
stripeAccount?: string; // Connect account for all requests
63
stripeContext?: string; // Context for all requests
64
}
65
66
// Advanced configuration example
67
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!, {
68
apiVersion: '2025-08-27.basil',
69
typescript: true,
70
maxNetworkRetries: 3,
71
timeout: 30000, // 30 seconds
72
telemetry: false,
73
appInfo: {
74
name: 'MyApp',
75
version: '1.0.0',
76
url: 'https://myapp.com'
77
}
78
});
79
```
80
81
## Network Configuration
82
83
### HTTP Agents and Proxies
84
85
Configure HTTP agents for proxy support and connection pooling:
86
87
```typescript { .api }
88
import { HttpsAgent } from 'agentkeepalive';
89
import { Agent as HttpAgent } from 'http';
90
import { Agent as HttpsProxyAgent } from 'https-proxy-agent';
91
92
// Keep-alive agent for better performance
93
const keepAliveAgent = new HttpsAgent({
94
keepAlive: true,
95
maxSockets: 100,
96
maxFreeSockets: 10,
97
timeout: 60000,
98
freeSocketTimeout: 30000
99
});
100
101
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!, {
102
httpAgent: keepAliveAgent,
103
apiVersion: '2025-08-27.basil'
104
});
105
106
// Proxy configuration
107
const proxyAgent = new HttpsProxyAgent('http://proxy.company.com:8080');
108
109
const stripeWithProxy = new Stripe(process.env.STRIPE_SECRET_KEY!, {
110
httpAgent: proxyAgent,
111
apiVersion: '2025-08-27.basil'
112
});
113
114
// Custom HTTP client implementation
115
class CustomHttpClient {
116
makeRequest(
117
host: string,
118
port: number,
119
path: string,
120
method: string,
121
headers: { [key: string]: string },
122
requestData: string,
123
protocol: string,
124
timeout: number
125
): Promise<any> {
126
// Custom implementation with logging, metrics, etc.
127
return fetch(`${protocol}://${host}:${port}${path}`, {
128
method,
129
headers,
130
body: requestData,
131
signal: AbortSignal.timeout(timeout)
132
}).then(response => ({
133
status: response.status,
134
headers: Object.fromEntries(response.headers.entries()),
135
body: response.text()
136
}));
137
}
138
}
139
140
const stripeWithCustomClient = new Stripe(process.env.STRIPE_SECRET_KEY!, {
141
httpClient: new CustomHttpClient(),
142
apiVersion: '2025-08-27.basil'
143
});
144
```
145
146
### Retry Configuration
147
148
Configure automatic retry behavior for failed requests:
149
150
```typescript { .api }
151
// Global retry configuration
152
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!, {
153
maxNetworkRetries: 5, // Retry up to 5 times
154
apiVersion: '2025-08-27.basil'
155
});
156
157
// Per-request retry override
158
const customer = await stripe.customers.create({
159
email: 'customer@example.com'
160
}, {
161
maxNetworkRetries: 2 // Override global setting
162
});
163
164
// Custom retry logic with exponential backoff
165
class RetryableHttpClient {
166
async makeRequest(...args: any[]): Promise<any> {
167
const maxRetries = 3;
168
let attempt = 0;
169
170
while (attempt <= maxRetries) {
171
try {
172
return await this.performRequest(...args);
173
} catch (error) {
174
if (attempt === maxRetries || !this.shouldRetry(error)) {
175
throw error;
176
}
177
178
const delay = Math.pow(2, attempt) * 1000; // Exponential backoff
179
await new Promise(resolve => setTimeout(resolve, delay));
180
attempt++;
181
}
182
}
183
}
184
185
private shouldRetry(error: any): boolean {
186
// Retry on network errors and 5xx status codes
187
return error.code === 'ECONNRESET' ||
188
error.code === 'ENOTFOUND' ||
189
(error.statusCode >= 500 && error.statusCode < 600);
190
}
191
192
private async performRequest(...args: any[]): Promise<any> {
193
// Actual HTTP request implementation
194
}
195
}
196
```
197
198
### Timeout Configuration
199
200
Configure request timeouts at various levels:
201
202
```typescript { .api }
203
// Global timeout configuration
204
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!, {
205
timeout: 15000, // 15 seconds for all requests
206
apiVersion: '2025-08-27.basil'
207
});
208
209
// Per-request timeout
210
const paymentIntent = await stripe.paymentIntents.create({
211
amount: 2000,
212
currency: 'usd'
213
}, {
214
timeout: 30000 // 30 seconds for this specific request
215
});
216
217
// Different timeouts for different operations
218
class TimeoutManager {
219
private readonly timeouts = {
220
create: 30000, // 30s for creates
221
update: 20000, // 20s for updates
222
list: 10000, // 10s for lists
223
retrieve: 5000 // 5s for retrievals
224
};
225
226
getTimeout(operation: keyof typeof this.timeouts): number {
227
return this.timeouts[operation];
228
}
229
}
230
231
const timeoutManager = new TimeoutManager();
232
233
// Use operation-specific timeouts
234
const customer = await stripe.customers.create({
235
email: 'customer@example.com'
236
}, {
237
timeout: timeoutManager.getTimeout('create')
238
});
239
```
240
241
## Request Options
242
243
### Per-Request Configuration
244
245
Override global settings for individual requests:
246
247
```typescript { .api }
248
interface RequestOptions {
249
apiKey?: string; // Override API key
250
idempotencyKey?: string; // Idempotency key for safe retries
251
stripeAccount?: string; // Connect account
252
stripeContext?: string; // Request context
253
apiVersion?: string; // API version override
254
maxNetworkRetries?: number; // Retry limit override
255
timeout?: number; // Timeout override
256
host?: string; // Host override
257
}
258
259
// API key override for multi-tenant applications
260
const platformCustomer = await stripe.customers.create({
261
email: 'platform@example.com'
262
}, {
263
apiKey: process.env.PLATFORM_SECRET_KEY
264
});
265
266
// Connect account operations
267
const connectedAccountCharge = await stripe.charges.create({
268
amount: 2000,
269
currency: 'usd',
270
source: 'tok_visa'
271
}, {
272
stripeAccount: 'acct_connected_account_id'
273
});
274
275
// Idempotency for safe retries
276
const idempotentPayment = await stripe.paymentIntents.create({
277
amount: 2000,
278
currency: 'usd'
279
}, {
280
idempotencyKey: `payment_${orderId}_${timestamp}`
281
});
282
283
// Context for request tracking
284
const contextualRequest = await stripe.customers.create({
285
email: 'customer@example.com'
286
}, {
287
stripeContext: 'signup_flow_step_3'
288
});
289
```
290
291
### Idempotency Management
292
293
Implement robust idempotency for reliable operations:
294
295
```typescript { .api }
296
class IdempotencyManager {
297
private generateKey(prefix: string, data: any): string {
298
const hash = require('crypto')
299
.createHash('sha256')
300
.update(JSON.stringify(data))
301
.digest('hex')
302
.substring(0, 16);
303
304
return `${prefix}_${Date.now()}_${hash}`;
305
}
306
307
async createPaymentIntent(params: Stripe.PaymentIntentCreateParams): Promise<Stripe.PaymentIntent> {
308
const idempotencyKey = this.generateKey('pi', params);
309
310
return stripe.paymentIntents.create(params, {
311
idempotencyKey
312
});
313
}
314
315
async createCustomer(params: Stripe.CustomerCreateParams): Promise<Stripe.Customer> {
316
// Use email as part of idempotency key for customers
317
const keyData = { email: params.email, name: params.name };
318
const idempotencyKey = this.generateKey('cus', keyData);
319
320
return stripe.customers.create(params, {
321
idempotencyKey
322
});
323
}
324
}
325
```
326
327
## Error Handling
328
329
### Error Types and Handling
330
331
Comprehensive error handling for different Stripe error types:
332
333
```typescript { .api }
334
// All Stripe error types
335
interface StripeErrorTypes {
336
StripeError: typeof Stripe.errors.StripeError;
337
StripeCardError: typeof Stripe.errors.StripeCardError;
338
StripeInvalidRequestError: typeof Stripe.errors.StripeInvalidRequestError;
339
StripeAPIError: typeof Stripe.errors.StripeAPIError;
340
StripeAuthenticationError: typeof Stripe.errors.StripeAuthenticationError;
341
StripePermissionError: typeof Stripe.errors.StripePermissionError;
342
StripeRateLimitError: typeof Stripe.errors.StripeRateLimitError;
343
StripeConnectionError: typeof Stripe.errors.StripeConnectionError;
344
StripeSignatureVerificationError: typeof Stripe.errors.StripeSignatureVerificationError;
345
StripeIdempotencyError: typeof Stripe.errors.StripeIdempotencyError;
346
StripeInvalidGrantError: typeof Stripe.errors.StripeInvalidGrantError;
347
StripeUnknownError: typeof Stripe.errors.StripeUnknownError;
348
}
349
350
// Comprehensive error handling function
351
async function handleStripeOperation<T>(operation: () => Promise<T>): Promise<T> {
352
try {
353
return await operation();
354
} catch (error) {
355
if (error instanceof stripe.errors.StripeCardError) {
356
// Card was declined
357
throw new PaymentError(
358
'Card declined',
359
error.decline_code,
360
error.code,
361
error.payment_intent?.id
362
);
363
} else if (error instanceof stripe.errors.StripeInvalidRequestError) {
364
// Invalid parameters
365
throw new ValidationError(
366
'Invalid request',
367
error.param,
368
error.code
369
);
370
} else if (error instanceof stripe.errors.StripeAuthenticationError) {
371
// Authentication failed
372
throw new AuthError('Authentication failed', error.code);
373
} else if (error instanceof stripe.errors.StripePermissionError) {
374
// Insufficient permissions
375
throw new AuthorizationError('Insufficient permissions', error.code);
376
} else if (error instanceof stripe.errors.StripeRateLimitError) {
377
// Rate limited
378
throw new RateLimitError('Rate limit exceeded', error.code);
379
} else if (error instanceof stripe.errors.StripeConnectionError) {
380
// Network error
381
throw new NetworkError('Network error', error.code);
382
} else if (error instanceof stripe.errors.StripeAPIError) {
383
// API error
384
throw new APIError('API error', error.code, error.statusCode);
385
} else {
386
// Unknown error
387
throw new UnknownError('Unknown error', error);
388
}
389
}
390
}
391
392
// Usage example with proper error handling
393
async function processPayment(paymentIntentId: string): Promise<PaymentResult> {
394
return handleStripeOperation(async () => {
395
const paymentIntent = await stripe.paymentIntents.retrieve(paymentIntentId);
396
397
if (paymentIntent.status === 'requires_payment_method') {
398
throw new Error('Payment method required');
399
}
400
401
const confirmed = await stripe.paymentIntents.confirm(paymentIntentId);
402
403
return {
404
success: true,
405
paymentIntent: confirmed
406
};
407
});
408
}
409
```
410
411
### Retry Logic for Errors
412
413
Implement intelligent retry logic based on error types:
414
415
```typescript { .api }
416
class StripeRetryHandler {
417
private readonly retryableErrors = [
418
'rate_limit',
419
'api_connection_error',
420
'api_error'
421
];
422
423
async withRetry<T>(
424
operation: () => Promise<T>,
425
maxRetries: number = 3
426
): Promise<T> {
427
let attempt = 0;
428
429
while (attempt <= maxRetries) {
430
try {
431
return await operation();
432
} catch (error) {
433
if (!this.shouldRetry(error) || attempt === maxRetries) {
434
throw error;
435
}
436
437
const delay = this.calculateDelay(attempt, error);
438
await this.delay(delay);
439
attempt++;
440
}
441
}
442
443
throw new Error('Max retries exceeded');
444
}
445
446
private shouldRetry(error: any): boolean {
447
if (error instanceof stripe.errors.StripeRateLimitError) {
448
return true;
449
}
450
451
if (error instanceof stripe.errors.StripeAPIError) {
452
return error.statusCode >= 500;
453
}
454
455
if (error instanceof stripe.errors.StripeConnectionError) {
456
return true;
457
}
458
459
return false;
460
}
461
462
private calculateDelay(attempt: number, error: any): number {
463
// Use Stripe's Retry-After header if available
464
if (error instanceof stripe.errors.StripeRateLimitError) {
465
const retryAfter = error.headers?.['retry-after'];
466
if (retryAfter) {
467
return parseInt(retryAfter) * 1000;
468
}
469
}
470
471
// Exponential backoff with jitter
472
const baseDelay = Math.pow(2, attempt) * 1000;
473
const jitter = Math.random() * 1000;
474
return baseDelay + jitter;
475
}
476
477
private delay(ms: number): Promise<void> {
478
return new Promise(resolve => setTimeout(resolve, ms));
479
}
480
}
481
482
// Usage
483
const retryHandler = new StripeRetryHandler();
484
485
const customer = await retryHandler.withRetry(() =>
486
stripe.customers.create({
487
email: 'customer@example.com'
488
})
489
);
490
```
491
492
## Advanced Configuration
493
494
### App Information
495
496
Configure application metadata for better support:
497
498
```typescript { .api }
499
interface AppInfo {
500
name: string;
501
version?: string;
502
url?: string;
503
partner_id?: string;
504
}
505
506
// Plugin/framework identification
507
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!, {
508
apiVersion: '2025-08-27.basil',
509
appInfo: {
510
name: 'MyEcommercePlugin',
511
version: '2.1.0',
512
url: 'https://github.com/mycompany/ecommerce-plugin',
513
partner_id: 'pp_partner_123'
514
}
515
});
516
517
// Dynamic app info based on environment
518
const getAppInfo = (): AppInfo => {
519
const packageJson = require('./package.json');
520
521
return {
522
name: packageJson.name,
523
version: packageJson.version,
524
url: packageJson.homepage
525
};
526
};
527
528
const stripeWithDynamicInfo = new Stripe(process.env.STRIPE_SECRET_KEY!, {
529
apiVersion: '2025-08-27.basil',
530
appInfo: getAppInfo()
531
});
532
```
533
534
### Telemetry Configuration
535
536
Control telemetry data collection:
537
538
```typescript { .api }
539
// Disable telemetry for privacy-sensitive applications
540
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!, {
541
apiVersion: '2025-08-27.basil',
542
telemetry: false
543
});
544
545
// Conditional telemetry based on environment
546
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!, {
547
apiVersion: '2025-08-27.basil',
548
telemetry: process.env.NODE_ENV === 'production'
549
});
550
```
551
552
### Event Monitoring
553
554
Set up request/response monitoring:
555
556
```typescript { .api }
557
// Request monitoring
558
stripe.on('request', (event: Stripe.RequestEvent) => {
559
console.log('Request made:', {
560
method: event.method,
561
url: event.url,
562
requestId: event.request_id
563
});
564
565
// Log to monitoring service
566
monitoring.logRequest({
567
method: event.method,
568
path: event.path,
569
requestId: event.request_id,
570
timestamp: new Date()
571
});
572
});
573
574
// Response monitoring
575
stripe.on('response', (event: Stripe.ResponseEvent) => {
576
console.log('Response received:', {
577
status: event.status_code,
578
requestId: event.request_id,
579
elapsed: event.elapsed
580
});
581
582
// Track performance metrics
583
metrics.timing('stripe.request_duration', event.elapsed, {
584
status_code: event.status_code.toString(),
585
method: event.method
586
});
587
588
// Alert on errors
589
if (event.status_code >= 400) {
590
alerting.notifyError('Stripe API Error', {
591
statusCode: event.status_code,
592
requestId: event.request_id,
593
elapsed: event.elapsed
594
});
595
}
596
});
597
598
// One-time event listeners
599
stripe.once('request', (event) => {
600
console.log('First request made:', event.request_id);
601
});
602
603
// Remove event listeners
604
const requestHandler = (event: Stripe.RequestEvent) => {
605
console.log('Request:', event.request_id);
606
};
607
608
stripe.on('request', requestHandler);
609
// Later...
610
stripe.off('request', requestHandler);
611
```
612
613
## Environment-Specific Configuration
614
615
### Multi-Environment Setup
616
617
Configure Stripe for different environments:
618
619
```typescript { .api }
620
interface StripeEnvironmentConfig {
621
apiKey: string;
622
webhookSecret: string;
623
publishableKey: string;
624
connectClientId?: string;
625
}
626
627
class StripeConfigManager {
628
private configs: Record<string, StripeEnvironmentConfig> = {
629
development: {
630
apiKey: process.env.STRIPE_TEST_SECRET_KEY!,
631
webhookSecret: process.env.STRIPE_TEST_WEBHOOK_SECRET!,
632
publishableKey: process.env.STRIPE_TEST_PUBLISHABLE_KEY!,
633
connectClientId: process.env.STRIPE_TEST_CONNECT_CLIENT_ID
634
},
635
staging: {
636
apiKey: process.env.STRIPE_STAGING_SECRET_KEY!,
637
webhookSecret: process.env.STRIPE_STAGING_WEBHOOK_SECRET!,
638
publishableKey: process.env.STRIPE_STAGING_PUBLISHABLE_KEY!,
639
connectClientId: process.env.STRIPE_STAGING_CONNECT_CLIENT_ID
640
},
641
production: {
642
apiKey: process.env.STRIPE_LIVE_SECRET_KEY!,
643
webhookSecret: process.env.STRIPE_LIVE_WEBHOOK_SECRET!,
644
publishableKey: process.env.STRIPE_LIVE_PUBLISHABLE_KEY!,
645
connectClientId: process.env.STRIPE_LIVE_CONNECT_CLIENT_ID
646
}
647
};
648
649
createStripeInstance(environment: string = process.env.NODE_ENV || 'development'): Stripe {
650
const config = this.configs[environment];
651
652
if (!config) {
653
throw new Error(`No Stripe configuration found for environment: ${environment}`);
654
}
655
656
return new Stripe(config.apiKey, {
657
apiVersion: '2025-08-27.basil',
658
typescript: true,
659
maxNetworkRetries: environment === 'production' ? 3 : 1,
660
timeout: environment === 'production' ? 30000 : 10000,
661
telemetry: environment === 'production',
662
appInfo: {
663
name: 'MyApp',
664
version: process.env.APP_VERSION || '1.0.0'
665
}
666
});
667
}
668
669
getConfig(environment: string = process.env.NODE_ENV || 'development'): StripeEnvironmentConfig {
670
return this.configs[environment];
671
}
672
}
673
674
// Usage
675
const configManager = new StripeConfigManager();
676
const stripe = configManager.createStripeInstance();
677
const config = configManager.getConfig();
678
```
679
680
### Security Best Practices
681
682
Implement security best practices for configuration:
683
684
```typescript { .api }
685
// Secure configuration loading
686
class SecureStripeConfig {
687
private static instance: SecureStripeConfig;
688
private stripe: Stripe;
689
690
private constructor() {
691
// Validate required environment variables
692
this.validateEnvironment();
693
694
// Create Stripe instance with security measures
695
this.stripe = new Stripe(this.getSecureApiKey(), {
696
apiVersion: '2025-08-27.basil',
697
typescript: true,
698
telemetry: this.isTelemetryEnabled(),
699
timeout: this.getTimeout(),
700
maxNetworkRetries: this.getMaxRetries()
701
});
702
703
// Set up security monitoring
704
this.setupSecurityMonitoring();
705
}
706
707
static getInstance(): SecureStripeConfig {
708
if (!SecureStripeConfig.instance) {
709
SecureStripeConfig.instance = new SecureStripeConfig();
710
}
711
return SecureStripeConfig.instance;
712
}
713
714
getStripe(): Stripe {
715
return this.stripe;
716
}
717
718
private validateEnvironment(): void {
719
const required = ['STRIPE_SECRET_KEY'];
720
const missing = required.filter(key => !process.env[key]);
721
722
if (missing.length > 0) {
723
throw new Error(`Missing required environment variables: ${missing.join(', ')}`);
724
}
725
726
// Validate API key format
727
const apiKey = process.env.STRIPE_SECRET_KEY!;
728
if (!apiKey.startsWith('sk_')) {
729
throw new Error('Invalid Stripe API key format');
730
}
731
732
// Warn about test keys in production
733
if (process.env.NODE_ENV === 'production' && apiKey.includes('test')) {
734
throw new Error('Test API key detected in production environment');
735
}
736
}
737
738
private getSecureApiKey(): string {
739
const apiKey = process.env.STRIPE_SECRET_KEY!;
740
741
// Additional security checks
742
if (apiKey.length < 32) {
743
throw new Error('API key appears to be invalid');
744
}
745
746
return apiKey;
747
}
748
749
private setupSecurityMonitoring(): void {
750
// Monitor for suspicious patterns
751
this.stripe.on('request', (event) => {
752
// Log all API requests for security audit
753
securityLogger.log('stripe_request', {
754
method: event.method,
755
url: event.url,
756
requestId: event.request_id,
757
timestamp: new Date(),
758
userAgent: event.user_agent
759
});
760
});
761
}
762
763
private isTelemetryEnabled(): boolean {
764
return process.env.STRIPE_TELEMETRY !== 'false';
765
}
766
767
private getTimeout(): number {
768
return parseInt(process.env.STRIPE_TIMEOUT || '30000');
769
}
770
771
private getMaxRetries(): number {
772
return parseInt(process.env.STRIPE_MAX_RETRIES || '3');
773
}
774
}
775
776
// Usage
777
const secureConfig = SecureStripeConfig.getInstance();
778
const stripe = secureConfig.getStripe();
779
```
780
781
This comprehensive configuration system provides the foundation for robust, secure, and maintainable Stripe integrations across all environments and use cases.