1.2.8 • Published 7 months ago

@magensa/te-connect-react v1.2.8

Weekly downloads
1
License
MIT
Repository
github
Last release
7 months ago

TEConnect React Component

npm version

React component for use with Token Exchange Connect utility.

Getting Started

npm install @magensa/te-connect @magensa/te-connect-react

or

yarn add @magensa/te-connnect @magensa/te-connect-react

Manual Card Entry

This document will cover the card manual entry component that TEConnect offers.
TEConnect also offers a Payment Request component as well, with both Apple Pay and Google Pay supported. Payment Request Documentation can be found here
Below we will begin with a step-by-step integration of the card manual entry component. If you would prefer to let the code speak, there is an example implementation.

Magensa™

TEConnect Manual Entry, and TEConnect Payment Request components both require a valid Magensa™ account. If you need assistance creating or configuring an account, please reach out to the Magensa Support Team.

Step-By-Step

  1. The first step is to create a TEConnect instance, and feed that instance to the wrapper around your application.

    import React from 'react';
    import { TEConnect } from '@magensa/te-connect-react';
    import { createTEConnect } from '@magensa/te-connect';
    import ExampleApp from './components/exampleApp';
    
    const teConnectInstance = createTEConnect("__publicKeyGoesHere__", /* { hideZip: true } */);
    
    const App = () => (
        <TEConnect teConnect={ teConnectInstance }>
            <ExampleApp />
        </TEConnect>
    );
    • It's recommended to place this instance at the entrypoint of your application, to avoid multiple re-renders - or creating a new instance accidentally.
    • There is an optional options object that can be passed to createTEConnect as the second parameter.
  2. Next, once you have your form designed - drop the CardEntry component in the place of your choosing.

    import React from 'react';
    import { CardEntry } from '@magensa/te-connect-react';
    
    const appStyles = {
        height: '100px'
    }
    
    export default () => (
        <form>
            <input type="text" name="customer-name" />
            <div styles={ appStyles }>
                <CardEntry />
            </div>
        </form>
    );
    • It's recommended to wrap the CardEntry with a <div> of your choosing - so you may apply wrapper styles directly to your own div for juxtaposition. It's important to note that the height of this component is set to 100% so that it may respond to your application's wrapper styles. As for styles applied to the component itself - we have a styles object that you may use to inject your own custom styles.
    • stylesConfig prop is optional. If provided, it will override the defaults.
  3. Finally, to submit the inputted card values, utilize the createPayment and getCurrentElements functions and attach to your click handler.

       import React from 'react';
       import { CardEntry, useTeConnect } from '@magensa/te-connect-react';
    
       const customStyles =  {
           base: {
               wrapper: {
                   margin: '2rem',
                   padding: '2rem'
               },
               variants: {
                   inputType: 'outlined',
                   inputMargin: 'dense'
               },
               backgroundColor: '#ff7961'
           },
           boxes: {
               textColor: "#90ee02",
               borderRadius: 4,
               errorColor: "#2196f3"
           }
       }
    
       export default () => {
           const { createPayment, getCurrentElements } = useTeConnect();
    
           const clickHandler = async(e) => {
               try {
                   const elements = getCurrentElements();
                   const teConnectResponse = await createPayment(elements, /* billingZipCode */);
                   const { error } = teConnectResponse;
    
                   if (error)
                       console.log("Unsuccessful, message reads: ", error);
                   else
                       console.log('result:', teConnectResponse);
               }
               catch(err) {
                   console.log('[Catch]:', err);
               }
           }
    
           return (
               <>
                   <CardEntry stylesConfig={ customStyles } />
                   
                   <button onClick={ clickHandler }>Create Token</button>
               </>
           )
       }
  • Make sure to await this call, since it is asyncronous, and additionally be sure to wrap the call in a try/catch.

    • It's important to note that while there are some cases which will throw an exception (catch) - there are other cases in which an object will return successfully with an error message. Make sure you check for an error property on the returned object. If it's not present - the call is succesful. For additional information, please see the possible return objects
  • Note that in this example, we chose to provide customStyles to the CardEntry component.

