# 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 %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.payengine.co/developer-docs/getting-started-1/frontend-frameworks.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
