6. Loading PayEngine frontend library

PayEngine provides HTML/Javascript snippets that can be embedded in any frontend framework. Below you will find examples of PayEngine embedded in some popular frontend frameworks.

React

Step 1. Install PayEngine npm package

npm install payengine

Step 2. Load PayEngine using react useEffect hook

import { useEffect } from "react";
import { loadPayengine } from "payengine";

const MyComponent = () => {

    useEffect(() => {
        // Load Payengine on first render only
        loadPayengine({
            publicKey: config.PAYENGINE_PUBLIC_KEY,      
        }).then((pe) => {
            console.log(pe)
        });  
    }, []);
 
    return (
    <>
    <pay-engine 
      type="boarding" 
      merchant-id="<payengine_merchant_id>" 
      hash="<HMAC_hash_of_payengine_merchant_id>">
    </pay-engine>        
    </>
    )   
}

This is just our recommended way of loading PayEngine library. There are other ways library can be loaded for example by leveraging React's provider pattern.

React Native

Step 1. Install PayEngine npm package https://www.npmjs.com/package/payengine-react-native

npm install payengine-react-native
npm install react-native-webview

Attention Mac M1 users

Mac M1 architecture is not directly compatible with Cocoapods. If you encounter issues when installing pods, you can solve it by running:

  • sudo arch -x86_64 gem install ffi

  • arch -x86_64 pod install

These commands install the ffi package, to load dynamically-linked libraries and let you run the pod install properly, and runs pod install with the proper architecture.

Step 2. Step 2. Load PayEngine

import * as React from 'react';
import { View, Text, StyleSheet, Button, ScrollView } from 'react-native';
import { SecureFields, IPayEngineConfig } from 'payengine-react-native';

const PE_CONFIG: IPayEngineConfig = {
  publicKey: PUBLIC_KEY
}


export interface IProps {
}

export function HomeScreen(props: IProps) {
  const secureFieldRef = React.createRef<any>()
  const [secureFieldsResult, setSecureFieldsResult] = React.useState('')
  const [submitting, setSubmitting] = React.useState(false)

  const createCard = async () => {
    try {
      setSubmitting(true)
      const result = await secureFieldRef.current?.createCard()
      setSecureFieldsResult(result)
      console.log({ result })
    } catch (err: any) {
      console.log({ err })
      setSecureFieldsResult(err.message)
    } finally {
      setSubmitting(false)
    }
  }


  return (
    <View style={styles.container}>
      <Text>Welcome to PayEngine React Native SDK example</Text>
      <Text>Click the hamburger menu above to browse our examples</Text>

      <View style={{ height: 30 }} />
      <Text style={{ fontSize: 18, fontWeight: '600' }}>Secure Fields</Text>
      <SecureFields.CollectManager ref={secureFieldRef} config={PE_CONFIG}>
        <SecureFields.CardHolderNameField style={styles.field} />
        <SecureFields.CardNumberField placeholder="Card number" style={styles.field} />
        <View style={{ display: 'flex', flexDirection: "row", width: '100%', height: 50, margin: 8 }}>
          <SecureFields.ExpDateTextField style={[styles.field, { flex: 1, margin: 0, marginRight: 10 }]} />
          <SecureFields.CVCField style={[styles.field, { flex: 1, margin: 0 }]} />
        </View>
        <SecureFields.ZipCodeField placeholder="Zip code" style={styles.field} />

        <Button disabled={submitting} onPress={() => createCard()} title="Create Card" />

      </SecureFields.CollectManager>
      <ScrollView scrollEnabled={true} style={{ flex: 1, width: '100%', backgroundColor: 'lightyellow', padding: 10, marginVertical: 20 }}>
        <Text>{JSON.stringify(secureFieldsResult, null, 4)}</Text>
      </ScrollView>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    display: 'flex',
    padding: 20,
    alignItems: 'center',
    justifyContent: 'center'
  },
  field: {
    width: '100%',
    height: 50,
    margin: 8,
    padding: 5
  }
})

Vue.js

Step 1. Install PayEngine npm package

npm install payengine

Step 2. Load PayEngine using Vue.js lifecycle created hook

<template>
<div>
    <pay-engine 
      type="boarding" 
      merchant-id="<payengine_merchant_id>" 
      hash="<HMAC_hash_of_payengine_merchant_id>">
    </pay-engine>        
</div>
</template>

<script>
import { loadPayengine } from "payengine";

export default {
    name: "MyComponent",
    created() {    
        try {
             loadPayengine({
                publicKey: config.PAYENGINE_PUBLIC_KEY,
            });
        } catch (e) {
            console.log({ e });
        }
    }
}
</script>

This is our recommended way of loading PayEngine library. Other methods can be used according to your own requirements.

Angular

Step 1. Install PayEngine npm package

npm install payengine

Step 2. Enable `CUSTOM_ELEMENTS_SCHEMA` mode

By default, Angular assumes that all custom HTML elements are Angular components and throws errors when encountering non-angular components. You need to enable custom elements by adding the CUSTOM_ELEMENTS_SCHEMA to the application module.

Following is an example of what a module file should look like with CUSTOM_ELEMENTS_SCHEMA added.

// app.module.js

import { NgModule, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule
  ],
  providers: [],
  bootstrap: [AppComponent],
  schemas: [ CUSTOM_ELEMENTS_SCHEMA ]
})
export class AppModule { }

Step 3. Load PayEngine using lifecycle ngOnInit hook

import { Component, OnInit } from '@angular/core';
import {loadPayengine} form 'payengine';