TEConnect Options

The second parameter of the createTEConnect method is an options object. This object is optional. | Property Name | Input Type | Notes | |:--:|:--:|:--:| | billingZip | boolean | See billingZip options below | | tecPaymentRequest | TecPaymentRequestOptions | See the Payment Request README for more info |

type TecPaymentRequestOptions = {
    appleMerchantId?: string,
    googleMerchantId?: string
}

type CreateTEConnectOptions = {
    hideZip?: boolean,
    tecPaymentRequest?: TecPaymentRequestOptions
}

Options for billingZip


Billing Zip Code (billingZip) is an optional field. There are two different ways to supply the billingZip, and one way to opt out.

Opt In:

The below instance will display the "ZIP Code" field along the other inputs. When choosing this option, the ZIP Code input box will be a required field for the customer.

    const teConnectInstance = createTEConnect("__publicKeyGoesHere__");

Supply Optional Billing Zip:

The below will hide the "ZIP Code" input box. Once the field is hidden - the value becomes optional. If you would still like to supply a billing zip (I.E. You have a ZIP Code input on your own form, and would like the billingZip to be included in the payment token), here is an example of how to achieve that.

    //First, create the instance with the ZIP field hidden
    const teConnectInstance = createTEConnect("__publicKeyGoesHere__", { hideZip: true });

    //Then supply the value when making the call to create payment token.
    const clickHandler = async(e) => {
        const billingZipCode = "90018";
        //Note that 'billingZip' is a string.

        try {
            const elements = getCurrentElements();
            const teConnectResponse = await createPayment(elements, billingZipCode);
            const { error } = teConnectResponse;

            if (error)
                console.log("Unsuccessful, message reads: ", error);
            else
                console.log('result:', teConnectResponse);
        }
        catch(err) {
            console.log('[Catch]:', err);
        }
    }

Opt Out:

The below will hide the input field, and when a value is not supplied - the payment token will be created without a billing zip code.

    //First, create the instance with the ZIP field hidden
    const teConnectInstance = createTEConnect("__publicKeyGoesHere__", { hideZip: true });

    //When the ZIP field is hidden, the billingZip parameter is optional.
    const clickHandler = async(e) => {
        try {
            const elements = getCurrentElements();
            const teConnectResponse = await createPayment(elements);
            const { error } = teConnectResponse;

            if (error)
                console.log("Unsuccessful, message reads: ", error);
            else
                console.log('result:', teConnectResponse);
        }
        catch(err) {
            console.log('[Catch]:', err);
        }
    }

createPayment Return Objects

These are the possible objects that will be returned successfully from the createPayment function. Thrown errors will be thrown as any other async method.

  1. Success:

{
    magTranID: String,
    timestamp: String,
    customerTranRef: String,
    token: String,
    code: String,
    message: String,
    status: Number,
    cardMetaData: null | {
        maskedPAN: String,
        expirationDate: String,
        billingZip: null | String
    }
}
  1. Bad Request

{
    magTranID: String,
    timestamp: String,
    customerTranRef: String,
    token: null,
    code: String,
    message: String,
    error: String,
    cardMetaData: null
}
  1. Error (Failed Validation, Timeout, Mixed Protocol, etc)

{ error: String }

Styles API

The styles object injected is composed of two main properties:

  • base
    • General styles applied to the container.
  • boxes
    • Styles applied to the input elements.

Below we have the complete API with examples of default values for each.

Base

