React components for payments:
<CardForm>: credit card entry (with validation)<BankForm>: bank account entry (with validation)<PaymentMethods>: list of payment methods (with add / remove buttons)
You can configure/modify some things with props and CSS, and if you need to do any further customization, they're small files—send me a quick PR!
Demo
CardForm
BankForm
PaymentMethods
Usage
yarn add react-paymentSince this library uses Material-UI components, you need to have a Material-UI theme. To get the default style, just wrap this module's components in a <MuiThemeProvider> tag (see the full example).
The alternate syntax for partial imports is react-payment/dist/ComponentName:
import { CardForm } from 'react-payment'; OR import CardForm from 'react-payment/dist/CardForm';CardForm usage
<CardForm> is a credit card form. By default it only has inputs for number, expiration, and CVC.
Props:
onSubmit(card => {})getName: show the name input, defaultfalsegetZip: show the zip code input, defaultfalsestyles: override styles on the elementsdefaultValues: initial input values. Object of the form{ inputName: defaultString }, and the input names are:name, number, expiration, cvc, zip. Expiration is of the format"01/44"for January 2044.
import { CardForm } from 'react-payment'; onSubmit: (card) => { const { number, exp_month, exp_year, cvc, name, zip } = card; Stripe.card.createToken({ number, exp_month, exp_year, cvc, name, address_zip: zip }, (status, response) => { if (response.error) { alert('Adding card failed with error: ' + response.error.message); } else { const cardToken = response.id; // send cardToken to server to be saved under the current user // show success message and navigate away from form } }); } <CardForm onSubmit={this.onSubmit} getName={true} getZip={true} />BankForm usage
<BankForm> is a form for entering US bank account information.
If you would like BankForm to intelligently validate the account & routing number, make sure that Stripe.js is loaded (see the full example below).
Props:
onSubmit(account => {})defaultValues: initial input values. Object of the form{ inputName: defaultString }, and the input names arename, accountNumber, routingNumber.
import BankForm from 'react-payment'; onSubmit(account) { const { name, accountNumber, routingNumber, accountType } = account; const account_holder_type = accountType === 'personal' ? 'individual' : 'company'; Stripe.bankAccount.createToken({ country: 'US', currency: 'USD', routing_number: routingNumber, account_number: accountNumber, account_holder_name: name, account_holder_type }, (status, response) => { if (response.error) { alert('Adding bank account failed with error: ' + response.error.message); } else { const bankAccountToken = response.id; // send bankAccountToken to server to be saved under the current user // show success message and navigate away from form } }); } <BankForm onSubmit={this.onSubmit} />PaymentMethods usage
<PaymentMethods> is a list of your credit cards and/or bank accounts.
Props:
showCards: whether to show the card list & add buttonshowBanks: whether to show the bank list & add buttoncards: array of cards, in the format{ id: '1', last4: '1234', brand: 'visa' }banks: array of banks, in the format{ id: '1', last4: '1234' }onAddCardonAddBankonRemoveCard(id => {})onRemoveBank(id => {})
import { PaymentMethods } from 'react-payment'; <PaymentMethods showCards={true} showBanks={false} cards={[{ id: '1', last4: '1234', brand: 'visa' }]} onAddCard={this.showCardFormDialog} onRemoveCard={this.removeCard} />Full example
import { CardForm, BankForm, PaymentMethods } from 'react-payment'; import React, { Component } from 'react' import Dialog from 'material-ui/Dialog'; import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider'; import server from './server'; let loadedStripe = false; export default class PaymentExample extends Component { state = { dialogOpen: false cardDialog: true }; componentWillMount() { if (loadedStripe) { return; } const script = document.createElement("script"); script.src = "https://js.stripe.com/v2/"; script.type = "text/javascript"; script.async = true; script.onload = () => { Stripe.setPublishableKey('pk_test_6pRNASCoBOKtIshFeQd4XMUh'); }; document.body.appendChild(script); loadedStripe = true; } openDialog = (type) => { this.setState({ dialogOpen: true, cardDialog: type === 'card' ? true : false }); }; closeDialog = () => { this.setState({dialogOpen: false}); }; removeCard = (id) => { server.removeCard(id); }; removeBank = (id) => { server.removeBankAccount(id); }; onSubmitCard = (card) => { const { number, exp_month, exp_year, cvc, name, zip } = card; Stripe.card.createToken({ number, exp_month, exp_year, cvc, name, address_zip: zip }, (status, response) => { if (response.error) { alert('Adding card failed with error: ' + response.error.message) } else { const cardToken = response.id; server.saveCard(cardToken); this.closeDialog(); // show success message } }); }; onSubmitBank = (account) => { const { name, accountNumber, routingNumber, accountType } = account; const account_holder_type = accountType === 'personal' ? 'individual' : 'company'; Stripe.bankAccount.createToken({ country: 'US', currency: 'USD', routing_number: routingNumber, account_number: accountNumber, account_holder_name: name, account_holder_type }, (status, response) => { if (response.error) { alert('Adding bank account failed with error: ' + response.error.message); } else { const bankAccountToken = response.id; server.saveBankAccount(bankAccountToken); this.closeDialog(); // show success message } }) }; render() { const title = this.state.cardDialog ? 'Add credit card' : 'Add bank account'; return ( <MuiThemeProvider> <PaymentMethods showCards={true} showBanks={true} cards={[{ id: '1', last4: '1234', brand: 'visa' }]} banks={[]} onAddCard={() => this.openDialog('card')} onAddBank={() => this.openDialog('bank')} onRemoveCard={this.removeCard} onRemoveBank={this.removeBank} /> <Dialog title={title} modal={false} open={this.state.dialogOpen} onRequestClose={this.closeDialog} > { this.state.cardDialog ? <CardForm onSubmit={this.onSubmitCard} getName={true} getZip={true} /> : <BankForm onSubmit={this.onSubmitBank} /> } </Dialog> </MuiThemeProvider> ); } }Development
git clone [email protected]:lorensr/react-payment.git npm install npm run storybookDeployment
npm version patch npm publishnpm run deploy-storybookCredits
- Contributions by these fine folks
- Segmented control component from
segmented-control