@Component({
  selector: 'my-component',
  templateUrl: './my-component.component.html',
  styleUrls: ['./my-component.component.scss']
})

export class MyComponent implements OnInit {

  constructor() { }

  ngOnInit(): void {
      loadPayengine({
          publicKey: config.PAYENGINE_PUBLIC_KEY,          
      });
  }
}

Step 4. Add the respective PayEngine HTML components to the Angular Components.

<!-- my-component.component.html -->
 
<div>
 
  <pay-engine 
      type="boarding" 
      merchant-id="<payengine_merchant_id>" 
      hash="<HMAC_hash_of_payengine_merchant_id>">
  </pay-engine>
  
</div>

Plain HTML/Javascript

In HTML you can enable PayEngine web components by adding a script tag pointing to PayEngine javascript library. Once loaded, pay-engine web component are avialable to use anywhere in your HTML.

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />

    <!-- PayEngine script URL -->
    <script src="https://<payengine-partner-server>/js/1.0.0/embed.js?key=YOUR_PUBLIC_API_KEY"></script>
​   </head>

  <body>
    <pay-engine 
        type="boarding" 
        merchant-id="<payengine_merchant_id>" 
        hash="<HMAC_hash_of_payengine_merchant_id>">
    </pay-engine>    
  </body>
</html>

Flutter

PayEngine Flutter package can be downloaded from https://pub.dev/packages/payengine

Step 1. Configuration

final PayEngineConfig config = const PayEngineConfig(
      publicKey: "pk_test_xxx",
      scriptURL: "https://console.payengine.co");
final String merchantId = "<your-merchant-id>";

Step 2. Displaying a credit card form

final creditCardForm = CreditCardForm(config: payengineConfig);

Container(padding: const EdgeInsets.all(10), child: creditCardForm),

OutlinedButton(
    onPressed: () async {
      final response = await creditCardForm.tokenize(merchantId);
      setState(() {
        result = response;
      });
    },
    child: const Text('Tokenize')),

Step 3. Displaying a bank account form for ACH

final bankAccountForm = BankAccountForm(config: payengineConfig);

Container(padding: const EdgeInsets.all(10), child: bankAccountForm),
OutlinedButton(
    onPressed: () async {
      final response = await bankAccountForm.tokenize(merchantId);
      setState(() {
        result = response;
      });
    },
    child: const Text('Tokenize')),

Step 4 - Using other components.

Note that the type can be any of the payengine web components.

Widget build(BuildContext context) {
  return PayEngine(
      type: "boarding",
      config: payengineConfig,
      params: {
        "merchant-id": merchantId
      },
      onEvent: (Map<String, dynamic> event) {
        debugPrint("$event");
      });
}

iOS SDK

Please ask your PayEngine's technical contact to get access to iOS SDK

Displaying secure form

override func viewDidLoad() {
    super.viewDidLoad()
    
    let config = PEConfig(publicKey: "pk_test_xxx", 
    baseURL: "https://console.payengine.co")
    
    let payengine = PayEngine(config: config)
    
    payengine.createSecureView { [unowned self] result in
        switch result {
        case .success(let view):
            DispatchQueue.main.async {
                self.secureField = view
                self.stackView.addArrangedSubview(self.secureField)                
                //... other UI elements
                // register tap action will send the createCard request
                button.addTarget(self, action: #selector(self.onButtonTap), for: .touchUpInside)                
                self.stackView.addArrangedSubview(button)
            }
        case .failure(let error):
           // Error Handling
        }
    }
}

Capturing card token

@objc func onButtonTap() {
    secureField.createCard(merchantId: "MERCHANT_ID") { [unowned self] result in
        switch result {
        case .success(let data):
            //Use data.token to make the sale API call
        case .failure(let error):
            // Error Handling
        }
    }
}

Displaying ACH form and capturing token

override func viewDidLoad() {
        super.viewDidLoad()
        
        let config = PEConfig(publicKey: "pk_test_xxx", 
        baseURL: "https://console.payengine.co")
        
        let payengine = PayEngine(config: config)
        
        payengine.createBankAccountView { [unowned self] result in
            switch result {
            case .success(let view):
                DispatchQueue.main.async {
                    self.secureField = view
                    self.stackView.addArrangedSubview(self.secureField)
                    
                    //... other UI elements
                    // register tap action will send the createCard request
                    button.addTarget(self, action: #selector(self.onButtonTap), for: .touchUpInside)                
                    self.stackView.addArrangedSubview(button)
                    }
            case .failure(let error):
                // Error Handling
            }
        }
    }
                         
    @objc func onButtonTap() {
        secureField.createBankAccount(merchantId: "a0c1f72e-b44b-48e0-a8b6-bc72ce38b4ca") { [unowned self] result in
            switch result {
            case .success(let data):
                //Use data.token to make the ach sale API call            
            case .failure(let error):
                // Error Handling
            }
        }
    }

Lightweight Version (Optimized for Secure Fields)

For applications that don't require all web components, an optimized PayEngine library version enables faster load times with access to only a limited set of components. This is advisable for those needing only secure fields or Plaid in their web application.

Please note that the optimized library only provides the following functionalities. For UI web widgets, please use the full library as specified in the previous section.

  • Secure Fields

  • Plaid

  • Fraud Session

  • 3DS flow

<head>
  <script src="https://<payengine-partner-server>/js/1.0.0/securefields.min.js?key=<your-public-api-key>"></script>
</head>

Last updated