stack-pay-hosted-payments-react
v0.1.3
Published
Provides input fields for a custom credit card payment form
Downloads
20
Maintainers
Readme
Stack Pay Hosted Payments React
Quick scaffolding of credit card input fields for React
Install
npm install --save stack-pay-hosted-payments-react
Usage
Create a component under
src/components
called PaymentForm.js and add the code below to it
This code includes the creation of a service called the StackPayService.js, created under
src/services
. The sample code for that is below.
import React, { Component } from 'react';
import ReactDom, { render } from 'react-dom';
import Card from 'stack-pay-hosted-payments-react';
// import SupportedCards from './Cards';
import {
formatCreditCardNumber,
formatCVC,
formatExpirationDate,
formatFormData
} from '../../utils';
import './styles.css';
import api from '../../services/StackPayService';
export default class PaymentForm extends Component {
constructor(props) {
super(props);
this.state = {
number: '',
name: '',
expiry: '',
cvc: '',
issuer: '',
focused: '',
formData: null,
paymentToken: '',
error: null,
processing: true,
complete: false
};
}
handleCallback = ({ issuer }, isValid) => {
if (isValid) {
this.setState({ issuer });
}
};
handleInputFocus = ({ target }) => {
this.setState({
focused: target.name
});
};
handleInputChange = ({ target }) => {
if (target.name === 'number') {
target.value = formatCreditCardNumber(target.value);
} else if (target.name === 'expiry') {
target.value = formatExpirationDate(target.value);
} else if (target.name === 'cvc') {
target.value = formatCVC(target.value);
}
this.setState({ [target.name]: target.value });
};
handleSubmit = e => {
e.preventDefault();
const { issuer } = this.state;
const formData = [...e.target.elements]
.filter(d => d.name)
.reduce((acc, d) => {
acc[d.name] = d.value;
return acc;
}, {});
this.setState({ formData, issuer });
api
.returnPaymentMethodToken(this.state)
.then(payload => {
console.log('Payment Method Payload: ', payload);
this.setState({
paymentToken: payload.token,
error: null,
processing: false,
complete: true
});
})
.catch(error => {
console.log('Payment Method Error: ', error);
this.setState({
stackPayError: `Failed to create paymentMethod Token: ${error.message}`,
processing: false
});
});
this.form.reset();
};
render() {
const { name, number, expiry, cvc, focused, issuer, formData } = this.state;
return (
<div key="Payment">
<div className="App-payment">
<h1>Stack Pay Hosted Payment</h1>
<h4>Pay securely here</h4>
<Card
number={number}
name={name}
expiry={expiry}
cvc={cvc}
focused={focused}
issuer={issuer}
callback={this.handleCallback}
/>
<form ref={c => (this.form = c)} onSubmit={this.handleSubmit}>
<hr className="color-grey" />
<div className="form-group">
<input
type="tel"
name="number"
className="form-control"
placeholder="Card Number"
pattern="[\d| ]{16,22}"
required
onChange={this.handleInputChange}
onFocus={this.handleInputFocus}
/>
<small className="card-body">4242 4242 4242 4242 4242</small>
</div>
<div className="form-group">
<input
type="text"
name="name"
className="form-control"
placeholder="Name"
required
onChange={this.handleInputChange}
onFocus={this.handleInputFocus}
/>
</div>
<div className="row">
<div className="col-4">
<input
type="tel"
name="expiry"
className="form-control"
placeholder="Valid Thru"
pattern="\d\d/\d\d"
required
onChange={this.handleInputChange}
onFocus={this.handleInputFocus}
/>
</div>
<div className="col-4">
<input
type="tel"
name="cvc"
className="form-control"
placeholder="CVC"
pattern="\d{3,4}"
required
onChange={this.handleInputChange}
onFocus={this.handleInputFocus}
/>
</div>
<div className="col-4">
<input
type="text"
name="zipcode"
className="form-control"
placeholder="ZIP"
pattern="\d{5,1}"
required
onChange={this.handleInputChange}
onFocus={this.handleInputFocus}
/>
</div>
</div>
<input type="hidden" name="issuer" value={issuer} />
<div className="form-actions">
<button className="btn btn-primary btn-block">PAY</button>
</div>
</form>
{this.state.complete && (
<div className="App-highlight">
{formatFormData(this.state).map((d, i) => (
<div key={i}>{d}</div>
))}
</div>
)}
<hr style={{ margin: '60px 0 30px; color: #f6f6f6f6' }} />
</div>
</div>
);
}
}
Don't forget to import the stack-pay-hosted-payments-react/lib/styles.scss
if you are using SASS in your project.
Or you can import the CSS:import 'stack-pay-hosted-payments-react/es/styles-compiled.css';
Communicating with Stack Pay API ( StackPayService.js)
Create a service in your
src/services directory
import axios from 'axios';
const returnPaymentMethodToken = (options: {}): Promise<string> => {
return axios({
method: 'post',
url: `http://localhost:9080/api/token`,
data: {
Order: {
Account: {
Type: options.issuer,
Number: options.number.replace(/\s+/g, ''),
ExpireDate: options.expiry.replace(/\//g, '')
},
AccountHolder: {
Name: options.name,
BillingAddress: {
Address1: '1234 Payment Method Dr',
City: 'Frisco',
State: 'TX',
Zip: '75034'
}
}
}
},
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
Authorization: 'Bearer sp-api-12345'
}
})
.then(result => ({ token: result.data.Body.Token }))
.catch(error => ({ error: error.error_message }));
};
const api = {
returnPaymentMethodToken
};
export default api;
Important:
In the index.js file you must include these two stylesheets, unless of course you'd prefer to implement your own styling.
import 'bootstrap/dist/css/bootstrap.min.css';
import 'react-credit-cards/es/styles-compiled.css';
Props
name
{string}: Name on card. *number
{string|number}: Card number. *expiry
{string|number}: Card expiry date.10/20
or012017
*cvc
{string|number}: Card CVC/CVV. *focused
{string}: Focused card field.name|number|expiry|cvc
locale
{object}: Localization text (e.g.{ valid: 'valid thru' }
).placeholders
{object}: Placeholder text (e.g.{ name: 'YOUR NAME HERE' }
).preview
{bool}: To use the card to show scrambled data (e.g.**** 4567
).issuer
{string}: Set the issuer for thepreview
mode (e.g.visa|mastercard|...
)acceptedCards
{array}: If you want to limit the accepted cards. (e.g.['visa', 'mastercard']
callback
{func}: A callback function that will be called when the card number has changed with 2 paramaters:type ({ issuer: 'visa', maxLength: 19 }), isValid ({boolean})
* Required fields
SCSS options
Credit Card sizing
$rccs-card-ratio
: Card ratio. Defaults to1.5858
$rccs-size
: Card width. Defaults to290px
Credit Card fonts
$rccs-name-font-size
: Defaults to17px
$rccs-name-font-family
: Defaults toConsolas, Courier, monospace
$rccs-number-font-size
: Defaults to17px
$rccs-number-font-family
: Defaults toConsolas, Courier, monospace
$rccs-valid-font-size
: Defaults to10px
$rccs-expiry-font-size
: Defaults to16px
$rccs-expiry-font-family
: Defaults toConsolas, Courier, monospace
$rccs-cvc-font-size
: Defaults to14px
$rccs-cvc-font-family
: Defaults toConsolas, Courier, monospace
$rccs-cvc-color
: Defaults to#222
Credit Card styling
$rccs-shadow
: Defaults to0 0 20px rgba(#000, 0.2)
$rccs-light-text-color
: Card text color for dark cards. Defaults to#fff
$rccs-dark-text-color
: Card text color for light cards. Defaults to#555
$rccs-stripe-bg-color
: Stripe background color in the back. Defaults to#2a1d16
$rccs-signature-background
: Signature background in the back. Defaults torepeating-linear-gradient(0.1deg, #fff 20%, #fff 40%, #fea 40%, #fea 44%, #fff 44%)
$rccs-default-background
: Default card background. Defaults tolinear-gradient(25deg, #939393, #717171)
$rccs-unknown-background
: Unknown card background. Defaults tolinear-gradient(25deg, #999, #999)
$rccs-background-transition
: Card background transition. Defaults toall 0.5s ease-out
$rccs-animate-background
: Card background animation. Defaults totrue
Credit Card brands
$rccs-amex-background
: Defaults tolinear-gradient(25deg, #308c67, #a3f2cf)
$rccs-dankort-background
: Defaults tolinear-gradient(25deg, #ccc, #999)
$rccs-dinersclub-background
: Defaults tolinear-gradient(25deg, #fff, #eee)
$rccs-discover-background
: Defaults tolinear-gradient(25deg, #fff, #eee)
$rccs-mastercard-background
: Defaults tolinear-gradient(25deg, #e8e9e5, #fbfbfb)
$rccs-visa-background
: Defaults tolinear-gradient(25deg, #0f509e, #1399cd)
$rccs-elo-background
: Defaults tolinear-gradient(25deg, #211c18, #aaa7a2)
$rccs-hipercard-background
: Defaults tolinear-gradient(25deg, #8b181b, #de1f27)
Development
Here's how you can get started developing locally:
$ git clone [email protected]:stack-pay-code-owners/stack-pay-payments-react.git
$ cd stack-pay-payments-react
$ npm install
$ npm start
Now, if you go to http://localhost:3000
in your browser, you should see the demo page.
Contributing
Please read CONTRIBUTING.md for details on our code of conduct, and the process of contributing to the project.
Useful links
EBANK's test numbers
Adyen's test numbers
Worldpay's test card numbers
Brazilian cards patterns
LICENSE
This project is licensed under the MIT License.