Property NameParent PropertyInput TypeAcceptable ValuesDefault ValueNotes
backgroundColorbasestringjss color (rgb, #, or color name)"#fff"container background color
marginwrapperstring or numberjss spacing units (rem, em, px, etc)'1rem'container margin
paddingwrapperstring or numberjss spacing units (rem, em, px, etc)'1rem'container padding
directionwrapperstring'row', 'row-reverse', 'column', 'column-reverse''row''flex-direction' style property
flexWrapwrapperstring'wrap', 'wrap', 'wrap-reverse''wrap''flex-wrap' style property
inputTypevariantsstring"outlined", "filled", "standard""outlined"template design for input boxes
inputMarginvariantsstring"dense", "none", "normal""normal"template padding & margins for input boxes
autoMinHeightvariantsbooleanbooleanfalsetrue will maintain a static margin on each input box that will not grow with validation errors

Default Base Object:

{
    base: {
        wrapper: {
            margin: '1rem',
            padding: '1rem',
            direction: 'row',
            flexWrap: 'wrap'
        },
        variants: {
            inputType: 'outlined',
            inputMargin: 'normal',
            autoMinHeight: false
        },
        backgroundColor: '#fff'
    }
}

Boxes

Property NameInput TypeAcceptable ValuesDefault ValueNotes
labelColorstringjss color (rgb, #, or color name)"#3f51b5"label text and input outline (or underline) color
textColorstringjss color (rgb, #, or color name)"rgba(0, 0, 0, 0.87)"color of text for input value Also applies :onHover color to outline/underline
borderRadiusnumbernumerical unit for css border-radius property4border radius for input boxes
inputColorstringjss color (rgb, #, or color name)"#fff"input box background color
errorColorstringjss color (rgb, #, or color name)"#f44336"Error text and box outline (or underline) color

Default Boxes Object:

{
    boxes: {
        labelColor: "#3f51b5",
        textColor: "rgba(0, 0, 0, 0.87)",
        borderRadius: 4,
        errorColor: "#f44336",
        inputColor: "#fff"
    }
}

Example Implementation

import React from 'react';
import ReactDOM from 'react-dom';
import { TEConnect, CardEntry, useTeConnect  } from '@magensa/te-connect-react';
import { createTEConnect } from '@magensa/te-connect';

const customStyles =  {
    base: {
        wrapper: {
            margin: '2rem',
            padding: '2rem'
        },
        variants: {
            inputType: 'outlined',
            inputMargin: 'dense'
        },
       backgroundColor: '#ff7961'
    },
    boxes: {
        labelColor: "#9400D3",
        textColor: "#90ee02",
        borderRadius: 10,
        errorColor: "#2196f3",
        inputColor: '#ff7961'
    }
}

const ExampleApp = () => {
    const { createPayment, getCurrentElements } = useTeConnect();

    const clickHandler = async(e) => {
        try {
            const elements = getCurrentElements();
            const teConnectResponse = await createPayment(elements);
            console.log('result:', teConnectResponse);
        }
        catch(err) {
            console.error(err);
        }
    }
    
    return (
        <React.Fragment>
            <CardEntry stylesConfig={ customStyles } />
            
            <button onClick={ clickHandler }>Create Token</button>
        </React.Fragment>
    )
}

const teConnectInstance = createTEConnect("__publicKeyGoesHere__");

const App = () => (
    <TEConnect teConnect={ teConnectInstance }>
        <ExampleApp />
    </TEConnect>
);

ReactDOM.render(
    <React.StrictMode>
        <App />
    </React.StrictMode>,
    document.getElementById('root')
);

Minimum Requirements

There are three dependencies to use this product. If you built your project using create-react-app, then you have already met the requirements (may require a 'uuid' upgrade). If you are building your own React app, then please make sure to include the following in your project:

1.2.8

7 months ago

1.2.7

7 months ago

1.2.6

7 months ago

1.2.5

9 months ago

1.2.4

10 months ago

1.2.0

1 year ago

1.2.3

1 year ago

1.2.2

1 year ago

1.2.1

1 year ago

1.1.0

2 years ago

1.0.6

3 years ago

1.0.5

3 years ago

1.0.4

3 years ago

1.0.3

3 years ago

1.0.2

4 years ago

1.0.1

4 years ago

1.0.0

4 years ago