# 6. Loading the frontend library

You are provided HTML/Javascript snippets that can be embedded in any frontend framework. Below you will find examples of this platform embedded in some popular frontend frameworks.&#x20;

## React

#### Step 1. Install the npm package

```markup
npm install payengine
```

#### Step 2. Load the platform using react `useEffect` hook

```javascript
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>" 
    </pay-engine>        
    </>
    )   
}
```

{% hint style="info" %}
This is just our recommended way of loading the library. There are other ways library can be loaded for example by leveraging React's provider pattern.
{% endhint %}

## React Native

**Step 1. Install  npm package**\
<https://www.npmjs.com/package/payengine-react-native>

<pre class="language-shell" data-line-numbers><code class="lang-shell">npm install payengine-react-native
<strong>npm install react-native-webview
</strong></code></pre>

{% hint style="danger" %}
**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.
{% endhint %}

**Step 2. Step 2. Load the platform**

{% code lineNumbers="true" %}

```javascript
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
  }
})
```

{% endcode %}

## Vue.js

#### Step 1. Install the npm package

```markup
npm install payengine
```

#### Step 2. Load the platform using Vue.js lifecycle `created` hook

```javascript
<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>
```

{% hint style="info" %}
This is our recommended way of loading the library. Other methods can be used according to your own requirements.
{% endhint %}

## Angular

#### Step 1. Install the npm package

```markup
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.

```javascript
// 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 the platform using lifecycle `ngOnInit` hook

```typescript
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 HTML components to the Angular Components.

```markup
<!-- 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 web components by adding a script tag pointing to javascript library. Once loaded, `pay-engine` web component are available to use anywhere in your HTML.

```markup
<!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

The Flutter package can be downloaded from <https://pub.dev/packages/payengine>

#### Step 1. Configuration&#x20;

```dart
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

```dart
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

```dart
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 web components:

```dart
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 technical contact to get access to iOS SDK.

#### &#x20;Displaying secure form

```swift
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
        }
    }
}
```

#### &#x20;Capturing card token

```swift
@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

```swift
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 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.

{% hint style="info" %}
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
* Apple Pay
* Google Pay
  {% endhint %}

{% tabs %}
{% tab title="Script Tag" %}

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

{% endtab %}

{% tab title="React Example" %}

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

const MyComponent = () => {
    useEffect(() => {
        // Load Payengine on first render only
        loadPayengine({
            publicKey: config.PAYENGINE_PUBLIC_KEY,
            lightweight: true // By default it's false
        }).then((pe) => {
            console.log(pe)
        });  
    }, []);

//... Rest of the component
}
```

{% endtab %}
{% endtabs %}
