Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Reactivity is a core concept in modern web development, especially in the context of Single-Page Applications (SPAs). SPAs, such as those built with React, Vue.js, and Angular, aim to provide a seamless and responsive user experience by dynamically updating the UI in response to user interactions and data changes. In this article, we will explore reactivity in SPAs and how it relates to integrating third-party services like PayFields.

Reactivity in SPAs

Reactivity in SPAs refers to the ability of the application to automatically update the user interface (UI) when data changes occur. SPAs typically load a single HTML page and then use JavaScript frameworks like React, Vue.js, or Angular to manipulate and update the DOM (Document Object Model) dynamically.

Key Concepts of Reactivity in SPAs

  • Virtual DOM: React, for example, uses a Virtual DOM to represent the UI. When data changes, React compares the new Virtual DOM with the previous one to calculate the minimum number of changes needed to update the actual DOM.

  • Components: In React and Vue.js, UI elements are structured as components. Each component can have its own state and props (properties) and is responsible for rendering a part of the UI. When a component's state or props change, it re-renders itself.

  • Data Binding: Angular, on the other hand, uses two-way data binding. When data in the model changes, the view updates automatically, and vice versa.

  • Asynchronous Operations: SPAs often involve asynchronous operations, such as making API requests. These operations can trigger changes in the UI when responses are received.

Now, let's dive into how reactivity works with PayFields and why a setTimeout function is necessary in in JavaScript.

Integrating PayFields

PayFields is a payment processing embedded solution that allows you to securely handle sensitive payment information, such as credit card numbers, within a web application. When integrating PayFields into an SPA, you want to ensure a smooth and secure user experience. However, PayFields operates independently and asynchronously, which can create challenges when it comes to reactivity.

Dynamic Loading

PayFields loads its scripts and resources dynamically to enhance security. This means that the PayFields library might not be available immediately when an SPA loads.

iFrame Integration

PayFields uses iFrames to isolate and secure payment-related data. These iFrames need to be added to the DOM when the PayFields library is ready.

Reactivity Delay

SPAs often expect immediate reactivity, but PayFields might not be ready instantly. This is why you see a setTimeout function in the JavaScript file.

Understanding setTimeout in the PayFields Integration

Here's why it's necessary:

...

Reactivity: By waiting for a short period, you ensure that when you call PayFields.addFields(), the iFrames are present in the DOM and can be manipulated reactively by an SPA.

...

PayFields Reactivity Example

Expand
titleHTML PayFields Example (setTimeout)
Code Block
languagehtml
<!-- Bootstrap CSS -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">

<div class="container">
    <div class="row">
        <div class="col-8 offset-2">
          <p>Customer Name:</p>
          <input type="text" id="newName" class="input" placeholder="Customer Name">
          <p>Email:</p>
          <input type="email" id="email" class="input" placeholder="Email Address">
          <div id="box">
            <p>Customer Name</p>
            <div class="con" id="name"></div>
            <p>Number:</p>
              <div class="con" id="number"></div>
              <p>Expiration:</p>
              <div class="con" id="expiration"></div>
            <p>CVV:</p>
              <div class="con" id="cvv"></div>
          </div>
            <p>Country:</p>
            <input type="text" id="country" class="input" placeholder="Country">
            <p>Zip Code:</p>
            <input type="zip" id="zip" class="input" placeholder="Zip Code">
            <br>
            <button type="button" id="btn" class="btn btn-md btn-success text-white float-end">Make Payment</button>
        </div>
    </div>
</div>

<style>

    div .con {
        height: 55px;
        border-right: 1rem
    }
    /*
    Match the CSS styles with PayField styles
    */
    .input {
      display: block;
      width: 100%;
      padding: 1.25rem 1.75rem 1.25rem 1rem;
      font-size: .825rem;
      font-weight: 400;
      line-height: 1.5rem;
      border: none;
      background-color: #fff;
      background-clip: padding-box;
      border-bottom: 1px solid #ddd;
      appearance: none;
      outline: none;
      height: 1.25rem;
      line-height: 2px;
    }

</style>

<!-- jQuery -->
<script type="text/javascript" src="https://code.jquery.com/jquery-2.2.4.min.js"></script>
<!-- Sandbox URL -->
<script type="text/javascript" src="https://test-api.payrix.com/payFieldsScript"></script>
<!-- Option 1: Bootstrap Bundle with Popper -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>

<script>

// Configurations
PayFields.config.apiKey = ''
PayFields.config.merchant = ''
PayFields.config.mode = 'txn';
PayFields.config.txnType = 'auth'
PayFields.config.amount = 1000

PayFields.fields = [
  {
    type: "number",
    element: "#number"
  },
  {
    type: "name",
    element: "#name"
  },
  {
    type: "cvv",
    element: "#cvv",
  },
  {
    type: "expiration",
    element: "#expiration",
  }
];

