Square Web Payments SDK: card.tokenize() freezes with verificationDetails (Japan 3DS)

Hello,

I’m integrating the Web Payments SDK into a custom payment method for an EC-CUBE (PHP) online store in Japan. Since April 2025, Strong Customer Authentication (3D Secure) is legally required for card payments in Japan, so I added verificationDetails to the card.tokenize() call.

Problem: After adding verificationDetails, clicking the payment confirmation button causes the screen to dim and freeze for 60+ seconds with no response — no 3DS modal/popup ever appears, and there are no errors in the browser console.

What I’ve already ruled out:

  • Reproduces identically in Chrome, Edge (InPrivate), and on a separate mobile device/network — not a browser extension or local network issue
  • No JavaScript errors in the console
  • Tried both unformatted (1030) and formatted (“1030.00”) amount strings — no change
  • No Content-Security-Policy header is set on the page that could be blocking the 3DS iframe/popup
  • Location ID and amount are consistent between the client-side verificationDetails and the server-side charge request (verified by code review)

What works: Without verificationDetails (i.e., card.tokenize() with no argument), the same flow completes successfully and the card is charged (confirmed on production, order #1082, ¥1,030).

Environment:

  • Application ID: sq0idp-AeukhKBVotQ-MR1sBnIbZw
  • Location ID: LJVCXJA3W3RT0
  • Web Payments SDK (latest, loaded from Square’s CDN)

Question: Is 3D Secure/SCA correctly enabled for this Location? What else could cause tokenize() to hang indefinitely (not error out, not time out) specifically when verificationDetails is supplied?

Any guidance would be appreciated.

Passing verificationDetails to card.tokenize() is the documented card payment flow, but I can’t confirm your location’s 3DS configuration from this post.

Could you share your verificationDetails object, the surrounding tokenize() code, and any pending or unsuccessful requests in the browser’s Network tab during the freeze? Remove credentials, payment tokens, and personal/card data before sharing.

Thank you for looking into this. Here is the code around `tokenize()`, with personal data replaced by Twig template placeholders (this is server-rendered HTML, so in the actual browser the placeholders are replaced with the real customer’s name/address/etc., but no credentials or tokens are involved here):

```javascript
// Called when the customer clicks the order-confirm button
if (payment == ‘14’) { // ‘14’ = Square payment method
$(‘#square-payment-errors’).text(‘’);
if (!window.squareCard) {
$(‘#square-payment-errors’).text(‘Card field is not ready yet.’);
return;
}
try {
const tokenResult = await window.squareCard.tokenize(getSquareVerificationDetails());
if (tokenResult.status === ‘OK’) {
$(‘#square_nonce_field’).val(tokenResult.token);
} else {
$(‘#square-payment-errors’).text(‘Please check your card details.’);
return;
}
} catch (err) {
$(‘#square-payment-errors’).text(‘An error occurred while processing your card.’);
return;
}
}
```

```javascript
// Square Web Payments SDK init (sandbox during testing)
const payments = window.Square.payments(‘{{ square_application_id }}’, ‘{{ square_location_id }}’);
const card = await payments.card();
await card.attach(‘#square-card-container’);
window.squareCard = card;

// Builds the verificationDetails object passed to tokenize()
function getSquareVerificationDetails() {
function val(id, fallback) {
var el = document.getElementById(id);
return (el && el.value) ? el.value : fallback;
}
var amount = Math.round(parseFloat(orderPaymentTotal) || 0);
return {
amount: amount.toFixed(2), // e.g. “1030.00”
currencyCode: ‘JPY’,
intent: ‘CHARGE’,
customerInitiated: true,
billingContact: {
familyName: val(‘customer-name01’, orderName01),
givenName: val(‘customer-name02’, orderName02),
email: val(‘customer-email’, orderEmail),
phone: val(‘customer-phone_number’, orderPhoneNumber),
addressLines: [
val(‘customer-addr01’, orderAddr01),
val(‘customer-addr02’, orderAddr02)
],
state: val(‘customer-pref’, orderPref),
countryCode: ‘JP’,
postalCode: val(‘customer-postal_code’, orderPostalCode)
}
};
}
```

Notes on what we’ve already confirmed:

  • Without `verificationDetails` (i.e. a plain `card.tokenize()` call with no argument), the payment completes successfully end-to-end (we confirmed a real production charge, order #1082, ¥1,030, on 2026-10-30).
  • The freeze only started after we added `verificationDetails` for 3DS.
  • Application ID: `sq0idp-AeukhKBVotQ-MR1sBnIbZw`, Location ID: `LJVCXJA3W3RT0`.
  • Reproduced consistently across Chrome, Edge (InPrivate), and a phone on a separate network/connection, so it doesn’t look environment-specific.
  • No JavaScript errors appear in the browser console when it freezes.

We will capture the Network tab during an actual freeze and follow up with that separately, since it requires reproducing the issue live.