Payment Process Script
April 21, 2025 · AI Conversations
let count = 0;
const checkoutClickInterval = setInterval(()=>{
count++;
const hasError = checkForError();
if( hasError || count == 15 ){
console.log('clicking');
destroyCheckoutClickInterval();
}else{
if( $('#hsspp[disabled]').length == 0 ){
document.getElementById("hsspp").click()
}
}
},700);
function destroyCheckoutClickInterval(){
clearInterval(checkoutClickInterval);
}
console.log('custom jquery');
var frmresult=checkVariantValid();
if ( ! frmresult ) {
return;
}
checkdActiveSubmit();
$('.sendprocess').show();
var url = paymentURL.url;
RealexHpp.setHppUrl(url);
let check_email = $("#email_marketing:checked").length;
let check_sms = $("#sms_marketing:checked").length;
let message = '';
if (check_email > 0 && check_sms > 0) {
message = 'Customer does not want to be contacted by Email or SMS';
} else if (check_email > 0) {
message = 'Customer does not want to be contacted by Email';
} else if (check_sms > 0) {
message = 'Customer does not want to be contacted by SMS';
} else {
message = 'Customer is happy to be contacted by Email or SMS';
}
var product_resurl=document.getElementById("product_resurl").value;
let addExocet = 0;
if ($("#exocet").is(":checked")) {
addExocet = 20;
}
const data = {
product_id: document.getElementById("product_id").value,
product_price: document.getElementById("product_price").value,
billingcity: document.getElementById("billing-city").value,
billingcompany: document.getElementById("billing-company").value,
billingzip: document.getElementById("billing-zip").value,
billingphone: document.getElementById("billing-phone").value,
billingname: document.getElementById("billing-name").value,
billinglastname: document.getElementById("billing-last-name").value,
billingemail: document.getElementById("contact-email").value,
billingaddress: document.getElementById("billing-address").value,
billingaddress2: document.getElementById("billing-address2").value,
delivery_date: document.getElementById("delivery_date").value,
shippingname: document.getElementById("shipping-name").value,
shippinglastname: document.getElementById("shipping-last-name").value,
shipping_address1: document.getElementById("shipping_address1").value,
shipping_address2: document.getElementById("shipping_address2").value,
shipping_city: document.getElementById("shipping_city").value,
shipping_code: document.getElementById("shipping_code").value,
liters: document.getElementById("liters").value,
town : document.getElementById("town").value,
type: document.getElementById("type").value,
other_notes: document.getElementById("other_notes").value,
email_marketing: message,
sms_marketing: message,
product_resurl: document.getElementById("product_resurl").value,
couponCode: document.getElementById("coupon").value,
addExocet: addExocet,
};
console.log(data);
var data1 = {
'action': 'chekcPayment',
product_id: document.getElementById("product_id").value,
product_price: document.getElementById("product_price").value,
billingcity: document.getElementById("billing-city").value,
billingcompany: document.getElementById("billing-company").value,
billingzip: document.getElementById("billing-zip").value,
billingphone: document.getElementById("billing-phone").value,
billingname: document.getElementById("billing-name").value,
billinglastname: document.getElementById("billing-last-name").value,
billingemail: document.getElementById("contact-email").value,
billingaddress: document.getElementById("billing-address").value,
billingaddress2: document.getElementById("billing-address2").value,
shippingname: document.getElementById("shipping-name").value,
shippinglastname: document.getElementById("shipping-last-name").value,
shipping_address1: document.getElementById("shipping_address1").value,
shipping_address2: document.getElementById("shipping_address2").value,
shipping_city: document.getElementById("shipping_city").value,
shipping_code: document.getElementById("shipping_code").value,
delivery_date: document.getElementById("delivery_date").value,
liters: document.getElementById("liters").value,
town : document.getElementById("town").value,
type: document.getElementById("type").value,
other_notes: document.getElementById("other_notes").value,
email_marketing: message,
sms_marketing: message,
product_resurl: document.getElementById("product_resurl").value,
couponCode: document.getElementById("coupon").value,
site_name: document.getElementById("site_name").value,
site_logo: document.getElementById("site_logo").value,
addExocet: addExocet,
}
console.log(data1);
var ajaxurl = pluginAjax.ajaxurl;
console.log(ajaxurl);
jQuery.post(ajaxurl, data1, function (response) {
console.log(response);
});
$.getJSON("relax-payment", data, function(jsonFromRequestEndpoint) {
$('#hsspp').prop("disabled", false);
console.log('JSON data:', jsonFromRequestEndpoint);
RealexHpp.embedded.init("hsspp", "hspp", "realex-response", jsonFromRequestEndpoint);
$('body').addClass('loaded');
});
var iframe = document.getElementById('hspp');
var iframeDoc = iframe.contentDocument || iframe.contentWindow.document;
if (iframeDoc.body.innerHTML.trim()) {
$('#first_step').hide();
$('#second_step').show();
$('.step1').removeClass('active');
$('.step2').addClass('active');
$('html, body').animate({ scrollTop: 0 }, 'slow');
document.getElementById("hsspp").click();
destroyCheckoutClickInterval();
} else {
console.log('Iframe is empty.');
}
});
explain above code
### **Overview:**
This snippet is an event handler attached to a button with the id `#hsspp`. When clicked, it performs validation checks, gathers form data, sends AJAX requests, and integrates a payment system via RealexHpp embedded iframe. The core functionality appears to handle a payment process and customer data submission.
—
### **Step-by-step explanation:**
### ✅ **1. Initial Setup and Interval Logic**
$("#hsspp").click(function() {
let count = 0;
const checkoutClickInterval = setInterval(() => {
count++;
const hasError = checkForError();
if (hasError || count == 15) {
console.log('clicking');
destroyCheckoutClickInterval();
} else {
if ($('#hsspp[disabled]').length == 0) {
document.getElementById("hsspp").click();
}
}
}, 700);
function destroyCheckoutClickInterval() {
clearInterval(checkoutClickInterval);
}
– When the `#hsspp` button is clicked, an interval starts, running every 700 milliseconds.
– It checks for errors via `checkForError()`. If an error is found or after 15 tries (about 10 seconds), it stops retrying (clearing the interval).
– If no error and the button isn't disabled, it recursively clicks itself again (probably to trigger validation repeatedly until conditions are met).
—
### ✅ **2. Form Validation and UI Interaction**
console.log('custom jquery');
var frmresult = checkVariantValid();
if (!frmresult) {
return; // Exit early if validation fails
}
checkdActiveSubmit(); // Likely activates submit button if disabled
$('.sendprocess').show(); // Shows some loader or "processing" UI
– Validates form inputs with `checkVariantValid()`. Stops further execution if validation fails.
– Ensures the submit button is active and displays a loading indicator (`.sendprocess`).
—
### ✅ **3. Payment Setup and User Preferences Handling**
var url = paymentURL.url;
RealexHpp.setHppUrl(url);
let check_email = $("#email_marketing:checked").length;
let check_sms = $("#sms_marketing:checked").length;
let message = '';
if (check_email > 0 && check_sms > 0) {
message = 'Customer does not want to be contacted by Email or SMS';
} else if (check_email > 0) {
message = 'Customer does not want to be contacted by Email';
} else if (check_sms > 0) {
message = 'Customer does not want to be contacted by SMS';
} else {
message = 'Customer is happy to be contacted by Email or SMS';
}
– Initializes Realex payment URL.
– Determines user communication preferences from checkboxes (`email_marketing`, `sms_marketing`).
– Sets a suitable marketing preference message based on user input.
—
### ✅ **4. Collecting Form Data**
Two similar objects (`data`, `data1`) are prepared with user-entered data, including billing and shipping details, product info, and marketing preferences:
const data = {
product_id, product_price, billingcity, billingcompany, billingzip,
billingphone, billingname, billinglastname, billingemail, billingaddress,
billingaddress2, delivery_date, shippingname, shippinglastname,
shipping_address1, shipping_address2, shipping_city, shipping_code, liters,
town, type, other_notes, email_marketing: message, sms_marketing: message,
product_resurl, couponCode, addExocet
};
var data1 = {
'action': 'chekcPayment',
... // same fields as above with extra fields site_name and site_logo
};
– Both objects hold comprehensive user and product data to be sent to backend endpoints.
—
### ✅ **5. AJAX POST Request for Payment Check**
var ajaxurl = pluginAjax.ajaxurl;
jQuery.post(ajaxurl, data1, function(response) {
console.log(response);
});
– Sends a POST request to `ajaxurl` (WordPress AJAX endpoint likely).
– Sends `data1` with an action `chekcPayment` (note possible typo, likely should be `checkPayment`).
– Logs the response received from the backend.
—
### ✅ **6. Initiating Payment (Realex) via JSON GET Request**
$.getJSON("relax-payment", data, function(jsonFromRequestEndpoint) {
$('#hsspp').prop("disabled", false);
RealexHpp.embedded.init("hsspp", "hspp", "realex-response", jsonFromRequestEndpoint);
$('body').addClass('loaded');
});
– Sends GET request to the `"relax-payment"` endpoint, passes collected data, and expects JSON response for payment processing.
– Upon successful response, enables the submit button and initializes Realex embedded payment with received JSON data.
– Adds class `loaded` to the body, possibly indicating the end of a loading state.
—
### ✅ **7. Checking iframe Content and UI Adjustment**
var iframe = document.getElementById('hspp');
var iframeDoc = iframe.contentDocument || iframe.contentWindow.document;
if (iframeDoc.body.innerHTML.trim()) {
$('#first_step').hide();
$('#second_step').show();
$('.step1').removeClass('active');
$('.step2').addClass('active');
$('html, body').animate({ scrollTop: 0 }, 'slow');
document.getElementById("hsspp").click();
destroyCheckoutClickInterval();
} else {
console.log('Iframe is empty.');
}
– Checks if the Realex iframe (`hspp`) has loaded content successfully.
– If yes:
– UI updates from the first step to the second step.
– Animates the view back to the top.
– Re-clicks the button (probably to trigger the next action).
– Clears the interval checking loop.
– If no content, logs "Iframe is empty," suggesting payment iframe failed to load.
—
### **Summary of Functional Flow:**
When clicked, the button `#hsspp`:
– Checks form validity.
– Initializes a payment URL.
– Prepares user and order data.
– Sends backend requests (for validation/payment setup).
– Initiates the Realex payment gateway embedded iframe.
– Updates the UI accordingly based on iframe load success.
This code integrates a backend validation, payment initialization, AJAX requests for data storage, and Realex payment processing using embedded iframe logic
### 🔴 **Issue Explanation**
When the button (`#hsspp`) is clicked, it sets an interval that clicks itself repeatedly every 700ms:
const checkoutClickInterval = setInterval(()=>{
if ($('#hsspp[disabled]').length == 0){
document.getElementById("hsspp").click();
}
},700);
Each time the button clicks itself again, **all AJAX requests** in the function are executed repeatedly. This means multiple AJAX POST requests (`jQuery.post`) are fired repeatedly, causing multiple database insertions for the same data.
—
### 🚩 **Why this happens:**
– **Recursive Button Clicks:**
Clicking the button again programmatically (`document.getElementById("hsspp").click()`) restarts the entire handler, leading to repeated AJAX requests.
– **No Request State Checks:**
There's no flag to stop further clicks or AJAX requests once a request is successfully sent, causing data duplication.
—
### ✅ **How to fix this problem:**
**Solution 1: Add a "processing" state check**
let processing = false;
$("#hsspp").click(function() {
if (processing) return; // prevent duplicate execution
processing = true;
// your existing logic here
$.getJSON("relax-payment", data, function(jsonFromRequestEndpoint) {
$('#hsspp').prop("disabled", false);
RealexHpp.embedded.init("hsspp", "hspp", "realex-response", jsonFromRequestEndpoint);
$('body').addClass('loaded');
// Once fully successful, reset the state
processing = false;
}).fail(() => {
// Handle error
processing = false;
});
});
**Solution 2: Immediately Disable Button after first click**
$("#hsspp").click(function() {
const $button = $("#hsspp");
if ($button.prop("disabled")) return; // prevent duplicate execution
$button.prop("disabled", true);
// existing logic here
$.getJSON("relax-payment", data, function(jsonFromRequestEndpoint) {
RealexHpp.embedded.init("hsspp", "hspp", "realex-response", jsonFromRequestEndpoint);
$('body').addClass('loaded');
// Optionally re-enable after success/error:
// $button.prop("disabled", false);
});
});
—
### 🚨 **Recommended Approach:**
– Prevent the multiple-click issue clearly using either a processing flag or disabling the button.
– Ensure that only one AJAX call occurs per valid interaction to avoid duplicate database entries.
This will ensure data only saves once per submission, resolving your current issue.