• Stars
    star
    131
  • Rank 275,867 (Top 6 %)
  • Language
    JavaScript
  • License
    MIT License
  • Created over 8 years ago
  • Updated over 7 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

๐Ÿ’ณ๐Ÿ’ฐ React components for credit card and bank account forms, using material-ui

npm version

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

Component demo

CardForm

Blank CardForm

Invalid CardForm

BankForm

Valid BankForm

Invalid BankForm

PaymentMethods

PaymentMethods

Usage

yarn add react-payment

Since 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, default false
  • getZip: show the zip code input, default false
  • styles: override styles on the elements
  • defaultValues: 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 are name, 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 button
  • showBanks: whether to show the bank list & add button
  • cards: array of cards, in the format { id: '1', last4: '1234', brand: 'visa' }
  • banks: array of banks, in the format { id: '1', last4: '1234' }
  • onAddCard
  • onAddBank
  • onRemoveCard(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 storybook

http://localhost:9001

Deployment

npm version patch
npm publish
npm run deploy-storybook

Credits

More Repositories

1

login-links

Send links that automatically log in the user with OTPs (one-time passwords)
JavaScript
70
star
2

apollo-accounts

Full-stack JS accounts system for Apollo and MongoDB
JavaScript
54
star
3

segmented-control

๐Ÿ’… A good-lookin' segmented control React component
CSS
30
star
4

temporal-time-utils

This is a library with some reusable functions for Temporal.io TypeScript SDK
TypeScript
17
star
5

react-native-periodic

JavaScript
16
star
6

test-meteor-apollo

JavaScript
9
star
7

food-delivery

A resilient, scalable food delivery app built with Temporal and Next.js
TypeScript
6
star
8

roles-restricted

Adds restricted-access state and autologin links to alanning:roles
JavaScript
6
star
9

lorensr.github.io

HTML
4
star
10

backbone-coffee-todos

The Backbone Todos example v0.9.2 in CoffeeScript
CoffeeScript
3
star
11

quick-options

Google Chrome extension for opening extensions' and apps' options pages via the address bar.
3
star
12

ppp

Purchasing power parity calculator
JavaScript
3
star
13

auth0-helpers

Helper functions for auth0-js
JavaScript
2
star
14

distributed-systems

How to build distributed systems in TypeScript
TypeScript
2
star
15

ynm

Java
2
star
16

adapter-rest

REST ToyStore Adapter
Ruby
2
star
17

facebook-emails

CoffeeScript
2
star
18

dragon-fractal

Draws a Heighway dragon fractal curve in Logo.
2
star
19

authentic-brooklyn

JavaScript
1
star
20

resources

lists that people might find useful
Emacs Lisp
1
star
21

replay-demo

Replay a Workflow Execution with the Temporal VS Code extension
TypeScript
1
star
22

test-gha

1
star
23

apollo-starter-kit

Boilerplate for getting off the ground quickly when writing a GraphQL server
JavaScript
1
star
24

hello-world

Basic sample of Temporal TypeScript
JavaScript
1
star