├── .babelrc
├── .eslintrc.yml
├── .flowconfig
├── .github
├── API_REVIEW.md
├── ISSUE_TEMPLATE.md
└── PULL_REQUEST_TEMPLATE.md
├── .gitignore
├── .prettierignore
├── .prettierrc.yml
├── .travis.yml
├── CHANGELOG.md
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── demo
├── async
│ ├── async.js
│ ├── async.test.js
│ ├── index.html
│ └── main.js
├── demo.png
├── demo
│ ├── index.html
│ └── index.js
└── intents
│ ├── api.js
│ ├── index.html
│ └── index.js
├── package.json
├── src
├── components
│ ├── Element.js
│ ├── Element.test.js
│ ├── Elements.js
│ ├── Elements.test.js
│ ├── PaymentRequestButtonElement.js
│ ├── PaymentRequestButtonElement.test.js
│ ├── Provider.js
│ ├── Provider.test.js
│ ├── inject.js
│ └── inject.test.js
├── decls
│ └── Stripe.js
├── index.js
├── index.test.js
└── utils
│ ├── isEqual.js
│ ├── isEqual.test.js
│ ├── shallowEqual.js
│ └── shallowEqual.test.js
├── test
└── setupJest.js
├── webpack.config.js
├── webpack.config.prod.js
└── yarn.lock
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": ["react", "env"],
3 | "plugins": [
4 | "transform-class-properties",
5 | "transform-object-rest-spread",
6 | [ "transform-es2015-classes", { "loose": true } ],
7 | "transform-inline-environment-variables"
8 | ]
9 | }
10 |
--------------------------------------------------------------------------------
/.eslintrc.yml:
--------------------------------------------------------------------------------
1 | ---
2 | extends:
3 | - stripe
4 | - plugin:flowtype/recommended
5 | # overwrite any rules that may conflict with prettier
6 | - "prettier"
7 | - "prettier/flowtype"
8 | - "prettier/react"
9 | parser: 'babel-eslint'
10 | plugins:
11 | - flowtype
12 | - jest
13 | env:
14 | jest/globals: true
15 | rules:
16 | react/jsx-filename-extension: 0
17 | no-duplicate-imports: 2 # doesn't support flow imports.
18 | no-console: 0
19 | func-style: 2
20 | consistent-return: 2
21 | prefer-arrow-callback:
22 | - 2
23 | - allowNamedFunctions: false
24 | allowUnboundThis: false
25 | flowtype/no-primitive-constructor-types: 2
26 | flowtype/require-valid-file-annotation:
27 | - 2
28 | - 'always'
29 | - annotationStyle: 'line'
30 | no-unused-vars:
31 | - 2
32 | - ignoreRestSiblings: true
33 | jest/no-disabled-tests: 2
34 | jest/no-focused-tests: 2
35 |
--------------------------------------------------------------------------------
/.flowconfig:
--------------------------------------------------------------------------------
1 | [libs]
2 | src/decls/
3 |
--------------------------------------------------------------------------------
/.github/API_REVIEW.md:
--------------------------------------------------------------------------------
1 | # API Review
2 |
3 | All API changes should go through API review, in addition to our normal code
4 | review process. We define an API change as
5 |
6 | - a change large enough to warrant updating documentation, or
7 | - a change that increases the maintenance burden of features we offer to our
8 | users (i.e., the "API surface area")
9 |
10 | For small changes, some or all of these changes can be omitted, but it's best to
11 | **err on the side of being thorough**. Especially for large changes, you might
12 | even consider drafting a full-fledged design document.
13 |
14 | It's best to go through an API review **before** you start changing the code, so
15 | that we can offer guidance on how to proceed before getting too caught in the
16 | weeds.
17 |
18 | ## Template
19 |
20 | Copy/paste this template into a new issue and fill it in to request an API
21 | review from a maintainer. Remember: depending on the size of your change, it's
22 | possible to omit some of the sections below.
23 |
24 | ```md
25 | #### Summary
26 |
27 | > A brief of the new API, including a code sample. Consider where this feature
28 | > would fit into our documentation, and what the updated documentation would
29 | > look like.
30 |
31 |
32 |
33 | #### Motivation
34 |
35 | > Describe the problem you are trying to solve with this API change. What does
36 | > this API enable that was previously not possible?
37 |
38 |
39 |
40 | #### Similar APIs
41 |
42 | > Is this new API similar to an existing Stripe API? Are there similar APIs or
43 | > prior art in other popular projects?
44 |
45 |
46 |
47 | #### Alternatives
48 |
49 | > How else could we implement this feature? Are there any existing workarounds
50 | > that would offer the same functionality? Why should we chose this
51 | > implementation over another?
52 |
53 |
54 |
55 | #### Scope
56 |
57 | > Which interfaces will this apply to? For example, is this specific to one
58 | > component, or does it affect all Element components? Does this set a precedent
59 | > for future interfaces we'll add?
60 |
61 |
62 |
63 | #### Risks
64 |
65 | > Are there any security implications (for example, XSS)? What are some ways
66 | > users might get confused or misuse this feature?
67 |
68 |
69 | ```
70 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | Feature request or idea? Consider opening an
2 | [API review](https://github.com/stripe/react-stripe-elements/tree/master/.github/API_REVIEW.md)!
3 |
4 |
14 |
15 | ### Summary
16 |
17 |
18 |
19 | ### Other information
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/.github/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | ### Summary & motivation
2 |
3 |
4 |
5 | ### API review
6 |
7 |
8 |
9 | Copy [this template] **or** link to an API review issue.
10 |
11 | [this template]:
12 | https://github.com/stripe/react-stripe-elements/tree/master/.github/API_REVIEW.md
13 |
14 | ### Testing & documentation
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | dist
4 | es
5 | lib
6 | *.log
7 |
--------------------------------------------------------------------------------
/.prettierignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | dist
3 | es
4 | lib
5 | package.json
6 |
--------------------------------------------------------------------------------
/.prettierrc.yml:
--------------------------------------------------------------------------------
1 | singleQuote: true
2 | trailingComma: es5
3 | bracketSpacing: false
4 | arrowParens: always
5 | proseWrap: always
6 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | node_js:
3 | - "8"
4 | script:
5 | - npm run lint
6 | - npm run flow
7 | - npm run test
8 | - npm run prettier-list-different
9 | cache: yarn
10 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 |
3 | `react-stripe-elements` adheres to
4 | [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
5 |
6 | ## v6.1.1 - 2020-04-01
7 |
8 | ### Changes
9 |
10 | - Register package version with Stripe instance (#512)
11 |
12 | ## v6.1.0 - 2020-02-14
13 |
14 | ### New Features
15 |
16 | Added the `auBankAccount` and `fpxBank` elements. These elements will not have
17 | automatic Element detection/insertion. To use them you will need to use
18 | `elements.getElement` and pass them directly to other Stripe.js methods (e.g.
19 | `stripe.confirmFpxPayment`):
20 |
21 | ```jsx
22 | const FpxForm = injectStripe(({stripe, elements}) => {
23 | const handleSubmit = async (event) => {
24 | event.preventDefault();
25 | const {error} = await stripe.confirmFpxPayment('{{CLIENT_SECRET}}', {
26 | payment_method: {
27 | fpx: elements.getElement('fpxBank'),
28 | },
29 | });
30 | };
31 |
32 | return (
33 |
37 | );
38 | });
39 | ```
40 |
41 | ## v6.0.1 - 2019-11-13
42 |
43 | Version bump that fixes some typos, no changes.
44 |
45 | ## v6.0.0 - 2019-11-13
46 |
47 | ### New Features
48 |
49 | - `injectStripe` now injects a reference to the Elements instance created by
50 | `` as the prop `elements`.
51 |
52 | The primary reason you would want an Elements instance is to use
53 | [`elements.getElement()`](https://stripe.com/docs/stripe-js/reference#elements-get-element).
54 | which provides an easy way to get a reference to an Element. You will need to
55 | get a reference to an Element to use
56 | [`confirmCardPayment`](https://stripe.com/docs/stripe-js/reference#stripe-confirm-card-payment),
57 | [`confirmCardSetup()`](https://stripe.com/docs/stripe-js/reference#stripe-confirm-card-setup),
58 | or
59 | [`createPaymentMethod()`](https://stripe.com/docs/stripe-js/reference#stripe-create-payment-method).
60 |
61 | Note that the old API for `createPaymentMethod` will continue to work and
62 | provide automatic element injection, but we are updating documentation and
63 | examples to use the new argument shape:
64 |
65 | ```js
66 | // old shape with automatic element detection - still works
67 | this.props.stripe.createPaymentMethod('card').then(/* ... */);
68 |
69 | // new shape without automatic element detection - recommended and will work with new non-card PaymentMethods
70 | this.props.stripe
71 | .createPaymentMethod({
72 | type: 'card',
73 | card: this.props.elements.getElement('card'),
74 | })
75 | .then(/* ... */);
76 | ```
77 |
78 | ### Breaking Changes
79 |
80 | - We have removed the `getElement` method on RSE components that we introduced
81 | in v5.1.0 in favor of the above change. Sorry for the churn.
82 |
83 | ## v5.1.0 - 2019-10-22
84 |
85 | ### New Features
86 |
87 | - Add support for accessing the underlying Element using refs via `getElement`.
88 |
89 | ### Bug Fixes
90 |
91 | - Fix crash when trying to create element while unmounting. Thanks @CarsonF!
92 |
93 | ## v5.0.1 - 2019-09-18
94 |
95 | ### Bug Fixes
96 |
97 | - Fixes a bug where calling `stripe.createPaymentMethod` would error in IE.
98 |
99 | ## v5.0.0 - 2019-08-27
100 |
101 | ### New Features
102 |
103 | - React 16.9 compatibility.
104 |
105 | ### Breaking Changes
106 |
107 | - We replaced the internal use of deprecated `componentWillReceiveProps`. This
108 | internal movement of logic between lifecycle methods is likely safe for almost
109 | all apps and should not require any changes.
110 |
111 | ## v4.0.1 - 2019-08-14
112 |
113 | ### Bug Fixes
114 |
115 | - Fixes a bug where calling `stripe.handleCardPayment` with only a client secret
116 | caused an error to be thrown.
117 |
118 | ## v4.0.0 - 2019-07-05
119 |
120 | ### New Features
121 |
122 | - Renamed `CardCVCElement` to `CardCvcElement` which better mirrors the Elements
123 | API. We will keep the old component name around as an alias until 5.0.0.
124 | - Added support for `stripe.handleCardSetup`
125 |
126 | ```js
127 | stripe.handleCardSetup(
128 | clientSecret: string,
129 | data?: Object
130 | ): Promise<{error?: Object, setupIntent?: Object}>
131 | ```
132 |
133 | For more information, please review the Stripe Docs:
134 |
135 | - [`stripe.handleCardSetup`](https://stripe.com/docs/stripe-js/reference#stripe-handle-card-setup)
136 |
137 | ### Deprecations
138 |
139 | - `CardCVCElement` has been renamed to `CardCvcElement`. `CardCVCElement` will
140 | be removed in version 5.0.0.
141 |
142 | ### Breaking Changes
143 |
144 | - If you were already using `handleCardSetup` with `react-stripe-elements`, you
145 | should upgrade your integration. This method will now automatically find and
146 | use valid Elements.
147 |
148 | #### Old Way
149 |
150 | ```js
151 |
155 |
156 | handleReady = (element) => {
157 | this.setState({cardElement: element}) ;
158 | };
159 |
160 | const {setupIntent, error} = await this.props.stripe.handleCardSetup(
161 | intent.client_secret, this.state.cardElement, {}
162 | );
163 | ```
164 |
165 | #### New Way
166 |
167 | ```js
168 | ;
169 |
170 | const {setupIntent, error} = await this.props.stripe.handleCardSetup(
171 | intent.client_secret,
172 | {}
173 | );
174 | ```
175 |
176 | ## v3.0.0 - 2019-04-17
177 |
178 | ### New Features
179 |
180 | - added a [changelog](/CHANGELOG.md)
181 | - added support for `stripe.handleCardPayment` and `stripe.createPaymentMethod`.
182 | These methods allow you to easily integrate Stripe's new Payment Intents API.
183 | Like `createToken` and `createSource`, these new methods will automatically
184 | find and use a corresponding Element when they are called.
185 |
186 | ```js
187 | stripe.createPaymentMethod(
188 | paymentMethodType: string,
189 | paymentMethodDetails: Object
190 | ): Promise<{error?: Object, paymentIntent?: Object}>
191 |
192 | stripe.handleCardPayment(
193 | clientSecret: string,
194 | data?: Object
195 | ): Promise<{error?: Object, paymentIntent?: Object}>
196 | ```
197 |
198 | For more information, please review the Stripe Docs:
199 |
200 | - [`stripe.createPaymentMethod`](https://stripe.com/docs/stripe-js/reference#stripe-create-payment-method)
201 | - [`stripe.handleCardPayment`](https://stripe.com/docs/stripe-js/reference#stripe-handle-card-payment)
202 | - [Payment Intents API](https://stripe.com/docs/payments/payment-intents)
203 | - [Payment Methods API](https://stripe.com/docs/payments/payment-methods)
204 |
205 | ### Breaking Changes:
206 |
207 | - If you were already using `handleCardPayment` or `createPaymentMethod` with
208 | `react-stripe-elements`, you should upgrade your integration. These methods
209 | will now automatically find and use valid Elements.
210 |
211 | #### Old Way
212 |
213 | ```js
214 |
218 |
219 | handleReady = (element) => {
220 | this.setState({cardElement: element}) ;
221 | };
222 |
223 | let { paymentIntent, error } = await this.props.stripe.handleCardPayment(
224 | intent.client_secret, this.state.cardElement, {}
225 | );
226 | ```
227 |
228 | #### New Way
229 |
230 | ```js
231 | ;
232 |
233 | let {paymentIntent, error} = await this.props.stripe.handleCardPayment(
234 | intent.client_secret,
235 | {}
236 | );
237 | ```
238 |
239 | - Passing a beta flag to Stripe.js to use one of the PaymentIntents betas is not
240 | supported.
241 |
242 | #### Old Way
243 |
244 | ```js
245 | const stripe = window.Stripe(
246 | publicKey,
247 | {betas: ['payment_intent_beta_3']},
248 | );
249 |
250 |
251 |
252 |
253 | ```
254 |
255 | #### New Way
256 |
257 | ```js
258 |
259 |
260 |
261 | ```
262 |
263 | - `PostalCodeElement` has been removed. We suggest that you build your own
264 | postal code input.
265 |
266 | ## v2.0.3 - 2019-01-25
267 |
268 | ### Bug Fixes
269 |
270 | - Fixes a bug where the elements.update event was triggered far too often,
271 | incorrectly, when an Element was repeatedly rendered with the same options.
272 |
273 | ## v2.0.1 - 2018-07-11
274 |
275 | ### Bug Fixes
276 |
277 | - The Element higher-order component now reports a proper displayName, which is
278 | more useful for debugging. (Thanks @emilrose!)
279 |
280 | ## v2.0.0 - 2018-06-01
281 |
282 | ### New Features
283 |
284 | - Support for the `IbanElement` and `IdealBankElement`.
285 |
286 | ### Breaking Changes
287 |
288 | - `stripe.createSource` now requires the Source type be passed in.
289 | - For example, if you previously called
290 | `stripe.createSource({ name: 'Jenny Rosen' })`, you now must use
291 | `stripe.createSource({ type: 'card', name: 'Jenny Rosen' })`.
292 | - elementRef is no longer a valid prop you can pass to an ``. Use
293 | onReady instead to get a reference to the underlying Element instance.
294 |
295 | ## v1.7.0 - 2018-05-31
296 |
297 | ### Deprecations
298 |
299 | - `createSource` automatically infers the type of Source to create based on
300 | which Elements are in use. This behavior is now deprecated, and the Source
301 | type will be required in version 2.0.0.
302 |
303 | ## v1.6.0 - 2018-03-05
304 |
305 | ### Deprecations
306 |
307 | - The elementRef callback is deprecated and will be removed in version 2.0.0.
308 | Use onReady instead, which is the exact same.
309 |
310 | ### Bug Fixes
311 |
312 | - The id prop from v1.5.0 was absent from the `PaymentRequestButtonElement`.
313 | Now, the `PaymentRequestButtonElement` behaves like all the other \*Element
314 | components.
315 |
316 | ## v1.5.0 - 2018-03-02
317 |
318 | ### New Features
319 |
320 | - (#177 / #178) The \*Element classes learned a new id prop. This can be used to
321 | set the ID of the underlying DOM Element.
322 |
323 | ## v1.4.1 - 2018-01-22
324 |
325 | ### Bug Fixes
326 |
327 | - Fixed a TODO in an error message emitted by Provider.js.
328 |
329 | ## v1.4.0 - 2018-01-17
330 |
331 | ### Bug Fixes
332 |
333 | - Modify build pipeline to fix issues with IE9 and IE10.
334 |
335 | ## v1.3.2 - 2018-01-11
336 |
337 | ### Bug Fixes
338 |
339 | - Fix split Element token creation for async codepath. (#148)
340 |
341 | ## v1.3.1 - 2018-01-10
342 |
343 | ### Bug Fixes
344 |
345 | - Fixes a regression introduced by v1.3.0 (#146).
346 |
347 | ## v1.3.0 - 2018-01-09
348 |
349 | ### New Features
350 |
351 | - Loading Stripe.js and react-stripe-elements asynchronously
352 | - Rendering react-stripe-elements on the server
353 | - Passing a custom stripe instance to `StripeProvider`
354 | - For an overview of how this works, see the Advanced integrations section.
355 |
356 | ## v1.2.1 - 2017-11-21
357 |
358 | ### Bug Fixes
359 |
360 | - Fixed a bug where using pure components under the `` component would
361 | lead to an error.
362 |
363 | ## v1.2.0 - 2017-10-12
364 |
365 | ### New Features
366 |
367 | - The PaymentRequestButtonElement now accepts an onClick prop that maps to the
368 | `element.on('click')` event.
369 |
370 | ## v1.1.1 - 2017-10-11
371 |
372 | ### Bug Fixes
373 |
374 | - The instance of Stripe provided by StripeProvider is now consistent across
375 | StripeProvider usages across your application, as long as you're passing in
376 | the same API key & configuration.
377 |
378 | ## v1.1.0 - 2017-10-05
379 |
380 | ### New Features
381 |
382 | - We've added a new component! You can now use ``
383 | which wraps up `elements.create('paymentRequestButton')` in a React component.
384 |
385 | ## v1.0.0 - 2017-09-18
386 |
387 | ### New Features
388 |
389 | - Update dependencies
390 | - Improve test coverage
391 | - Allow React 16 as peer dependency
392 |
393 | ## v0.1.0 - 2017-09-13
394 |
395 | ### New Features
396 |
397 | - You can now pass the `withRef` option to `injectStripe` to make the wrapped
398 | component instance available via `getWrappedInstance()`
399 |
400 | ## v0.0.8 - 2017-08-21
401 |
402 | ### New Features
403 |
404 | - Render \*Element components with div instead of span (#61)
405 |
406 | ## v0.0.7 - 2018-08-03
407 |
408 | ### New Features
409 |
410 | - You can now pass `className` to `<*Element>` (e.g.
411 | and it will be passed down to the element
412 | container DOM element.
413 |
414 | ## v0.0.6 - 2017-07-25
415 |
416 | ### Bug Fixes
417 |
418 | - Bugfix for collapsed Elements: #45 #48
419 |
420 | ## v0.0.5 - 2017-07-20
421 |
422 | ### Bug Fixes
423 |
424 | - Same as v0.0.3 but fixed corrupted npm upload.
425 |
426 | ## v0.0.3 - 2017-07-20
427 |
428 | ### Bug Fixes
429 |
430 | - Bug fixes for: #29, #40
431 |
432 | ## v0.0.2 - 05-04-2017
433 |
434 | ### New Features
435 |
436 | Initial release! Support for:
437 |
438 | - StripeProvider
439 | - Elements
440 | - injectStripe
441 | - Individual elements:
442 | - CardElement
443 | - CardNumberElement
444 | - CardExpiryElement
445 | - CardCVCElement
446 | - PostalCodeElement
447 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing to `react-stripe-elements`
2 |
3 | Thanks for contributing to react-stripe-elements!
4 |
5 | ## Issues
6 |
7 | `react-stripe-elements` is a thin wrapper around [Stripe.js] and [Stripe
8 | Elements][elements] for React. Please only file issues here that you believe
9 | represent bugs with react-stripe-elements, not Stripe.js itself.
10 |
11 | If you're having general trouble with Stripe.js or your Stripe integration,
12 | please reach out to us using the form at or
13 | come chat with us at #stripe on freenode. We're very proud of our level of
14 | service, and we're more than happy to help you out with your integration.
15 |
16 | If you've found a bug in `react-stripe-elements`, please [let us know][issue]!
17 | You may also want to check out our [issue template][issue-template].
18 |
19 | ## API review
20 |
21 | At Stripe, we scrutinize changes that affect the developer API more so than
22 | implementation changes. If your code change involves adding, removing, or
23 | modifying the surface area of the API, we ask that you go through an API review
24 | by following [this guide][api-review]. It's best to go through API review before
25 | implementing a feature. If you've already implemented a feature, address the
26 | [API review][api-review] considerations within your pull request.
27 |
28 | Going through an API review is not required, but it helps us to understand the
29 | problem you are trying to solve, and enables us to collaborate and solve it
30 | together.
31 |
32 | ## Code review
33 |
34 | All pull requests will be reviewed by someone from Stripe before merging. At
35 | Stripe, we believe that code review is for explaining and having a discussion
36 | around code. For those new to code review, we strongly recommend [this
37 | video][code-review] on "code review culture."
38 |
39 | ## Developing
40 |
41 | We use a number of automated checks:
42 |
43 | - Flow, for adding types to JavaScript
44 | - `yarn run flow`
45 | - Jest, for testing
46 | - `yarn test`
47 | - ESLint, for assorted warnings
48 | - `yarn run lint`
49 | - Prettier, for code formatting
50 | - `yarn run prettier`
51 |
52 | You might want to configure your editor to automatically run these checks. Not
53 | passing any of these checks will cause the CI build to fail.
54 |
55 | [code-review]: https://www.youtube.com/watch?v=PJjmw9TRB7s
56 | [api-review]: .github/API_REVIEW.md
57 | [stripe.js]: https://stripe.com/docs/stripe.js
58 | [elements]: https://stripe.com/elements
59 | [issue]: https://github.com/stripe/react-stripe-elements/issues/new
60 | [issue-template]: .github/ISSUE_TEMPLATE.md
61 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 Stripe
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ## We’ve moved to [@stripe/react-stripe-js](https://github.com/stripe/react-stripe-js)!
2 |
3 | We have decided to rename, rework, and move this project. We have no plans for
4 | any additional major releases of `react-stripe-elements`. If you have an issue with this package, please open it on the [react-stripe-js repo](https://github.com/stripe/react-stripe-js).
5 |
6 | If you are starting a new Stripe integration or are looking to update your
7 | existing 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 | [](https://travis-ci.org/stripe/react-stripe-elements)
18 | [](https://www.npmjs.com/package/react-stripe-elements)
19 |
20 | > React components for Stripe.js and Stripe Elements
21 |
22 | This 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
25 | Elements to any React app, and manages the state and lifecycle of Elements for
26 | you.
27 |
28 | The
29 | [Stripe.js / Stripe Elements API reference](https://stripe.com/docs/elements/reference)
30 | goes into more detail on the various customization options for Elements (e.g.
31 | styles, fonts).
32 |
33 |
34 |
35 |
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)
54 | - [Props shape](#props-shape)
55 | - [``](#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 |
67 |
68 |
69 | ## Demo
70 |
71 | The fastest way to start playing around with `react-stripe-elements` is with
72 | this JSFiddle: .
73 |
74 | You can also play around with the demo locally. The source code is in
75 | [demo/](demo/). To run it:
76 |
77 | ```shell
78 | git clone https://github.com/stripe/react-stripe-elements
79 | cd react-stripe-elements
80 |
81 | # (make sure you have yarn installed: https://yarnpkg.com/)
82 |
83 | yarn install
84 | yarn run demo
85 | ```
86 |
87 | Now go to 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 | 
94 |
95 | ## Installation
96 |
97 | ### First, install `react-stripe-elements`.
98 |
99 | Install with `yarn`:
100 |
101 | ```
102 | yarn add react-stripe-elements
103 | ```
104 |
105 | OR with `npm`:
106 |
107 | ```
108 | npm install --save react-stripe-elements
109 | ```
110 |
111 | OR using UMD build (exports a global `ReactStripeElements` object);
112 |
113 | ```html
114 |
115 | ```
116 |
117 | ### Then, load Stripe.js in your application:
118 |
119 | ```html
120 |
121 | ```
122 |
123 | ## Getting started
124 |
125 | ### The Stripe context (`StripeProvider`)
126 |
127 | In order for your application to have access to
128 | [the Stripe object](https://stripe.com/docs/elements/reference#the-stripe-object),
129 | let's add `StripeProvider` to our root React App component:
130 |
131 | ```jsx
132 | // index.js
133 | import React from 'react';
134 | import {render} from 'react-dom';
135 | import {StripeProvider} from 'react-stripe-elements';
136 |
137 | import MyStoreCheckout from './MyStoreCheckout';
138 |
139 | const App = () => {
140 | return (
141 |
142 |
143 |
144 | );
145 | };
146 |
147 | render(, document.getElementById('root'));
148 | ```
149 |
150 | ### Element groups (`Elements`)
151 |
152 | Next, when you're building components for your checkout form, you'll want to
153 | wrap the `Elements` component around your `form`. This groups the set of Stripe
154 | Elements you're using together, so that we're able to pull data from groups of
155 | Elements when you're tokenizing.
156 |
157 | ```jsx
158 | // MyStoreCheckout.js
159 | import React from 'react';
160 | import {Elements} from 'react-stripe-elements';
161 |
162 | import InjectedCheckoutForm from './CheckoutForm';
163 |
164 | class MyStoreCheckout extends React.Component {
165 | render() {
166 | return (
167 |
168 |
169 |
170 | );
171 | }
172 | }
173 |
174 | export default MyStoreCheckout;
175 | ```
176 |
177 | ### Setting up your payment form (`injectStripe`)
178 |
179 | Use the `injectStripe` [Higher-Order Component][hoc] (HOC) to build your payment
180 | form components in the `Elements` tree. The [Higher-Order Component][hoc]
181 | pattern in React can be unfamiliar to those who've never seen it before, so
182 | consider 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
185 | on 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 `` but above any code where you'd like to access
195 | > `this.props.stripe`.
196 |
197 | ```jsx
198 | // CheckoutForm.js
199 | import React from 'react';
200 | import {injectStripe} from 'react-stripe-elements';
201 |
202 | import AddressSection from './AddressSection';
203 | import CardSection from './CardSection';
204 |
205 | class 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 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 |
278 | );
279 | }
280 | }
281 |
282 | export default injectStripe(CheckoutForm);
283 | ```
284 |
285 | ### Using individual `*Element` components
286 |
287 | Now, you can use individual `*Element` components, such as `CardElement`, to
288 | build your form.
289 |
290 | ```jsx
291 | // CardSection.js
292 | import React from 'react';
293 | import {CardElement} from 'react-stripe-elements';
294 |
295 | class CardSection extends React.Component {
296 | render() {
297 | return (
298 |
302 | );
303 | }
304 | }
305 |
306 | export default CardSection;
307 | ```
308 |
309 | ### Using the `PaymentRequestButtonElement`
310 |
311 | The
312 | [Payment Request Button](https://stripe.com/docs/elements/payment-request-button)
313 | lets you collect payment and address information from your customers using Apple
314 | Pay and the Payment Request API.
315 |
316 | To use the `PaymentRequestButtonElement` you need to first create a
317 | [`PaymentRequest` object](https://stripe.com/docs/stripe.js#the-payment-request-object).
318 | You can then conditionally render the `PaymentRequestButtonElement` based on the
319 | result of `paymentRequest.canMakePayment` and pass the `PaymentRequest` Object
320 | as a prop.
321 |
322 | ```jsx
323 | class 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 |
368 | ) : null;
369 | }
370 | }
371 | export default injectStripe(PaymentRequestForm);
372 | ```
373 |
374 | ## Advanced integrations
375 |
376 | The above [Getting started](#getting-started) section outlines the most common
377 | integration, 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 |
384 | When all of these assumptions are true, you can pass the `apiKey` prop to
385 | `` and let `react-stripe-elements` handle the rest.
386 |
387 | When one or more of these assumptions doesn't hold true for your integration,
388 | you have another option: pass a Stripe instance as the `stripe` prop to
389 | `` directly. The `stripe` prop can be either `null` or the
390 | result of using `Stripe(apiKey, options)` to construct a [Stripe instance].
391 |
392 | [stripe-function]: https://stripe.com/docs/stripe-js/reference#stripe-function
393 |
394 | We'll now cover a couple of use cases which break at least one of the
395 | assumptions listed above.
396 |
397 | ### Loading Stripe.js asynchronously
398 |
399 | Loading Stripe.js asynchronously can speed up your initial page load, especially
400 | if you don't show the payment form until the user interacts with your
401 | application in some way.
402 |
403 | ```html
404 |
405 |
406 |
407 |
408 |
409 |
410 |
411 |
412 |
413 |
414 |
415 |
416 | ```
417 |
418 | Initialize `this.state.stripe` to `null` in the `constructor`, then update it in
419 | `componentDidMount` when the script tag has loaded.
420 |
421 | ```jsx
422 | class 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 |
442 |
443 |
444 |
445 |
446 | );
447 | }
448 | }
449 | ```
450 |
451 | When loading Stripe.js asynchronously, the `stripe` prop provided by
452 | `injectStripe` will initially be `null`, and will update to the Stripe instance
453 | once you pass it in to your `StripeProvider`. You can find a working demo of
454 | this strategy in [async.js](demo/async/async.js). If you run the demo locally,
455 | you can view it at .
456 |
457 | For alternatives to calling `setState`in `componentDidMount`, consider using a
458 | `setTimeout()`, moving the `if/else` statement to the `constructor`, or
459 | dynamically injecting a script tag in `componentDidMount`. For more information,
460 | see [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 |
466 | If 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 |
470 | The general idea is similar to the async loading snippet from the previous
471 | section (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
473 | load in `componentDidMount`; we can use `window.Stripe` directly.
474 |
475 | ```jsx
476 | class 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 |
489 |
490 |
491 |
492 |
493 | );
494 | }
495 | }
496 | ```
497 |
498 | Inside your form, ``, `this.props.stripe` will either be
499 | `null` or a valid Stripe instance. This means that it will be `null` when
500 | rendered server-side, but set when rendered in a browser.
501 |
502 | ### Using an existing Stripe instance
503 |
504 | In some projects, part of the project uses React, while another part doesn't.
505 | For example, maybe you have business logic and view logic separate. Or maybe you
506 | use `react-stripe-elements` for your credit card form, but use Stripe.js APIs
507 | directly for tokenizing bank account information.
508 |
509 | You can use the `stripe` prop to get more fine-grained control over the Stripe
510 | instance that `` uses. For example, if you have a `stripe`
511 | instance in a Redux store that you pass to your `` as a prop, you can
512 | pass that instance directly into ``:
513 |
514 | ```jsx
515 | class App extends React.Component {
516 | render() {
517 | return (
518 |
519 |
520 |
521 |
522 |
523 | );
524 | }
525 | }
526 | ```
527 |
528 | As long as `` is provided a non-`null` `stripe` prop, `this.props.stripe`
529 | will always be available within your `InjectedCheckoutForm`.
530 |
531 | ## Component reference
532 |
533 | ### ``
534 |
535 | All applications using `react-stripe-elements` must use the ``
536 | component, which sets up the Stripe context for a component tree.
537 | `react-stripe-elements` uses the provider pattern (which is also adopted by
538 | tools like [`react-redux`](https://github.com/reactjs/react-redux) and
539 | [`react-intl`](https://github.com/yahoo/react-intl)) to scope a Stripe context
540 | to a tree of components.
541 |
542 | This allows configuration like your API key to be provided at the root of a
543 | component tree. This context is then made available to the ``
544 | component and individual `<*Element>` components that we provide.
545 |
546 | An integration usually wraps the `` around the application’s
547 | root component. This way, your entire application has the configured Stripe
548 | context.
549 |
550 | #### Props shape
551 |
552 | There are two _distinct_ props shapes you can pass to ``.
553 |
554 | ```jsx
555 | type StripeProviderProps =
556 | | {apiKey: string, ...}
557 | | {stripe: StripeObject | null};
558 | ```
559 |
560 | See [Advanced integrations](#advanced-integrations) for more information on when
561 | to use each.
562 |
563 | The `...` above represents that this component accepts props for any option that
564 | can 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
566 | connected account, you can pass `stripeAccount="acct_123"` as a property to
567 | ``. This will get used just like passing `stripeAccount` in the
568 | options of the `Stripe` constructor or like using `stripe_account` when your
569 | backend calls the Stripe API directly
570 |
571 | ### ``
572 |
573 | The `Elements` component wraps groups of Elements that belong together. In most
574 | cases, you want to wrap this around your checkout form.
575 |
576 | #### Props shape
577 |
578 | This component accepts all `options` that can be passed into
579 | `stripe.elements(options)` as props.
580 |
581 | ```jsx
582 | type ElementsProps = {
583 | locale?: string,
584 | fonts?: Array