Security News
Node.js EOL Versions CVE Dubbed the "Worst CVE of the Year" by Security Experts
Critics call the Node.js EOL CVE a misuse of the system, sparking debate over CVE standards and the growing noise in vulnerability databases.
react-stripe-elements-universal
Advanced tools
React components for Stripe.js and Stripe Elements (universal)
React components for Stripe.js and Stripe Elements
This project is a thin React wrapper around Stripe.js and Stripe Elements. It allows you to add Elements to any React app, and manages the state and lifecycle of Elements for you.
The Stripe.js / Stripe Elements API reference goes into more detail on the various customization options for Elements (e.g. styles, fonts).
The fastest way to start playing around with react-stripe-elements
is with
this JSFiddle: https://jsfiddle.net/g9rm5qkt/.
You can also play around with the demo locally. The source code is in demo/. To run it:
git clone https://github.com/stripe/react-stripe-elements
cd react-stripe-elements
# (make sure you have yarn installed: https://yarnpkg.com/)
yarn install
yarn run demo
Now go to https://localhost:8080/ to try it out!
react-stripe-elements
.Install with yarn
:
yarn add react-stripe-elements
OR with npm
:
npm install --save react-stripe-elements
OR using UMD build (exports a global ReactStripeElements
object);
<script src="https://unpkg.com/react-stripe-elements@latest/dist/react-stripe-elements.min.js"></script>
<script src="https://js.stripe.com/v3/"></script>
StripeProvider
)In order for your application to have access to the Stripe object,
let's add StripeProvider
to our root React App component:
// index.js
import React from 'react';
import {render} from 'react-dom';
import {StripeProvider} from 'react-stripe-elements';
import MyStoreCheckout from './MyStoreCheckout';
const App = () => {
return (
<StripeProvider apiKey="pk_test_12345">
<MyStoreCheckout />
</StripeProvider>
);
};
render(<App />, document.getElementById('root'));
Elements
)Next, when you're building components for your checkout form, you'll want to wrap the Elements
component around your form
.
This groups the set of Stripe Elements you're using together, so that we're able to pull data from groups of Elements when
you're tokenizing.
// MyStoreCheckout.js
import React from 'react';
import {Elements} from 'react-stripe-elements';
import CheckoutForm from './CheckoutForm';
class MyStoreCheckout extends React.Component {
render() {
return (
<Elements>
<CheckoutForm />
</Elements>
);
}
}
export default MyStoreCheckout;
injectStripe
)Use the injectStripe
Higher-Order Component (HOC) to build your payment
form components in the Elements
tree. The Higher-Order Component
pattern in React can be unfamiliar to those who've never seen it before, so
consider reading up before continuing. The injectStripe
HOC provides the
this.props.stripe
property that manages your Elements
groups. You can call
this.props.stripe.createToken
within a component that has been injected to
submit payment data to Stripe.
:warning: NOTE
injectStripe
cannot be used on the same element that renders theElements
component; it must be used on the child component ofElements
.injectStripe
returns a wrapped component that needs to sit under<Elements>
but above any code where you'd like to accessthis.props.stripe
.
// CheckoutForm.js
import React from 'react';
import {injectStripe} from 'react-stripe-elements';
import AddressSection from './AddressSection';
import CardSection from './CardSection';
class CheckoutForm extends React.Component {
handleSubmit = (ev) => {
// We don't want to let default form submission happen here, which would refresh the page.
ev.preventDefault();
// Within the context of `Elements`, this call to createToken knows which Element to
// tokenize, since there's only one in this group.
this.props.stripe.createToken({name: 'Jenny Rosen'}).then(({token}) => {
console.log('Received Stripe token:', token);
});
// However, this line of code will do the same thing:
// this.props.stripe.createToken({type: 'card', name: 'Jenny Rosen'});
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<AddressSection />
<CardSection />
<button>Confirm order</button>
</form>
);
}
}
export default injectStripe(CheckoutForm);
*Element
componentsNow, you can use individual *Element
components, such as CardElement
, to build your form.
// CardSection.js
import React from 'react';
import {CardElement} from 'react-stripe-elements';
class CardSection extends React.Component {
render() {
return (
<label>
Card details
<CardElement style={{base: {fontSize: '18px'}}} />
</label>
);
}
};
export default CardSection;
PaymentRequestButtonElement
The Payment Request Button lets you collect payment and address information from your customers using Apple Pay and the Payment Request API.
To use the PaymentRequestButtonElement
you need to first create a PaymentRequest
object. You can then conditionally render the PaymentRequestButtonElement
based on the result of paymentRequest.canMakePayment
and pass the PaymentRequest
Object as a prop.
class PaymentRequestForm extends React.Component {
constructor(props) {
super(props);
// For full documentation of the available paymentRequest options, see:
// https://stripe.com/docs/stripe.js#the-payment-request-object
const paymentRequest = props.stripe.paymentRequest({
country: 'US',
currency: 'usd',
total: {
label: 'Demo total',
amount: 1000,
},
});
paymentRequest.on('token', ({complete, token, ...data}) => {
console.log('Received Stripe token: ', token);
console.log('Received customer information: ', data);
complete('success');
});
paymentRequest.canMakePayment().then(result => {
this.setState({canMakePayment: !!result});
});
this.state = {
canMakePayment: false,
paymentRequest,
};
}
render() {
return this.state.canMakePayment ? (
<PaymentRequestButtonElement
paymentRequest={this.state.paymentRequest}
className="PaymentRequestButton"
style={{
// For more details on how to style the Payment Request Button, see:
// https://stripe.com/docs/elements/payment-request-button#styling-the-element
paymentRequestButton: {
theme: 'light',
height: '64px',
},
}}
/>
) : null;
}
}
export default injectStripe(PaymentRequestForm);
<StripeProvider>
All applications using react-stripe-elements
must use the <StripeProvider>
component, which sets up the Stripe context for a component tree.
react-stripe-elements
uses the provider pattern (which is also adopted by tools like react-redux
and react-intl
) to scope a Stripe context to a tree of components. This allows configuration like your API key to be provided at the root of a component tree. This context is then made available to the <Elements>
component and individual <*Element>
components that we provide.
An integration usually wraps the <StripeProvider>
around the application’s root component. This way, your entire application has the configured Stripe context.
This component accepts all options
that can be passed into Stripe(apiKey, options)
as props.
type StripeProviderProps = {
apiKey: string,
};
<Elements>
The Elements
component wraps groups of Elements that belong together. In most cases, you want to wrap this around your checkout form.
This component accepts all options
that can be passed into stripe.elements(options)
as props.
type ElementsProps = {
locale?: string,
fonts?: Array<Object>,
// The full specification for `elements()` options is here: https://stripe.com/docs/elements/reference#elements-options
};
<*Element>
componentsThese components display the UI for Elements, and must be used within StripeProvider
and Elements
.
(More to come!)
CardElement
CardNumberElement
CardExpiryElement
CardCVCElement
PostalCodeElement
PaymentRequestButtonElement
These components accept all options
that can be passed into elements.create(type, options)
as props.
type ElementProps = {
className?: string,
elementRef?: (StripeElement) => void,
// For full documentation on the events and payloads below, see:
// https://stripe.com/docs/elements/reference#element-on
onBlur?: () => void,
onChange?: (changeObject: Object) => void,
onFocus?: () => void,
onReady?: () => void,
};
The props for the PaymentRequestButtonElement
are:
type PaymentRequestButtonProps = {
paymentRequest: StripePaymentRequest,
className?: string,
elementRef?: (StripeElement) => void,
onBlur?: () => void,
onClick?: () => void,
onFocus?: () => void,
onReady?: () => void,
};
injectStripe
HOCfunction injectStripe(
WrappedComponent: ReactClass,
options?: {
withRef?: boolean = false,
}
): ReactClass;
Components that need to initiate Source or Token creations (e.g. a checkout form component) can access stripe.createToken
via props of any component returned by the injectStripe
HOC factory.
If the withRef
option is set to true
, the wrapped component instance will be available with the getWrappedInstance()
method of the wrapper component. This feature can not be used if the wrapped component is a stateless function component.
const StripeCheckoutForm = injectStripe(CheckoutForm);
The following props will be available to this component:
type FactoryProps = {
stripe: {
createToken: (tokenParameters: {type?: string}) => Promise<{token?: Object, error?: Object}>,
// and other functions available on the `stripe` object,
// as officially documented here: https://stripe.com/docs/elements/reference#the-stripe-object
},
};
react-stripe-elements
may not work properly when used with components that implement shouldComponentUpdate
. react-stripe-elements
relies heavily on React's context
feature and shouldComponentUpdate
does not provide a way to take context updates into account when deciding whether to allow a re-render. These components can block context updates from reaching react-stripe-element
components in the tree.
For example, when using react-stripe-elements
together with react-redux
doing the following will not work:
const Component = connect()(injectStripe(_Component));
In this case, the context updates originating from the StripeProvider
are not reaching the components wrapped inside the connect
function. Therefore, react-stripe-elements
components deeper in the tree break. The reason is that the connect
function of react-redux
implements shouldComponentUpdate
and blocks re-renders that are triggered by context changes outside of the connected component.
There are two ways to prevent this issue:
injectStripe
be the outermost one:const Component = injectStripe(connect()(_CardForm));
This works, because injectStripe
does not implement shouldComponentUpdate
itself, so context updates originating from the redux
Provider
will still reach all components.
pure: false
option for redux-connect
:const Component = connect(mapStateToProps, mapDispatchToProps, mergeProps, {
pure: false,
})(injectStripe(_CardForm));
Install dependencies:
yarn install
Run the demo:
yarn run demo
Run the tests:
yarn run test
Build:
yarn run build
We use prettier for code formatting:
yarn run prettier
To update the ToC in the README if any of the headers changed:
yarn run doctoc
Checks:
yarn test
yarn run lint
yarn run flow
FAQs
React components for Stripe.js and Stripe Elements (universal)
The npm package react-stripe-elements-universal receives a total of 17 weekly downloads. As such, react-stripe-elements-universal popularity was classified as not popular.
We found that react-stripe-elements-universal demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Critics call the Node.js EOL CVE a misuse of the system, sparking debate over CVE standards and the growing noise in vulnerability databases.
Security News
cURL and Go security teams are publicly rejecting CVSS as flawed for assessing vulnerabilities and are calling for more accurate, context-aware approaches.
Security News
Bun 1.2 enhances its JavaScript runtime with 90% Node.js compatibility, built-in S3 and Postgres support, HTML Imports, and faster, cloud-first performance.