@rebilly/framepay-react
Version:
A React wrapper for Rebilly's FramePay offering out-of-the-box support for Redux and other common React features
279 lines (267 loc) • 10.5 kB
JavaScript
import React, { Component } from 'react';
import { FramePayProvider, withFramePayCardComponent } from '../../../build';
import {
deepMerge,
prettyDebugRender,
ReactVersion,
renderFixture,
} from './util';
import './style.css';
const params = {
publishableKey: 'pk_sandbox_c6cqKLddciVikuBOjhcng-rLccTz70NT4W_qZ_h',
style: {
base: {
color: 'green',
fontSize: '12px',
webkitFontSmoothing: 'auto',
fontFeatureSettings: 'test',
fontStyle: 'italic',
fontVariant: 'normal',
fontStretch: 'none',
fontSomething: 'not-included',
fontOtherThing: 'not-included',
lineHeight: '20px',
},
invalid: {
fontWeight: 'bold',
},
},
classes: {
base: 'rebilly-framepay',
focus: 'rebilly-framepay-focus',
valid: 'rebilly-framepay-valid',
invalid: 'rebilly-framepay-invalid',
buttons: 'rebilly-framepay-buttons',
webkitAutofill: 'rebilly-framepay-webkit-autofill',
},
icon: {
foobar: 123,
display: true,
color: 'blue',
},
riskMetadata: {
browserData: {
colorDepth: '48',
isJavaEnabled: 'true',
language: 'en',
screenHeight: '100',
screenWidth: '100',
timeZoneOffset: '0',
},
extraData: {
kountFraudSessionId: 'kountFraudSessionId123',
},
fingerprint: 'fingerprint123',
},
};
class CardElementComponent extends Component {
constructor(props) {
super(props);
this.state = {
events: {
onReady: null,
onError: null,
onChange: null,
onFocus: null,
onBlur: null,
},
billingAddress: {
firstName: 'first-name-value',
lastName: 'last-name-value',
address: 'address-value',
country: 'GB',
region: 'region-value',
},
token: {
error: null,
data: null,
},
};
this.handleSubmit = this.handleSubmit.bind(this);
}
handleSubmit(e) {
e.preventDefault();
/**
*
* @see https://www.rebilly.com/docs/dev-docs/framepay-global-reference/#framepay.createtoken
*
*/
const billingAddress = {
...this.state.billingAddress,
};
if (billingAddress.emails) {
billingAddress.emails = [
{
label: 'Email',
value: billingAddress.emails,
},
];
}
if (billingAddress.phoneNumbers) {
billingAddress.phoneNumbers = [
{
label: 'Phone Number',
value: billingAddress.phoneNumbers,
},
];
}
this.props.Framepay.createToken(this.formNode, { billingAddress })
.then((data) => {
this.deepUpdateState({ token: { error: false, data } });
})
.catch((err) => {
this.deepUpdateState({ token: { error: true, data: err } });
});
}
deepUpdateState(data) {
this.setState((prevState) => {
return deepMerge(prevState, data);
});
}
render() {
return (
<div>
<h2>{this.props.title}</h2>
<h3>FramePay version: {this.props.Framepay.version}</h3>
<div className="flex-wrapper">
{prettyDebugRender(this.state)}
<div className="example-2">
<form
id="form"
ref={(node) => (this.formNode = node)}
method="post"
onSubmit={this.handleSubmit}
>
<fieldset>
<div className="field">
<input
type="text"
name="firstName"
placeholder="First Name"
defaultValue={
this.state.billingAddress.firstName
}
onChange={(e) => {
this.deepUpdateState({
billingAddress: {
firstName: e.target.value,
},
});
}}
/>
</div>
<div className="field">
<input
type="text"
name="lastName"
placeholder="Last Name"
defaultValue={
this.state.billingAddress.lastName
}
onChange={(e) => {
this.deepUpdateState({
billingAddress: {
lastName: e.target.value,
},
});
}}
/>
</div>
<div className="field">
<input
type="text"
name="email"
placeholder="Email"
defaultValue={
this.state.billingAddress.emails
}
onChange={(e) => {
this.deepUpdateState({
billingAddress: {
emails: e.target.value,
},
});
}}
/>
</div>
<div className="field">
<input
type="text"
name="phone"
placeholder="Phone"
defaultValue={
this.state.billingAddress
.phoneNumbers
}
onChange={(e) => {
this.deepUpdateState({
billingAddress: {
phoneNumbers:
e.target.value,
},
});
}}
/>
</div>
<div className="field">
<this.props.CardElement
onError={(err) =>
this.deepUpdateState({
events: { onError: err },
})
}
onReady={() =>
this.deepUpdateState({
events: { onReady: true },
})
}
onChange={(data) =>
this.deepUpdateState({
events: { onChange: data },
})
}
onFocus={() =>
this.deepUpdateState({
events: { onFocus: true },
})
}
onBlur={() =>
this.deepUpdateState({
events: { onBlur: true },
})
}
/>
</div>
</fieldset>
<button id="submit">Make Payment</button>
</form>
</div>
</div>
</div>
);
}
}
const CardElement = withFramePayCardComponent(CardElementComponent);
class App extends Component {
deepUpdateState(data) {
this.setState((prevState) => {
return deepMerge(prevState, data);
});
}
render() {
return (
<FramePayProvider
{...params}
onTokenReady={(token) =>
this.deepUpdateState({ error: false, data: token })
}
>
<div>
{ReactVersion()}
<CardElement />
</div>
</FramePayProvider>
);
}
}
renderFixture(<App />);