0
# Card Elements
1
2
Individual card input elements for granular control over payment form layout. These elements provide fine-grained control over card data collection and can be used individually or together to create custom payment forms.
3
4
## Capabilities
5
6
### CardElement
7
8
Complete card input element that collects card number, expiry date, and CVC in a single field.
9
10
```typescript { .api }
11
/**
12
* Complete card input element collecting all card details
13
* @param props - Card element configuration props
14
* @returns JSX element for complete card input
15
*/
16
function CardElement(props: CardElementProps): JSX.Element;
17
18
interface CardElementProps extends ElementProps {
19
/** Configuration options for the Card Element */
20
options?: StripeCardElementOptions;
21
/** Triggered when data exposed by this Element is changed */
22
onChange?: (event: StripeCardElementChangeEvent) => any;
23
/** Triggered when the Element is fully rendered and can accept focus */
24
onReady?: (element: StripeCardElement) => any;
25
/** Triggered when the escape key is pressed within the Element */
26
onEscape?: () => any;
27
/** Triggered when there is a change to the available networks */
28
onNetworksChange?: (event: {elementType: 'card'}) => any;
29
/** Triggered when the Element fails to load */
30
onLoadError?: (event: {elementType: 'card'; error: StripeError}) => any;
31
}
32
33
interface StripeCardElementOptions {
34
/** Appearance and styling options */
35
style?: StripeElementStyle;
36
/** Placeholder text for the card input */
37
placeholder?: string;
38
/** Whether to hide the postal code field */
39
hidePostalCode?: boolean;
40
/** Whether to show the card brand icon */
41
iconStyle?: 'default' | 'solid';
42
/** Disabled state */
43
disabled?: boolean;
44
/** Default values */
45
value?: {
46
postalCode?: string;
47
};
48
}
49
```
50
51
**Usage Examples:**
52
53
```typescript
54
import React, { useState } from 'react';
55
import { CardElement, useStripe, useElements } from '@stripe/react-stripe-js';
56
57
const CardPaymentForm = () => {
58
const stripe = useStripe();
59
const elements = useElements();
60
const [cardComplete, setCardComplete] = useState(false);
61
const [cardError, setCardError] = useState(null);
62
63
const handleCardChange = (event) => {
64
setCardComplete(event.complete);
65
setCardError(event.error ? event.error.message : null);
66
};
67
68
const handleSubmit = async (event) => {
69
event.preventDefault();
70
71
if (!stripe || !elements) return;
72
73
const card = elements.getElement(CardElement);
74
75
const { error, paymentMethod } = await stripe.createPaymentMethod({
76
type: 'card',
77
card: card,
78
billing_details: {
79
name: 'Jenny Rosen',
80
},
81
});
82
83
if (error) {
84
console.log('[error]', error);
85
} else {
86
console.log('[PaymentMethod]', paymentMethod);
87
}
88
};
89
90
return (
91
<form onSubmit={handleSubmit}>
92
<CardElement
93
options={{
94
style: {
95
base: {
96
fontSize: '16px',
97
color: '#424770',
98
'::placeholder': {
99
color: '#aab7c4',
100
},
101
},
102
invalid: {
103
color: '#9e2146',
104
},
105
},
106
hidePostalCode: true
107
}}
108
onChange={handleCardChange}
109
onReady={() => console.log('CardElement ready')}
110
/>
111
{cardError && <div className="card-error">{cardError}</div>}
112
<button disabled={!stripe || !cardComplete}>
113
Pay
114
</button>
115
</form>
116
);
117
};
118
```
119
120
### CardNumberElement
121
122
Card number input element for collecting just the card number.
123
124
```typescript { .api }
125
/**
126
* Card number input element
127
* @param props - Card number element configuration props
128
* @returns JSX element for card number input
129
*/
130
function CardNumberElement(props: CardNumberElementProps): JSX.Element;
131
132
interface CardNumberElementProps extends ElementProps {
133
/** Configuration options for the Card Number Element */
134
options?: StripeCardNumberElementOptions;
135
/** Triggered when data exposed by this Element is changed */
136
onChange?: (event: StripeCardNumberElementChangeEvent) => any;
137
/** Triggered when the Element is fully rendered and can accept focus */
138
onReady?: (element: StripeCardNumberElement) => any;
139
/** Triggered when the escape key is pressed within the Element */
140
onEscape?: () => any;
141
}
142
143
interface StripeCardNumberElementOptions {
144
/** Appearance and styling options */
145
style?: StripeElementStyle;
146
/** Placeholder text for the card number input */
147
placeholder?: string;
148
/** Whether to show the card brand icon */
149
showIcon?: boolean;
150
/** Icon style */
151
iconStyle?: 'default' | 'solid';
152
/** Disabled state */
153
disabled?: boolean;
154
}
155
```
156
157
### CardExpiryElement
158
159
Card expiry date input element for collecting the expiration month and year.
160
161
```typescript { .api }
162
/**
163
* Card expiry date input element
164
* @param props - Card expiry element configuration props
165
* @returns JSX element for card expiry input
166
*/
167
function CardExpiryElement(props: CardExpiryElementProps): JSX.Element;
168
169
interface CardExpiryElementProps extends ElementProps {
170
/** Configuration options for the Card Expiry Element */
171
options?: StripeCardExpiryElementOptions;
172
/** Triggered when data exposed by this Element is changed */
173
onChange?: (event: StripeCardExpiryElementChangeEvent) => any;
174
/** Triggered when the Element is fully rendered and can accept focus */
175
onReady?: (element: StripeCardExpiryElement) => any;
176
/** Triggered when the escape key is pressed within the Element */
177
onEscape?: () => any;
178
}
179
180
interface StripeCardExpiryElementOptions {
181
/** Appearance and styling options */
182
style?: StripeElementStyle;
183
/** Placeholder text for the expiry input */
184
placeholder?: string;
185
/** Disabled state */
186
disabled?: boolean;
187
}
188
```
189
190
### CardCvcElement
191
192
Card CVC/CVV input element for collecting the card verification code.
193
194
```typescript { .api }
195
/**
196
* Card CVC input element
197
* @param props - Card CVC element configuration props
198
* @returns JSX element for card CVC input
199
*/
200
function CardCvcElement(props: CardCvcElementProps): JSX.Element;
201
202
interface CardCvcElementProps extends ElementProps {
203
/** Configuration options for the Card CVC Element */
204
options?: StripeCardCvcElementOptions;
205
/** Triggered when data exposed by this Element is changed */
206
onChange?: (event: StripeCardCvcElementChangeEvent) => any;
207
/** Triggered when the Element is fully rendered and can accept focus */
208
onReady?: (element: StripeCardCvcElement) => any;
209
/** Triggered when the escape key is pressed within the Element */
210
onEscape?: () => any;
211
}
212
213
interface StripeCardCvcElementOptions {
214
/** Appearance and styling options */
215
style?: StripeElementStyle;
216
/** Placeholder text for the CVC input */
217
placeholder?: string;
218
/** Disabled state */
219
disabled?: boolean;
220
}
221
```
222
223
**Multi-Element Usage Example:**
224
225
```typescript
226
import React, { useState } from 'react';
227
import {
228
CardNumberElement,
229
CardExpiryElement,
230
CardCvcElement,
231
useStripe,
232
useElements
233
} from '@stripe/react-stripe-js';
234
235
const SplitCardForm = () => {
236
const stripe = useStripe();
237
const elements = useElements();
238
const [cardState, setCardState] = useState({
239
number: { complete: false, error: null },
240
expiry: { complete: false, error: null },
241
cvc: { complete: false, error: null }
242
});
243
244
const handleCardChange = (field) => (event) => {
245
setCardState(prev => ({
246
...prev,
247
[field]: {
248
complete: event.complete,
249
error: event.error
250
}
251
}));
252
};
253
254
const isFormComplete = Object.values(cardState).every(field => field.complete);
255
256
const handleSubmit = async (event) => {
257
event.preventDefault();
258
259
if (!stripe || !elements) return;
260
261
const cardNumber = elements.getElement(CardNumberElement);
262
263
const { error, paymentMethod } = await stripe.createPaymentMethod({
264
type: 'card',
265
card: cardNumber,
266
});
267
268
if (error) {
269
console.log('Payment failed:', error);
270
} else {
271
console.log('Payment method created:', paymentMethod);
272
}
273
};
274
275
const elementOptions = {
276
style: {
277
base: {
278
fontSize: '18px',
279
color: '#424770',
280
letterSpacing: '0.025em',
281
fontFamily: 'Source Code Pro, monospace',
282
'::placeholder': {
283
color: '#aab7c4',
284
},
285
},
286
invalid: {
287
color: '#9e2146',
288
},
289
},
290
};
291
292
return (
293
<form onSubmit={handleSubmit} className="split-card-form">
294
<div className="card-row">
295
<div className="card-number">
296
<label>Card Number</label>
297
<CardNumberElement
298
options={elementOptions}
299
onChange={handleCardChange('number')}
300
/>
301
{cardState.number.error && (
302
<div className="error">{cardState.number.error.message}</div>
303
)}
304
</div>
305
</div>
306
307
<div className="card-row">
308
<div className="card-expiry">
309
<label>Expiry Date</label>
310
<CardExpiryElement
311
options={elementOptions}
312
onChange={handleCardChange('expiry')}
313
/>
314
{cardState.expiry.error && (
315
<div className="error">{cardState.expiry.error.message}</div>
316
)}
317
</div>
318
319
<div className="card-cvc">
320
<label>CVC</label>
321
<CardCvcElement
322
options={elementOptions}
323
onChange={handleCardChange('cvc')}
324
/>
325
{cardState.cvc.error && (
326
<div className="error">{cardState.cvc.error.message}</div>
327
)}
328
</div>
329
</div>
330
331
<button disabled={!stripe || !isFormComplete}>
332
Pay Now
333
</button>
334
</form>
335
);
336
};
337
```
338
339
## Card Element Event Types
340
341
```typescript { .api }
342
interface StripeCardElementChangeEvent {
343
elementType: 'card' | 'cardNumber' | 'cardExpiry' | 'cardCvc';
344
empty: boolean;
345
complete: boolean;
346
error?: StripeError;
347
value?: {
348
postalCode?: string;
349
};
350
brand?: string;
351
}
352
353
interface StripeCardNumberElementChangeEvent extends StripeCardElementChangeEvent {
354
elementType: 'cardNumber';
355
brand: 'visa' | 'mastercard' | 'amex' | 'discover' | 'diners' | 'jcb' | 'unionpay' | 'unknown';
356
}
357
358
interface StripeCardExpiryElementChangeEvent extends StripeCardElementChangeEvent {
359
elementType: 'cardExpiry';
360
}
361
362
interface StripeCardCvcElementChangeEvent extends StripeCardElementChangeEvent {
363
elementType: 'cardCvc';
364
}
365
```
366
367
## Element Styling
368
369
```typescript { .api }
370
interface StripeElementStyle {
371
base?: StripeElementStyleVariant;
372
complete?: StripeElementStyleVariant;
373
empty?: StripeElementStyleVariant;
374
invalid?: StripeElementStyleVariant;
375
}
376
377
interface StripeElementStyleVariant {
378
color?: string;
379
fontFamily?: string;
380
fontSize?: string;
381
fontSmoothing?: string;
382
fontStyle?: string;
383
fontVariant?: string;
384
fontWeight?: string;
385
iconColor?: string;
386
lineHeight?: string;
387
letterSpacing?: string;
388
textAlign?: string;
389
textDecoration?: string;
390
textShadow?: string;
391
textTransform?: string;
392
'::placeholder'?: {
393
color?: string;
394
fontWeight?: string;
395
};
396
'::selection'?: {
397
backgroundColor?: string;
398
};
399
':-webkit-autofill'?: {
400
color?: string;
401
};
402
':disabled'?: {
403
color?: string;
404
};
405
':focus'?: {
406
color?: string;
407
};
408
':hover'?: {
409
color?: string;
410
};
411
'@media screen and (max-width: 30em)'?: StripeElementStyleVariant;
412
}
413
```