UNPKG

27.9 kBMarkdownView Raw
1## We’ve moved to [@stripe/react-stripe-js](https://github.com/stripe/react-stripe-js)!
2
3We have decided to rename, rework, and move this project. We have no plans for
4any additional major releases of `react-stripe-elements`.
5
6If you are starting a new Stripe integration or are looking to update your
7existing integration, use
8[React Stripe.js](https://github.com/stripe/react-stripe-js).
9
10- [Learn to accept a payment (with React Stripe.js!)](https://stripe.com/docs/payments/accept-a-payment#web)
11- [Migrate from `react-stripe-elements` to React Stripe.js](https://github.com/stripe/react-stripe-js/blob/master/docs/migrating.md)
12
13---
14
15# react-stripe-elements
16
17[![build status](https://img.shields.io/travis/stripe/react-stripe-elements/master.svg?style=flat-square)](https://travis-ci.org/stripe/react-stripe-elements)
18[![npm version](https://img.shields.io/npm/v/react-stripe-elements.svg?style=flat-square)](https://www.npmjs.com/package/react-stripe-elements)
19
20> React components for Stripe.js and Stripe Elements
21
22This project is a thin React wrapper around
23[Stripe.js](https://stripe.com/docs/stripe.js) and
24[Stripe Elements](https://stripe.com/docs/elements). It allows you to add
25Elements to any React app, and manages the state and lifecycle of Elements for
26you.
27
28The
29[Stripe.js / Stripe Elements API reference](https://stripe.com/docs/elements/reference)
30goes into more detail on the various customization options for Elements (e.g.
31styles, fonts).
32
33<!-- prettier-ignore-start -->
34<!-- START doctoc generated TOC please keep comment here to allow auto update -->
35<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
36## Table of Contents
37
38- [Demo](#demo)
39- [Installation](#installation)
40 - [First, install `react-stripe-elements`.](#first-install-react-stripe-elements)
41 - [Then, load Stripe.js in your application:](#then-load-stripejs-in-your-application)
42- [Getting started](#getting-started)
43 - [The Stripe context (`StripeProvider`)](#the-stripe-context-stripeprovider)
44 - [Element groups (`Elements`)](#element-groups-elements)
45 - [Setting up your payment form (`injectStripe`)](#setting-up-your-payment-form-injectstripe)
46 - [Using individual `*Element` components](#using-individual-element-components)
47 - [Using the `PaymentRequestButtonElement`](#using-the-paymentrequestbuttonelement)
48- [Advanced integrations](#advanced-integrations)
49 - [Loading Stripe.js asynchronously](#loading-stripejs-asynchronously)
50 - [Server-side rendering (SSR)](#server-side-rendering-ssr)
51 - [Using an existing Stripe instance](#using-an-existing-stripe-instance)
52- [Component reference](#component-reference)
53 - [`<StripeProvider>`](#stripeprovider)
54 - [Props shape](#props-shape)
55 - [`<Elements>`](#elements)
56 - [Props shape](#props-shape-1)
57 - [`<*Element>` components](#element-components)
58 - [Available components](#available-components)
59 - [Props shape](#props-shape-2)
60 - [Using `onReady`](#using-onready)
61 - [`injectStripe` HOC](#injectstripe-hoc)
62 - [Example](#example)
63- [Troubleshooting](#troubleshooting)
64- [Development](#development)
65
66<!-- END doctoc generated TOC please keep comment here to allow auto update -->
67<!-- prettier-ignore-end -->
68
69## Demo
70
71The fastest way to start playing around with `react-stripe-elements` is with
72this JSFiddle: <https://jsfiddle.net/f5wxprnc/>.
73
74You can also play around with the demo locally. The source code is in
75[demo/](demo/). To run it:
76
77```shell
78git clone https://github.com/stripe/react-stripe-elements
79cd react-stripe-elements
80
81# (make sure you have yarn installed: https://yarnpkg.com/)
82
83yarn install
84yarn run demo
85```
86
87Now go to <http://localhost:8080/> to try it out!
88
89> :warning: `PaymentRequestButtonElement` will not render unless the page is
90> served over HTTPS. To demo `PaymentRequestButtonElement`, you can tunnel over
91> HTTPS to the local server using ngrok or a similar service.
92
93![Screenshot of the demo running](demo/demo.png)
94
95## Installation
96
97### First, install `react-stripe-elements`.
98
99Install with `yarn`:
100
101```
102yarn add react-stripe-elements
103```
104
105OR with `npm`:
106
107```
108npm install --save react-stripe-elements
109```
110
111OR using UMD build (exports a global `ReactStripeElements` object);
112
113```html
114<script src="https://unpkg.com/react-stripe-elements@latest/dist/react-stripe-elements.min.js"></script>
115```
116
117### Then, load Stripe.js in your application:
118
119```html
120<script src="https://js.stripe.com/v3/"></script>
121```
122
123## Getting started
124
125### The Stripe context (`StripeProvider`)
126
127In order for your application to have access to
128[the Stripe object](https://stripe.com/docs/elements/reference#the-stripe-object),
129let's add `StripeProvider` to our root React App component:
130
131```jsx
132// index.js
133import React from 'react';
134import {render} from 'react-dom';
135import {StripeProvider} from 'react-stripe-elements';
136
137import MyStoreCheckout from './MyStoreCheckout';
138
139const App = () => {
140 return (
141 <StripeProvider apiKey="pk_test_12345">
142 <MyStoreCheckout />
143 </StripeProvider>
144 );
145};
146
147render(<App />, document.getElementById('root'));
148```
149
150### Element groups (`Elements`)
151
152Next, when you're building components for your checkout form, you'll want to
153wrap the `Elements` component around your `form`. This groups the set of Stripe
154Elements you're using together, so that we're able to pull data from groups of
155Elements when you're tokenizing.
156
157```jsx
158// MyStoreCheckout.js
159import React from 'react';
160import {Elements} from 'react-stripe-elements';
161
162import InjectedCheckoutForm from './CheckoutForm';
163
164class MyStoreCheckout extends React.Component {
165 render() {
166 return (
167 <Elements>
168 <InjectedCheckoutForm />
169 </Elements>
170 );
171 }
172}
173
174export default MyStoreCheckout;
175```
176
177### Setting up your payment form (`injectStripe`)
178
179Use the `injectStripe` [Higher-Order Component][hoc] (HOC) to build your payment
180form components in the `Elements` tree. The [Higher-Order Component][hoc]
181pattern in React can be unfamiliar to those who've never seen it before, so
182consider reading up before continuing. The `injectStripe` HOC provides the
183`this.props.stripe` and `this.props.elements` properties that manage your
184`Elements` groups. Within an injected component, you can call any of the methods
185on the [Stripe][stripe] or [Elements][elements] objects.
186
187[hoc]: https://facebook.github.io/react/docs/higher-order-components.html
188[stripe]: https://stripe.com/docs/stripe-js/reference#the-stripe-object
189[elements]: https://stripe.com/docs/stripe-js/reference#the-elements-object
190
191> :warning: NOTE `injectStripe` cannot be used on the same element that renders
192> the `Elements` component; it must be used on the child component of
193> `Elements`. `injectStripe` _returns a wrapped component_ that needs to sit
194> under `<Elements>` but above any code where you'd like to access
195> `this.props.stripe`.
196
197```jsx
198// CheckoutForm.js
199import React from 'react';
200import {injectStripe} from 'react-stripe-elements';
201
202import AddressSection from './AddressSection';
203import CardSection from './CardSection';
204
205class CheckoutForm extends React.Component {
206 handleSubmit = (ev) => {
207 // We don't want to let default form submission happen here, which would refresh the page.
208 ev.preventDefault();
209
210 // Use Elements to get a reference to the Card Element mounted somewhere
211 // in your <Elements> tree. Elements will know how to find your Card Element
212 // because only one is allowed.
213 // See our getElement documentation for more:
214 // https://stripe.com/docs/stripe-js/reference#elements-get-element
215 const cardElement = this.props.elements.getElement('card');
216
217 // From here we can call createPaymentMethod to create a PaymentMethod
218 // See our createPaymentMethod documentation for more:
219 // https://stripe.com/docs/stripe-js/reference#stripe-create-payment-method
220 this.props.stripe
221 .createPaymentMethod({
222 type: 'card',
223 card: cardElement,
224 billing_details: {name: 'Jenny Rosen'},
225 })
226 .then(({paymentMethod}) => {
227 console.log('Received Stripe PaymentMethod:', paymentMethod);
228 });
229
230 // You can also use confirmCardPayment with the PaymentIntents API automatic confirmation flow.
231 // See our confirmCardPayment documentation for more:
232 // https://stripe.com/docs/stripe-js/reference#stripe-confirm-card-payment
233 this.props.stripe.confirmCardPayment('{PAYMENT_INTENT_CLIENT_SECRET}', {
234 payment_method: {
235 card: cardElement,
236 },
237 });
238
239 // You can also use confirmCardSetup with the SetupIntents API.
240 // See our confirmCardSetup documentation for more:
241 // https://stripe.com/docs/stripe-js/reference#stripe-confirm-card-setup
242 this.props.stripe.confirmCardSetup('{PAYMENT_INTENT_CLIENT_SECRET}', {
243 payment_method: {
244 card: cardElement,
245 },
246 });
247
248 // You can also use createToken to create tokens.
249 // See our tokens documentation for more:
250 // https://stripe.com/docs/stripe-js/reference#stripe-create-token
251 // With createToken, you will not need to pass in the reference to
252 // the Element. It will be inferred automatically.
253 this.props.stripe.createToken({type: 'card', name: 'Jenny Rosen'});
254 // token type can optionally be inferred if there is only one Element
255 // with which to create tokens
256 // this.props.stripe.createToken({name: 'Jenny Rosen'});
257
258 // You can also use createSource to create Sources.
259 // See our Sources documentation for more:
260 // https://stripe.com/docs/stripe-js/reference#stripe-create-source
261 // With createSource, you will not need to pass in the reference to
262 // the Element. It will be inferred automatically.
263 this.props.stripe.createSource({
264 type: 'card',
265 owner: {
266 name: 'Jenny Rosen',
267 },
268 });
269 };
270
271 render() {
272 return (
273 <form onSubmit={this.handleSubmit}>
274 <AddressSection />
275 <CardSection />
276 <button>Confirm order</button>
277 </form>
278 );
279 }
280}
281
282export default injectStripe(CheckoutForm);
283```
284
285### Using individual `*Element` components
286
287Now, you can use individual `*Element` components, such as `CardElement`, to
288build your form.
289
290```jsx
291// CardSection.js
292import React from 'react';
293import {CardElement} from 'react-stripe-elements';
294
295class CardSection extends React.Component {
296 render() {
297 return (
298 <label>
299 Card details
300 <CardElement style={{base: {fontSize: '18px'}}} />
301 </label>
302 );
303 }
304}
305
306export default CardSection;
307```
308
309### Using the `PaymentRequestButtonElement`
310
311The
312[Payment Request Button](https://stripe.com/docs/elements/payment-request-button)
313lets you collect payment and address information from your customers using Apple
314Pay and the Payment Request API.
315
316To use the `PaymentRequestButtonElement` you need to first create a
317[`PaymentRequest` object](https://stripe.com/docs/stripe.js#the-payment-request-object).
318You can then conditionally render the `PaymentRequestButtonElement` based on the
319result of `paymentRequest.canMakePayment` and pass the `PaymentRequest` Object
320as a prop.
321
322```jsx
323class PaymentRequestForm extends React.Component {
324 constructor(props) {
325 super(props);
326
327 // For full documentation of the available paymentRequest options, see:
328 // https://stripe.com/docs/stripe.js#the-payment-request-object
329 const paymentRequest = props.stripe.paymentRequest({
330 country: 'US',
331 currency: 'usd',
332 total: {
333 label: 'Demo total',
334 amount: 1000,
335 },
336 });
337
338 paymentRequest.on('token', ({complete, token, ...data}) => {
339 console.log('Received Stripe token: ', token);
340 console.log('Received customer information: ', data);
341 complete('success');
342 });
343
344 paymentRequest.canMakePayment().then((result) => {
345 this.setState({canMakePayment: !!result});
346 });
347
348 this.state = {
349 canMakePayment: false,
350 paymentRequest,
351 };
352 }
353
354 render() {
355 return this.state.canMakePayment ? (
356 <PaymentRequestButtonElement
357 paymentRequest={this.state.paymentRequest}
358 className="PaymentRequestButton"
359 style={{
360 // For more details on how to style the Payment Request Button, see:
361 // https://stripe.com/docs/elements/payment-request-button#styling-the-element
362 paymentRequestButton: {
363 theme: 'light',
364 height: '64px',
365 },
366 }}
367 />
368 ) : null;
369 }
370}
371export default injectStripe(PaymentRequestForm);
372```
373
374## Advanced integrations
375
376The above [Getting started](#getting-started) section outlines the most common
377integration, which makes the following assumptions:
378
379- The Stripe.js script is loaded before your application's code.
380- Your code is only run in a browser environment.
381- You don't need fine-grained control over the Stripe instance that
382 `react-stripe-elements` uses under the hood.
383
384When all of these assumptions are true, you can pass the `apiKey` prop to
385`<StripeProvider>` and let `react-stripe-elements` handle the rest.
386
387When one or more of these assumptions doesn't hold true for your integration,
388you have another option: pass a Stripe instance as the `stripe` prop to
389`<StripeProvider>` directly. The `stripe` prop can be either `null` or the
390result of using `Stripe(apiKey, options)` to construct a [Stripe instance].
391
392[stripe-function]: https://stripe.com/docs/stripe-js/reference#stripe-function
393
394We'll now cover a couple of use cases which break at least one of the
395assumptions listed above.
396
397### Loading Stripe.js asynchronously
398
399Loading Stripe.js asynchronously can speed up your initial page load, especially
400if you don't show the payment form until the user interacts with your
401application in some way.
402
403```html
404<html>
405 <head>
406 <!-- ... -->
407
408 <!-- Note the 'id' and 'async' attributes: -->
409 <!-- ┌────────────┐ ┌───┐ -->
410 <script id="stripe-js" src="https://js.stripe.com/v3/" async></script>
411
412 <!-- ... -->
413 </head>
414 <!-- ... -->
415</html>
416```
417
418Initialize `this.state.stripe` to `null` in the `constructor`, then update it in
419`componentDidMount` when the script tag has loaded.
420
421```jsx
422class App extends React.Component {
423 constructor() {
424 super();
425 this.state = {stripe: null};
426 }
427 componentDidMount() {
428 if (window.Stripe) {
429 this.setState({stripe: window.Stripe('pk_test_12345')});
430 } else {
431 document.querySelector('#stripe-js').addEventListener('load', () => {
432 // Create Stripe instance once Stripe.js loads
433 this.setState({stripe: window.Stripe('pk_test_12345')});
434 });
435 }
436 }
437 render() {
438 // this.state.stripe will either be null or a Stripe instance
439 // depending on whether Stripe.js has loaded.
440 return (
441 <StripeProvider stripe={this.state.stripe}>
442 <Elements>
443 <InjectedCheckoutForm />
444 </Elements>
445 </StripeProvider>
446 );
447 }
448}
449```
450
451When loading Stripe.js asynchronously, the `stripe` prop provided by
452`injectStripe` will initially be `null`, and will update to the Stripe instance
453once you pass it in to your `StripeProvider`. You can find a working demo of
454this strategy in [async.js](demo/async/async.js). If you run the demo locally,
455you can view it at <http://localhost:8080/async/>.
456
457For alternatives to calling `setState`in `componentDidMount`, consider using a
458`setTimeout()`, moving the `if/else` statement to the `constructor`, or
459dynamically injecting a script tag in `componentDidMount`. For more information,
460see [stripe/react-stripe-elements][issue-154].
461
462[issue-154]: https://github.com/stripe/react-stripe-elements/issues/154
463
464### Server-side rendering (SSR)
465
466If you're using `react-stripe-elements` in a non-browser environment
467(`React.renderToString`, etc.), Stripe.js is not available. To use
468`react-stripe-elements` with SSR frameworks, use the following instructions.
469
470The general idea is similar to the async loading snippet from the previous
471section (initialize `this.state.stripe` to `null` in `constructor`, update in
472`componentDidMount`), but this time we don't have to wait for the script tag to
473load in `componentDidMount`; we can use `window.Stripe` directly.
474
475```jsx
476class App extends React.Component {
477 constructor() {
478 super();
479 this.state = {stripe: null};
480 }
481 componentDidMount() {
482 // Create Stripe instance in componentDidMount
483 // (componentDidMount only fires in browser/DOM environment)
484 this.setState({stripe: window.Stripe('pk_test_12345')});
485 }
486 render() {
487 return (
488 <StripeProvider stripe={this.state.stripe}>
489 <Elements>
490 <InjectedCheckoutForm />
491 </Elements>
492 </StripeProvider>
493 );
494 }
495}
496```
497
498Inside your form, `<InjectedCheckoutForm />`, `this.props.stripe` will either be
499`null` or a valid Stripe instance. This means that it will be `null` when
500rendered server-side, but set when rendered in a browser.
501
502### Using an existing Stripe instance
503
504In some projects, part of the project uses React, while another part doesn't.
505For example, maybe you have business logic and view logic separate. Or maybe you
506use `react-stripe-elements` for your credit card form, but use Stripe.js APIs
507directly for tokenizing bank account information.
508
509You can use the `stripe` prop to get more fine-grained control over the Stripe
510instance that `<StripeProvider>` uses. For example, if you have a `stripe`
511instance in a Redux store that you pass to your `<App />` as a prop, you can
512pass that instance directly into `<StripeProvider>`:
513
514```jsx
515class App extends React.Component {
516 render() {
517 return (
518 <StripeProvider stripe={this.props.stripe}>
519 <Elements>
520 <InjectedCheckoutForm />
521 </Elements>
522 </StripeProvider>
523 );
524 }
525}
526```
527
528As long as `<App />` is provided a non-`null` `stripe` prop, `this.props.stripe`
529will always be available within your `InjectedCheckoutForm`.
530
531## Component reference
532
533### `<StripeProvider>`
534
535All applications using `react-stripe-elements` must use the `<StripeProvider>`
536component, which sets up the Stripe context for a component tree.
537`react-stripe-elements` uses the provider pattern (which is also adopted by
538tools like [`react-redux`](https://github.com/reactjs/react-redux) and
539[`react-intl`](https://github.com/yahoo/react-intl)) to scope a Stripe context
540to a tree of components.
541
542This allows configuration like your API key to be provided at the root of a
543component tree. This context is then made available to the `<Elements>`
544component and individual `<*Element>` components that we provide.
545
546An integration usually wraps the `<StripeProvider>` around the application’s
547root component. This way, your entire application has the configured Stripe
548context.
549
550#### Props shape
551
552There are two _distinct_ props shapes you can pass to `<StripeProvider>`.
553
554```jsx
555type StripeProviderProps =
556 | {apiKey: string, ...}
557 | {stripe: StripeObject | null};
558```
559
560See [Advanced integrations](#advanced-integrations) for more information on when
561to use each.
562
563The `...` above represents that this component accepts props for any option that
564can be passed into `Stripe(apiKey, options)`. For example, if you are using
565[Stripe Connect](https://stripe.com/connect) and want to act on behalf of a
566connected account, you can pass `stripeAccount="acct_123"` as a property to
567`<StripeProvider>`. This will get used just like passing `stripeAccount` in the
568options of the `Stripe` constructor or like using `stripe_account` when your
569backend calls the Stripe API directly
570
571### `<Elements>`
572
573The `Elements` component wraps groups of Elements that belong together. In most
574cases, you want to wrap this around your checkout form.
575
576#### Props shape
577
578This component accepts all `options` that can be passed into
579`stripe.elements(options)` as props.
580
581```jsx
582type ElementsProps = {
583 locale?: string,
584 fonts?: Array<Object>,
585 // The full specification for `elements()` options is here: https://stripe.com/docs/elements/reference#elements-options
586};
587```
588
589### `<*Element>` components
590
591These components display the UI for Elements, and must be used within
592`StripeProvider` and `Elements`.
593
594#### Available components
595
596(More to come!)
597
598- `CardElement`
599- `CardNumberElement`
600- `CardExpiryElement`
601- `CardCvcElement`
602- `PaymentRequestButtonElement`
603- `IbanElement`
604- `IdealBankElement`
605
606#### Props shape
607
608These components accept all `options` that can be passed into
609`elements.create(type, options)` as props.
610
611```jsx
612type ElementProps = {
613 id?: string,
614 className?: string,
615
616 // For full documentation on the events and payloads below, see:
617 // https://stripe.com/docs/elements/reference#element-on
618 onBlur?: () => void,
619 onChange?: (changeObject: Object) => void,
620 onFocus?: () => void,
621 onReady?: (StripeElement) => void,
622};
623```
624
625The props for the `PaymentRequestButtonElement` are:
626
627```jsx
628type PaymentRequestButtonProps = {
629 id?: string,
630 className?: string,
631
632 paymentRequest: StripePaymentRequest,
633
634 onBlur?: () => void,
635 onClick?: () => void,
636 onFocus?: () => void,
637 onReady?: (StripeElement) => void,
638};
639```
640
641#### Using `onReady`
642
643Note that the `onReady` callback gives you access to the underlying [Element]
644created with Stripe.js. You can use this to get access to all the underlying
645methods that a Stripe Element supports.
646
647For example, you can use `onReady` to force your element to focus:
648
649```jsx
650// CardSection.js
651import React from 'react';
652import {CardElement} from 'react-stripe-elements';
653
654class CardSection extends React.Component {
655 render = () => {
656 return (
657 <label>
658 Card details
659 <CardElement onReady={(el) => el.focus()} />
660 </label>
661 );
662 };
663}
664
665export default CardSection;
666```
667
668(Note that this functionality is new as of react-stripe-elements v1.6.0.)
669
670[element]: https://stripe.com/docs/stripe-js/reference#other-methods
671
672### `injectStripe` HOC
673
674```jsx
675function injectStripe(
676 WrappedComponent: ReactClass,
677 options?: {
678 withRef?: boolean = false,
679 }
680): ReactClass;
681```
682
683Use `injectStripe` to wrap a component that needs to interact with `Stripe.js`
684to create sources or tokens.
685
6861. First, create a component that accepts the `stripe` prop and calls one of
687 the Stripe or Elements methods when necessary.
6882. Wrap that component by passing it to `injectStripe` so that it actually
689 receives the `stripe` and `elements` props.
6903. Render the component that `injectStripe` returns.
691
692#### Example
693
694```jsx
695// 1. Create a component that uses this.props.stripe:
696class CheckoutForm extends React.Component {
697 render() {
698 /* ... */
699 }
700 onCompleteCheckout() {
701 this.props.stripe
702 .createPaymentMethod({
703 type: 'card',
704 card: this.props.stripe.getElement('card'),
705 })
706 .then(/* ... */);
707 }
708}
709
710// 2. Wrap it in a higher-order component that provides the `stripe` prop:
711const InjectedCheckoutForm = injectStripe(CheckoutForm);
712
713// 3. Render the wrapped component in your app:
714const CheckoutRoute = (props) => (
715 <div>
716 <InjectedCheckoutForm />
717 </div>
718);
719```
720
721`injectStripe` will work with any method of providing the actual Stripe instance
722with `StripeProvider`, whether you just give it an api key,
723[load Stripe.js asynchronously](#loading-stripejs-asynchronously), or
724[pass in an existing instance](#using-an-existing-stripe-instance).
725
726Within the context of `Elements`, `stripe.createToken` and `stripe.createSource`
727wrap methods of the same name in
728[Stripe.js](https://stripe.com/docs/stripe-js/reference#stripe-create-Token).
729Calls to them automatically infer and pass the `Element` object as the first
730argument.
731
732If the `withRef` option is set to `true`, the wrapped component instance will be
733available with the `getWrappedInstance()` method of the wrapper component. This
734feature can not be used if the wrapped component is a stateless function
735component.
736
737Within the wrapped component, the `stripe` and `elements` props have the type:
738
739```jsx
740type FactoryProps = {
741 elements: null | {
742 getElement: (type: string) => Element | null,
743 // For more detail and documentation on other methods available on
744 // the `elements` object, please refer to our official documentation:
745 // https://stripe.com/docs/elements/reference#the-elements-object
746 },
747 stripe: null | {
748 createToken: (tokenData: {type?: string}) => Promise<{
749 token?: Object,
750 error?: Object,
751 }>,
752 createSource: (sourceData: {type: string}) => Promise<{
753 source?: Object,
754 error?: Object,
755 }>,
756 createPaymentMethod: (
757 paymentMethodData: Object
758 ) => Promise<{
759 paymentMethod?: Object,
760 error?: Object,
761 }>,
762 confirmCardPayment: (
763 clientSecret: string,
764 paymentIntentData?: Object
765 ) => Promise<{
766 paymentIntent?: Object,
767 error?: Object,
768 }>,
769 confirmCardSetup: (
770 clientSecret: string,
771 paymentIntentData?: Object
772 ) => Promise<{
773 setupIntent?: Object,
774 error?: Object,
775 }>,
776 // For more detail and documentation on other methods available on
777 // the `stripe` object, please refer to our official documentation:
778 // https://stripe.com/docs/elements/reference#the-stripe-object
779 },
780};
781```
782
783The `stripe` and `elements` props can only be `null` if you are using one of the
784[Advanced integrations](#advanced-integrations) mentioned above, like loading
785Stripe.js asynchronously or providing an existing instance. If you are using a
786basic integration where you pass in an api key to `<StripeProvider/>`, they will
787always be present.
788
789## Troubleshooting
790
791`react-stripe-elements` may not work properly when used with components that
792implement `shouldComponentUpdate`. `react-stripe-elements` relies heavily on
793React's `context` feature and `shouldComponentUpdate` does not provide a way to
794take context updates into account when deciding whether to allow a re-render.
795These components can block context updates from reaching `react-stripe-element`
796components in the tree.
797
798For example, when using `react-stripe-elements` together with
799[`react-redux`](https://github.com/reactjs/react-redux) doing the following will
800not work:
801
802```jsx
803const Component = connect()(injectStripe(_Component));
804```
805
806In this case, the context updates originating from the `StripeProvider` are not
807reaching the components wrapped inside the `connect` function. Therefore,
808`react-stripe-elements` components deeper in the tree break. The reason is that
809the `connect` function of `react-redux`
810[implements `shouldComponentUpdate`](https://github.com/reactjs/react-redux/blob/master/docs/troubleshooting.md#my-views-arent-updating-when-something-changes-outside-of-redux)
811and blocks re-renders that are triggered by context changes outside of the
812connected component.
813
814There are two ways to prevent this issue:
815
8161. Change the order of the functions to have `injectStripe` be the outermost
817 one:
818
819 ```jsx
820 const Component = injectStripe(connect()(_CardForm));
821 ```
822
823This works, because `injectStripe` does not implement `shouldComponentUpdate`
824itself, so context updates originating from the `redux` `Provider` will still
825reach all components.
826
8272. You can use the [`pure: false`][pure-false] option for redux-connect:
828
829 ```jsx
830 const Component = connect(
831 mapStateToProps,
832 mapDispatchToProps,
833 mergeProps,
834 {
835 pure: false,
836 }
837 )(injectStripe(_CardForm));
838 ```
839
840[pure-false]:
841 https://github.com/reactjs/react-redux/blob/master/docs/api.md#connectmapstatetoprops-mapdispatchtoprops-mergeprops-options
842
843## Development
844
845Install dependencies:
846
847 yarn install
848
849Run the demo:
850
851 yarn run demo
852
853Run the tests:
854
855 yarn run test
856
857Build:
858
859 yarn run build
860
861We use [prettier](https://github.com/prettier/prettier) for code formatting:
862
863 yarn run prettier
864
865To update the ToC in the README if any of the headers changed:
866
867 yarn run doctoc
868
869Checks:
870
871 yarn test
872 yarn run lint
873 yarn run flow