UNPKG

@chargebee/chargebee-js-react-wrapper

Version:
394 lines (346 loc) 13.2 kB
# Chargebee JS React Wrapper React wrapper for Chargebee Components ## Examples For detailed examples: [Click here](https://github.com/chargebee/chargebee-checkout-samples/tree/master/components/react-app#readme) ## Live Demo View live demo [here](https://www.recur.in/components-examples/react/#/example1) ## Installation Install from npm: ```bash npm install @chargebee/chargebee-js-react-wrapper ``` ## Usage Chargebee Components requires you to initialize chargebee js with `site` and `publishableKey` > Wondering where to obtain your publishable API key? [Refer here](https://www.chargebee.com/docs/api_keys.html) In your `index.html`: ```html <html> <head> ... <script src="https://js.chargebee.com/v2/chargebee.js"></script> <script> Chargebee.init({ site: 'your-site', publishableKey: 'your-publishable-key' }) </script> </head> <body> <div id='root'></div> </body> </html> ``` ### Basic usage In your react component ```jsx import { CardComponent } from '@chargebee/chargebee-js-react-wrapper'; class App extends React.Component { cardRef = React.createRef() ... onSubmit = (e) => { if(e) e.preventDefault() this.cardRef.current.tokenize() .then((data) => { console.log('chargebee token', data.token) }); } ... render() { // Using combined mode return( <div className="App"> <form> ... <CardComponent ref={this.cardRef} onChange={this.onChange}/> <button type="submit" onClick={this.onSubmit}>Submit</button> ... </form> </div> ) } } ``` ### A more complex example: ```jsx import {CardComponent, CardNumber, CardExpiry, CardCVV} from "react-cb"; import './App.css' class App extends Component { cardRef = React.createRef() state = { errors: {}, errorMessage: '', // CSS class names for field's status classes: { 'focus': 'focus-css-class', 'complete': 'complete-css-class', 'invalid': 'invalid-css-class', 'empty': 'empty-css-class', }, // Google Fonts and other whitelisted fonts fonts: [ 'https://fonts.googleapis.com/css?family=Open+Sans' ], // Style customizations styles: { base: { color: '#fff', fontWeight: 600, fontFamily: 'Quicksand, Open Sans, Segoe UI, sans-serif', fontSize: '16px', fontSmoothing: 'antialiased', ':focus': { color: '#424770', }, '::placeholder': { color: '#9BACC8', }, ':focus::placeholder': { color: '#CFD7DF', }, }, invalid: { color: '#fff', ':focus': { color: '#FA755A', }, '::placeholder': { color: '#FFCCA5', }, }, } } onSubmit = (e) => { if(e) e.preventDefault() if(this.cardRef) { // Call tokenize method on card element this.cardRef.current.tokenize().then((data) => { console.log('chargebee token', data.token) }); } } onChange = (status) => { let errors = { ...this.state.errors, [status.field]: status.error }; let errMessages = Object.values(errors).filter(message => !!message); this.setState({ errors, errorMessage: errMessages.pop() || '', }) } onReady = (el) => { el.focus(); } render() { const { fonts, styles, classes, locale } = this.state; // Using individual fields mode return ( <div className="App"> <div className="cell example example3" id="example-3"> <form> <div className="fieldset"> <CardComponent className="field" fonts={fonts} classes={classes} locale={locale} styles={styles} ref={this.CardRef} showTestCards={true} onReady={this.onReady} > <CardNumber placeholder='4111 1111 1111 1111' className="field empty" onChange={this.onChange} onReady={this.onReady} /> <CardExpiry placeholder='MM / YY' className="field empty" onChange={this.onChange} /> <CardCVV placeholder='CVV' className="field empty" onChange={this.onChange} /> </CardComponent> </div> <button type="submit" onClick={this.onSubmit}>Pay now</button> </form> <div id="errors">{this.state.errorMessage}</div> </div> </div> ); } } ``` ## Server Side Rendering using NextJS #### Pre-requisites: The chargebee instance should be initialized with `site` and `API Key` and the initiated cb instance should be passed as props to the `Provider` component. A validation is done to check 3 things: * Passed `site` as non-empty string, during initialization call * Passed `API Key` as non-empty string, during initialization call * cbInstance initialized status Also, a project using `NextJS` should be setup #### Usage: 1. Load `chargebee.js script` before any other code/script execution(generally `index.html`). This is to enable `Chargebee` be a part of client side browser `window` ```html <script src="https://js.chargebee.com/v2/chargebee.js"> </script> ``` 2. Initialize chargebee inside componentDidMount(), do not use it in constructor() or render() when using SSR ```jsx componentDidMount() { .. // initialize with site, publishableKey window.Chargebee.init({ site: "...", publishableKey: "..." }); // get cb Instance cbInstance = window.Chargebee.getInstance(); .. } ``` 3. Import the Provider, CardComponent, etc. components from the module ```jsx import {CardComponent, CardNumber, CardExpiry, CardCVV, Provider} from "@chargebee/chargebee-js-react-wrapper"; ``` 4. Within your custom component, wrap the `CardComponent` inside a `Provider` component, pass the cbInstance as props ```jsx <Provider cbInstance={this.props.cbInstance}> <CardComponent ... > ... </CardComponent> </Provider> ``` #### Example: Detailed example : ```jsx import {CardComponent, CardNumber, CardExpiry, CardCVV, Provider} from "@chargebee/chargebee-js-react-wrapper"; ... componentDidMount() { window.Chargebee.init({ site: "honeycomics-v3-test", publishableKey: "your_site_pub_api_key" }) this.setState({ cbInstance: window.Chargebee.getInstance() }) } render() { ... <script src="https://js.chargebee.com/v2/chargebee.js" ></script> ... <Provider cbInstance={this.state.cbInstance}> <CardComponent ref={this.cardRef} className="fieldset field" styles={style} classes={classes} locale={locale} placeholder={placeholder} fonts={fonts} showTestCards={true} > <div className="ex1-field"> {/* Card number component */} <CardNumber className="ex1-input"/> <label className="ex1-label">Card Number</label><i className="ex1-bar"></i> </div> <div className="ex1-fields"> <div className="ex1-field"> {/* Card expiry component */} <CardExpiry className="ex1-input"/> <label className="ex1-label">Expiry</label><i className="ex1-bar"></i> </div> <div className="ex1-field"> {/* Card cvv component */} <CardCVV className="ex1-input"/> <label className="ex1-label">CVC</label><i className="ex1-bar"></i> </div> </div> </CardComponent> </Provider> ... } ``` #### Run the application * npm install * (NextJS project structure with chargebee-js-react-wrapper installed) -> npm run build / start / dev ```jsx "scripts": { "dev": "next dev", "build": "next build", "start": "next start" } ``` ### 3DS Authorization In your react component ```jsx import { CardComponent } from '@chargebee/chargebee-js-react-wrapper'; class App extends React.Component { cardRef = React.createRef() ... createPaymentIntent() { // make ajax call to server to create payment intent } ... componentDidMount() { this.createPaymentIntent().then(intent => { this.state.intent = intent; }) } ... onSubmit = (e) => { if(e) e.preventDefault() const intent = this.state.intent; const additionalData = this.state.additionalData; this.cardRef.current.authorizeWith3ds(intent, additionalData) .then(authorizedPaymentIntent => { console.log('Authorized payment intent', authorizedPaymentIntent.id) }).catch(error => { console.error('Error occured', error) }); } ... render() { // Using combined mode return( <div className="App"> <form> ... <CardComponent ref={this.cardRef} onChange={this.onChange}/> <button type="submit" onClick={this.onSubmit}>Submit</button> ... </form> </div> ) } } ``` ## Components and APIs #### Card Component ([docs](https://chargebee.com/checkout-portal-docs/components-fields-reference.html#card-component-object)) Props | Description | Datatype ------|-------------|--------- `className` | CSS Class name for the container div | String `fonts` | An array of font faces or links | [Fonts](https://chargebee.com/checkout-portal-docs/components-fields-reference.html#parameters-3) `classes` | Set of CSS classnames that get substituted for various [events](https://chargebee.com/checkout-portal-docs/components-fields-reference.html#on) | [Classes](https://chargebee.com/checkout-portal-docs/components-fields-reference.html#parameters-3) `locale` | Language code | [Locale](https://chargebee.com/checkout-portal-docs/components-fields-reference.html#parameters-3) `styles` | Set of style customizations | [Styles](https://chargebee.com/checkout-portal-docs/components-fields-reference.html#parameters-3) `placeholder` | Set of placeholders for the card fields | [Placeholder](https://chargebee.com/checkout-portal-docs/components-fields-reference.html#parameters-3) `ref` | React Ref element for tokenizing data | [ReactRef](https://reactjs.org/docs/refs-and-the-dom.html#creating-refs) `showTestCards` | Add ability to show test cards on test sites | Boolean ##### Event Props ([docs](https://chargebee.com/checkout-portal-docs/components-fields-reference.html#on)) Props | Description | Arguments ------|-------------|--------- `onReady` | Triggers when component is mounted and ready | [Field](https://chargebee.com/checkout-portal-docs/components-fields-reference.html#card-field-object) `onChange` | Triggers for every state change | [Field State](https://chargebee.com/checkout-portal-docs/components-fields-reference.html#parameters-6) `onFocus` | Triggers when component is focused | [Field State](https://chargebee.com/checkout-portal-docs/components-fields-reference.html#parameters-6) `onBlur` | Triggers when component is blurred | [Field State](https://chargebee.com/checkout-portal-docs/components-fields-reference.html#parameters-6) `onKeyPress` | Triggers when a key is pressed inside component <br/>Supports `ESC` key | [Field State](https://chargebee.com/checkout-portal-docs/components-fields-reference.html#parameters-6) #### Field Components ([docs](https://chargebee.com/checkout-portal-docs/components-fields-reference.html#card-field-object)) * CardNumber * CardExpiry * CardCVV Props | Description | Datatype ------|-------------|--------- `className` | CSS Classname for container `div` | String `styles` | Styles for inidividual field | [Styles](http://localhost:8081/checkout-portal-docs/components-fields-reference.html#parameters-5) `placeholder` | Placeholder for the field | String ##### Event Props ([docs](https://chargebee.com/checkout-portal-docs/components-fields-reference.html#on-2)) Props | Description | Arguments ------|-------------|--------- `onReady` | Triggers when component is mounted and ready | [Field](https://chargebee.com/checkout-portal-docs/components-fields-reference.html#card-field-object) `onChange` | Triggers for every state change | [Field State](https://chargebee.com/checkout-portal-docs/components-fields-reference.html#parameters-6) `onFocus` | Triggers when component is focused | [Field State](https://chargebee.com/checkout-portal-docs/components-fields-reference.html#parameters-6) `onBlur` | Triggers when component is blurred | [Field State](https://chargebee.com/checkout-portal-docs/components-fields-reference.html#parameters-6) ## Reference: [Chargebee Components - JS Docs](https://chargebee.com/checkout-portal-docs/components-fields-integrations.html#quick-start-integration) ## Support Have any queries regarding the implementation? Reach out to [support@chargebee.com](mailto:support@chargebee.com)