Disable SqPaymentForm input fields after checkout has started

Hi Everyone,

I was wondering, in SqPaymentForm, is there a way to disable the input fields for cardNumber, cvv, expirationDate and postalCode after the checkout process / payment has started and is currently in progress? In my integration, I have the problem that the fields above can still be edited by the user while the payment is in progress.

I believe, all of these are iframes once mounted, correct? Simply disabling the original

I provide in the html as no effect.

Am I missing something?


Hi @fbormann, welcome to the forums!

No, I don’t believe there’s a way to directly access those iframes to disable them. What are you trying to actually prevent, though?

Hi @sjosey,

Thanks for your reply.

I just feel that the information displayed on the page should at all times reflect a transaction while it is still in progress in the background. I am therefore disabling all of my own input elements in the form until receiving the final result of the transaction. Not being able to do this with the SqPaymentForm elements makes the user experience inconsistent. They can’t edit my own elements but they can still edit the Square elements. Plus whatever is on the screen once the final transaction result comes back may no longer reflect the data used for the transaction.

I’ve also had the transaction status field on my page auto-clear the last transaction result (if failed) as soon as the user starts to make modifications to any data entered on the page. This currently actually even clears the “In progress” message while the transaction is still going on as soon as the user starts editing any of the SqPaymentForm fields. I would now have to refine that implementation to defer any effect of SqPaymentForm input field data changes on the status message until after the ongoing transaction result comes back. Plus, facing a decision on how long I want to display the result of the previous (failed) transaction, given that the previous design paradigm was to display it until the user starts to edit the data in form, however, now the data may already been edited by the time the result comes back.

Overall, I feel that the user experience is just much more confusing this way.

May I kindly ask to make this a feature request? I’ve made integrations with two other (competing) credit card payment services before and they both offer this functionality.


In case, anyone else is interested, I came up with my own solution, after much Googling (this is my first ever web application). It works by putting an empty <div> as an overlay in the container containing all the Square card elements and pay button at the exact same position. The container <div> is changed to a positioned element by giving it the positon:relative property but not actually moving it from its default position in the document flow. However, this allows the overlay element with position:absolute to reference the container’s position and size and match it exactly. The overlay is initially hidden. Being the last element in the container ensures that it is rendered “on top” of all the other elements in the container, therefore blocking access to any of the card entry as well as the pay button when enabled.

<div id=“sq-container” style=“position: relative; max-width: 380px; margin: auto;”>
<div id=“sq-card-number”></div>
<div class=“third” id=“sq-expiration-date”></div>
<div class=“third” id=“sq-cvv”></div>
<div class=“third” id=“sq-postal-code”></div>
<button id=“sq-creditcard” class=“button-credit-card”>Pay</button>
<div id=“sq-overlay” style=“position: absolute; left: 0; top: 0; width: 100%; height: 100%; visibility: hidden;”></div>

In Javascript, you can then turn the overlay on and off at will:

function disableSquareElements(state)
document.getElementById(“sq-overlay”).style.visibility = state ? “visible” : “hidden”;

While this takes care of the elements not being reachable by mouse clicks, they can still be activated by using the keyboard “tab” key. However, there is a solution for this as well. While mounting the Square Elements on the <div>s above and converting them into <iframe>s, the element ids actually stay the same. In addition to that, the <iframes> still support the tabIndex property, which I guess would prevent any active element in an <iframe> to not be reachable, but here we only seem to have a single element in each of the <iframe>s. Therefore, we can extend the above code to:

function disableSquareElements(state)
document.getElementById(“sq-overlay”).style.visibility = state ? “visible” : “hidden”;
document.getElementById(“sq-card-number”).tabIndex =
document.getElementById(“sq-expiration-date”).tabIndex =
document.getElementById(“sq-cvv”).tabIndex =
document.getElementById(“sq-postal-code”).tabIndex = state ? -1 : 0;
document.getElementById(“sq-creditcard”).disabled = state;