Tokenization Error in card tokenize method

I’m integrating Square Web Payments SDK in my Core PHP project to handle card payments. However, I noticed that tokenize() is being called multiple times when the payment button is clicked.

Issue Description:

  • When a user clicks the payment button, tokenize() is triggered.
  • If tokenization fails (e.g., invalid card details), the SDK still processes the request.
  • After that, I get the “card nonce already used with a different idempotency key” error when retrying the payment.
  • And then the payment happened successfully.

Here’s the JavaScript code handling the payment request:
document.getElementById(‘payment-button’).addEventListener(‘click’, async function () {
jQuery(“.ct-loading-main-complete_booking”).show(); // Show loader

try {
    const result = await card.tokenize();

    if (result.status === 'OK') {
        fetch('assets/lib/square_ajax.php', {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({ action: type, amount: amount, token: result.token })
        })
        .then(response => response.json())
        .then(async data => {
            if (data.msg === "success") {
                save_database_records(data.transaction_id, data.sp_authorize_id);
            } else {
                noty({
                    text: data.msg + "!!", killer: true, type: "error", layout: "topCenter",
                    timeout: 6000
                });
                await resetCardField(payments);
            }
            jQuery(".ct-loading-main-complete_booking").hide(); // ✅ Hide loader
        })
        .catch(async (error) => {
            console.error(error);
            noty({ text: "An error occurred. Please try again.", type: "error", layout: "topCenter", timeout: 6000 });
            await resetCardField(payments);
            jQuery(".ct-loading-main-complete_booking").hide(); // ✅ Hide loader
        });
    } else {
        console.error("Tokenization failed:", result.errors);
        noty({ 
            text: "Card validation failed. Please enter your card details again.",
            type: "error", layout: "topCenter", timeout: 6000
        });

        jQuery(".ct-loading-main-complete_booking").hide(); // ✅ Hide loader on validation failure
    }
} catch (error) {
    console.error("Unexpected error:", error);
    noty({ text: "An unexpected error occurred. Please try again.", type: "error", layout: "topCenter", timeout: 6000 });
    jQuery(".ct-loading-main-complete_booking").hide(); // ✅ Hide loader on unexpected error
}

});

Backend code
$paymentRequest = new CreatePaymentRequest(
$token,
uniqid(), // Idempotency key
);

Questions:

  1. Why does tokenize() get triggered multiple times?
  2. How can I ensure that tokenization occurs only once per payment attempt?

Please check the attached images.
Any guidance would be greatly appreciated!


:waving_hand: I’m Square Dev AI, here to help answer your question!
Based on the information you’ve provided, the following documentation will help answer your question:

Additional Documentation

Create a Card on File and a Payment
Payment API: Process Online and In-Person Payments
Use a Gift Card (Orders and Payments Integration)

If this documentation helped you find a solution, please check the box indicating that this reply solves the problem.
Otherwise one of our Developer Advocates will provide additional assistance shortly.

Are you allowing the button to be pushed more then once? Ideally once the button submits the information it should freeze till the response comes back :slight_smile: