Payment Process Script

User
$("#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);
}
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

Assistant
Here's a structured explanation of the given JavaScript/jQuery code snippet:

### **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

User
why this function save data multiple times into db
Assistant
The function is saving data multiple times into the database likely due to:

### 🔴 **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.

Leave a Comment

Your email address will not be published. Required fields are marked *