PayFields.customizations.style = {
    ".input": {
        display: "block",
        width: "100%",
        padding: "0.5rem 0.9rem",
        fontSize: ".825rem",
        fontWeight: "400",
        backgroundColor: "#fff",
        backgroundClip: "padding-box",
        borderBottom: "1px solid #ddd",
        appearance: "none",
        height: "1.25rem",
        borderRight: "1px solid #ddd"
    },
    ".form-error": {
        color: "#980000"
    }
};

document.querySelector("#newName").addEventListener('blur', function() {
  // If we remove all iFrames, the iframe-main will also be removed which is the parent wrapper of each PayFields.fields.
  // With this approach, iframe-main will remain within the DOM, and child DIV's are removed.
  let expiration = document.querySelector('iframe#payFields-iframe-expiration')
  let name = document.querySelector('iframe#payFields-iframe-name')
  let cvv = document.querySelector('iframe#payFields-iframe-cvv')
  let number = document.querySelector('iframe#payFields-iframe-number')

  // Remove all divs to re-mount all iFrames to the DOM
  expiration.remove()
  name.remove()
  cvv.remove()
  number.remove()

  setTimeout(() => {
  PayFields.fields = [
  {
    type: "name",
    element: "#name",
    values: {
      name: document.querySelector('#newName').value
    }
  },
  {
    type: "number",
    element: "#number"
  },
  {
    type: "cvv",
    element: "#cvv",
  },
  {
    type: "expiration",
    element: "#expiration",
  }

];
  
  PayFields.addFields()

  // 1 second will allow adequate time for the iFrames to be mounted to the DOM
}, 1000);
})

document.querySelector('#btn').addEventListener('click', function() {
    PayFields.config.billingAddress = {
      zip: document.querySelector('#zip').value,
      email: document.querySelector('#email').value,
      country: document.querySelector('#country').value
    };
    PayFields.submit()
})

// Failure Callback
PayFields.onFailure = function(err) {
  console.log(err)
}

// Success Callback
PayFields.onSuccess = function(response) {
  console.log(response)
}
</script>

Configuration (PayFields.config)

Parameter

Description

PayFields.config.apiKey = ''

This line initializes the PayFields configuration by setting an empty string as the API key.

PayFields.config.merchant = ''

Like the API key, this sets an empty string as the Merchant ID. Replace it with the Merchant ID.

PayFields.config.mode = 'txn';

This sets the operating mode to txn, which stands for a transaction. It specifies the mode in which PayFields should operate.

PayFields.config.txnType = 'auth'

The txnType is set to auth, indicating that the transaction type is authorization.

PayFields.config.amount = 1000

This sets the transaction amount to 1000 units, which represents $10.00.

Defining Payment Fields (PayFields.fields)

Several objects are defined within the PayFields.fields array. These objects specify the types of payment fields and the corresponding DOM elements where they should be rendered.

Array Parameters

Description

type: "number", element: "#number"

Card Number

type: "name", element: "#name"

Cardholder Name

type: "cvv", element: "#cvv"

CVV Code

type: "expiration", element: "#expiration"

Card Expiration Date

Customizing Styles (PayFields.customizations.style)

Styles for the payment fields are customized using the PayFields.customizations.style object. The styles are defined for elements with the class .input and elements with the class .form-error. These styles control the appearance of the payment fields and error messages.

Tip

Tip: Your PayFields.customizations.style object stylization section formatting will function identically to CSS under the .input class.

Event Listeners

Event Listener Script

Descriptions

Code Block
languagejs
document.querySelector("#newName").addEventListener('blur', function() { ... })

An event listener is added to the blur event of the input field with the ID newName. When this input field loses focus (i.e., the user clicks away or presses the ‘Tab’ key), the associated function is executed. This function removes and re-adds iFrames related to payment fields.

Code Block
languagejs
document.querySelector('#btn').addEventListener('click', function() { ... })

Another event listener is added to the click event of the button with the ID btn. When this button is clicked, the associated function is executed.

Callback Functions

Callback Function

Description

Code Block
languagejs
PayFields.onFailure = function(err) { ... }

This sets a callback function to handle failure scenarios when interacting with PayFields. It logs the error to the console.

Code Block
languagejs
PayFields.onSuccess = function(response) { ... }

This sets a callback function to handle successful interactions with PayFields. It logs the response to the console.

setTimeout Example Function Explained
Anchor
timeout
timeout

The script tag handles the configuration of PayFields, event handling, and callback functions, including customization of payment field styles and managing iFrames to ensure a smooth payment processing experience, while the setTimeout function ensures proper reactivity of these operations and timing synchronization with PayFields.

...