Info |
---|
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.
...
Info |
---|
Now, let's dive into how reactivity works with Payrix PayFields and why a setTimeout function is necessary in in the JavaScript. |
Integrating Payrix PayFields
Payrix 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.
...
Info |
---|
The setTimeout function acts as a synchronization mechanism between an SPA and the Payrix PayFields library, allowing you to ensure that the payment field iframes are ready for interaction. While this delay might seem like a workaround, it's a practical solution to handle the asynchronous nature of external services like PayFields within the context of SPAs, where immediate reactivity is expected. |
...
Walking through a PayFields Example of Reactivity
Expand |
---|
title | HTML PayFields Example (setTimeout) |
---|
|
Code Block |
---|
| <!-- 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):
PayFields.config.apiKey = ''
: This line initializes the PayFields configuration by setting an empty string as the API key.
PayFields.config.merchant = ''
: Similar to 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 an authorization.
PayFields.config.amount = 1000
: This sets the transaction amount to 1000 units, which represents $10.00.
Defining Payment Fields (PayFields.fields):
Customizing Styles (PayFields.customizations.style):
Event Listeners:
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 Tab), the associated function is executed. This function removes and re-add iframes related to payment fields.
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:
PayFields.onFailure = function(err) { ... }
: This sets a callback function to handle failure scenarios when interacting with PayFields. It logs the error to the console.
PayFields.onSuccess = function(response) { ... }
: This sets a callback function to handle successful interactions with PayFields. It logs the response to the console.
setTimeout Function Explanation:
The setTimeout
function is used within the 'blur' event listener for a specific purpose:
...