I’m attempting to integrate Apple Pay with the existing Web Payments SDK, and I’m facing an issue.
Sandbox Application ID: sandbox-sq0idb-Cy6QuV_eqqgldwD2kwrABQ
Location ID: 733JJPMXQA97X
Apple Merchant ID: merchant.io.applova.square.733JJPMXQA97X
I have added my Sandbox Domain and have verified it.
When attempting to make the payment, the Apple Pay Payment dialog pops up. When biometric authorisation is given, then I see a “Payment not completed” message on the Apple Pay pop-up, and it dismisses automatically.
{
function loadSquareSdkAndInitApplePay(sdkUrl, applicationId, locationId) {
debugLog(‘Loading Square Web Payments SDK from: ’ + sdkUrl, ‘info’);
var script = document.createElement(‘script’);
script.src = sdkUrl;
script.onload = function() {
debugLog(‘Square Web Payments SDK loaded successfully’, ‘info’);
initializeSquareApplePay(applicationId, locationId);
};
script.onerror = function() {
debugLog(‘Failed to load Square Web Payments SDK’, ‘error’);
var wrapper = document.querySelector(’.apple-pay-button-wrapper’);
if (wrapper) { wrapper.style.display = ‘none’; }
};
document.head.appendChild(script);
}
function initializeSquareApplePay(applicationId, locationId) {
debugLog('Initializing Square Apple Pay - AppId: ' + applicationId + ', LocationId: ' + locationId, 'info');
var requestId = $('#apple-pay-request-id').val();
var amount = parseFloat($('#apple-pay-amount').val());
var currency = $('#apple-pay-currency').val();
var tipAmount = parseFloat($('#apple-pay-tip').val() || '0');
var subTotal = parseFloat($('#apple-pay-subtotal').val() || amount.toString());
var completeUrl = $('#apple-pay-complete-url').val();
var billingRequiredVal = $('#apple-pay-billing-address-required').val();
var billingRequired = billingRequiredVal === 'true' || billingRequiredVal === true;
debugLog('Square Apple Pay params — requestId: ' + requestId + ', amount: ' + amount
+ ', currency: ' + currency + ', tip: ' + tipAmount + ', subTotal: ' + subTotal, 'info');
if (applicationId && applicationId.indexOf('sandbox-') === 0) {
debugLog('⚠️ SANDBOX mode detected (appId starts with "sandbox-"). '
+ 'Apple Pay requires Apple Pay sandbox test cards — real cards will show "payment not completed". '
+ 'Add sandbox tester cards via Apple Developer portal to test end-to-end.', 'warn');
}
if (!window.Square) {
debugLog('Square SDK not available after load — hiding Apple Pay button', 'error');
var wrapper = document.querySelector('.apple-pay-button-wrapper');
if (wrapper) { wrapper.style.display = 'none'; }
return;
}
var payments;
try {
payments = Square.payments(applicationId, locationId);
debugLog('Square.payments() initialized', 'info');
} catch (e) {
debugLog('Failed to initialize Square.payments(): ' + e.message, 'error');
var wrapper = document.querySelector('.apple-pay-button-wrapper');
if (wrapper) { wrapper.style.display = 'none'; }
return;
}
var lineItems = [];
if (subTotal > 0) {
lineItems.push({ label: 'Subtotal', amount: subTotal.toFixed(2), pending: false });
}
if (tipAmount > 0) {
lineItems.push({ label: 'Tip', amount: tipAmount.toFixed(2), pending: false });
}
var paymentRequestConfig = {
countryCode: 'US',
currencyCode: currency,
lineItems: lineItems,
total: { label: 'Total', amount: amount.toFixed(2), pending: false }
};
debugLog('Square paymentRequest config: ' + JSON.stringify(paymentRequestConfig), 'info');
var squarePaymentRequest = payments.paymentRequest(paymentRequestConfig);
var squareApplePay = null;
payments.applePay(squarePaymentRequest).then(function(applePay) {
squareApplePay = applePay;
debugLog('Square applePay instance ready — showing button', 'info');
var wrapper = document.querySelector('.apple-pay-button-wrapper');
if (wrapper) { wrapper.style.display = 'block'; }
// Define the global startApplePaySession so the button onclick calls it
window.startApplePaySession = function() {
var billingModal = document.getElementById('apple-pay-billing-modal');
if (billingModal && billingRequired) {
debugLog('Billing address required — showing modal before Square Apple Pay', 'info');
pendingApplePayBilling = null;
$('#apple-pay-billing-address').val('');
$('#apple-pay-billing-zip').val('');
$('#apple-pay-billing-address-error').text('');
$('#apple-pay-billing-zip-error').text('');
$('#apple-pay-billing-address').removeClass('billing-input-error');
$('#apple-pay-billing-zip').removeClass('billing-input-error');
$('#apple-pay-billing-modal').addClass('is-visible').css('display', 'flex');
return;
}
triggerSquareApplePay(squareApplePay, completeUrl, requestId);
};
// Wire the billing modal submit button to continue to Square tokenization
window.beginApplePaySession = function() {
triggerSquareApplePay(squareApplePay, completeUrl, requestId);
};
}).catch(function(e) {
debugLog('Square applePay() not available: ' + e.message, 'warn');
var wrapper = document.querySelector('.apple-pay-button-wrapper');
if (wrapper) { wrapper.style.display = 'none'; }
});
}
function triggerSquareApplePay(squareApplePay, completeUrl, requestId) {
debugLog('Triggering Square Apple Pay tokenization...', 'info');
// NOTE: Do NOT show the processing overlay before tokenize() on mobile.
// Showing a full-page overlay before the Apple Pay sheet can interfere with
// the user gesture chain and cause the sheet to be dismissed immediately.
// The overlay is shown only after the user authorizes (status OK).
squareApplePay.tokenize().then(function(tokenResult) {
// Log the full result — this is our primary diagnostic tool
try {
debugLog('Square tokenize() full result: ' + JSON.stringify(tokenResult), 'info');
} catch (jsonErr) {
debugLog('Square tokenize() status: ' + tokenResult.status + ' (could not serialize full result)', 'info');
}
if (tokenResult.status === 'OK') {
debugLog('Square Apple Pay authorized — showing processing overlay', 'info');
$('#processing-view').show();
$('.overlay').show();
var requestData = { squareNonce: tokenResult.token };
if (pendingApplePayBilling) {
requestData.billingAddress = pendingApplePayBilling.address;
requestData.billingZip = pendingApplePayBilling.zip;
pendingApplePayBilling = null;
}
debugLog('Sending Square nonce to backend: ' + completeUrl, 'info');
sendSquareApplePayNonce(completeUrl, requestData);
} else if (tokenResult.status === 'Cancel') {
// User dismissed the Apple Pay sheet — restore UI without an error message
debugLog('Apple Pay sheet dismissed (status: Cancel) — restoring UI', 'info');
$('#processing-view').hide();
$('.overlay').hide();
} else {
// Actual tokenization failure — extract every detail Square provides
debugLog('Square tokenize() error — status: ' + tokenResult.status, 'error');
$('#processing-view').hide();
$('.overlay').hide();
var errMsg = 'Apple Pay failed. Please try again.';
if (tokenResult.errors && tokenResult.errors.length > 0) {
tokenResult.errors.forEach(function(err, idx) {
debugLog(' Error[' + idx + '] field: ' + (err.field || 'n/a')
+ ' | type: ' + (err.type || 'n/a')
+ ' | message: ' + (err.message || 'n/a'), 'error');
});
errMsg = tokenResult.errors[0].message || errMsg;
} else {
debugLog(' No error details provided by Square SDK for status: ' + tokenResult.status, 'warn');
}
showError(errMsg, true);
}
}).catch(function(e) {
debugLog('Square tokenize() threw an exception: ' + (e.message || e), 'error');
if (e.stack) {
debugLog('Exception stack: ' + e.stack, 'error');
}
$('#processing-view').hide();
$('.overlay').hide();
var msg = (e.message || '').toLowerCase();
if (msg.indexOf('cancel') !== -1 || msg.indexOf('dismiss') !== -1) {
debugLog('Apple Pay cancelled (surfaced as exception)', 'info');
} else {
showError('Apple Pay failed. Please try again.', true);
}
});
}
function sendSquareApplePayNonce(completeUrl, requestData) {
var xhr = new XMLHttpRequest();
xhr.open('POST', completeUrl, true);
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.timeout = 30000;
xhr.onload = function() {
debugLog('Square Apple Pay completion response - HTTP ' + xhr.status, 'info');
var response = null;
try { response = JSON.parse(xhr.responseText); } catch (e) { /* non-JSON */ }
if (xhr.status >= 200 && xhr.status < 300 && response && response.status === 'success') {
debugLog('Square Apple Pay payment successful — redirecting', 'info');
$('#processing-view').hide();
$('.overlay').hide();
$('#apple-pay-billing-modal').removeClass('is-visible').css('display', 'none');
window.location.href = response.redirectUrl;
} else {
debugLog('Square Apple Pay payment failed', 'error');
$('#processing-view').hide();
$('.overlay').hide();
var msg = (response && response.error) ? response.error : 'Payment failed. Please try again.';
showError(msg, true);
}
};
xhr.onerror = function() {
$('#processing-view').hide();
$('.overlay').hide();
showError('Network error. Please check your connection and try again.', true);
};
xhr.ontimeout = function() {
$('#processing-view').hide();
$('.overlay').hide();
showError('Request timed out. Please try again.', true);
};
xhr.send(JSON.stringify(requestData));
}
}
Front End Logs:
[12:06:29 AM] [INFO] Digital Wallet module loaded
[12:06:29 AM] [INFO] Debug log panel found: yes
[12:06:29 AM] [INFO] Debug log content found: yes
[12:06:29 AM] [INFO] Running in regular browser (not WebView)
[12:06:29 AM] [INFO] Platform: iPad
[12:06:29 AM] [INFO] isSimulator() result: false
[12:06:29 AM] [INFO] Checking Apple Pay availability… Provider: squareup
[12:06:29 AM] [INFO] Checking Apple Pay availability…
[12:06:29 AM] [INFO] ApplePaySession API found (Safari)
[12:06:29 AM] [INFO] ApplePaySession.canMakePayments() = true
[12:06:29 AM] [INFO] User Agent: Mozilla/5.0 (iPad; CPU OS 26_3_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) CriOS/142.0.7444.128 Mobile/15E148 Safari/604.1
[12:06:29 AM] [INFO] isWebView() result: true
[12:06:29 AM] [INFO] ReactNativeWebView available: false
[12:06:29 AM] [INFO] webkit.messageHandlers available: true
[12:06:29 AM] [WARN] Apple Pay: Running in WebView - Apple Pay may be restricted by Apple security policies
[12:06:29 AM] [INFO] Square provider: loading Square Web Payments SDK for Apple Pay
[12:06:29 AM] [INFO] Loading Square Web Payments SDK from: https://sandbox.web.squarecdn.com/v1/square.js
[12:06:29 AM] [INFO] Google Pay initialization starting (non-digital-wallet page)…
[12:06:29 AM] [INFO] Environment: PRODUCTION
[12:06:29 AM] [INFO] User Agent: Mozilla/5.0 (iPad; CPU OS 26_3_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) CriOS/142.0.7444.128 Mobile/15E148 Safari/604.1
[12:06:29 AM] [INFO] isWebView() result: true
[12:06:29 AM] [INFO] ReactNativeWebView available: false
[12:06:29 AM] [INFO] webkit.messageHandlers available: true
[12:06:29 AM] [INFO] WebView detected: true
[12:06:29 AM] [INFO] Platform: iPad
[12:06:29 AM] [INFO] isSimulator() result: false
[12:06:29 AM] [INFO] Simulator detected: false
[12:06:29 AM] [INFO]
Google Pay JS API loaded successfully
[12:06:29 AM] [INFO] Testing Google Pay in simulators:
[12:06:29 AM] [INFO] - Android Emulator: Requires Google Play Services and test account
[12:06:29 AM] [INFO] - iOS Simulator: Use Chrome browser, may have limitations
[12:06:29 AM] [INFO] - Best practice: Test on real devices for production
[12:06:29 AM] [INFO] Initializing Google Pay…
[12:06:29 AM] [INFO] Google Pay config - RequestId: 69f1ad01e60a3f0d9d95396e, Amount: 6.36, Currency: USD, Tip: 0, SubTotal: 6.36, Type: GATEWAY, Environment: PRODUCTION
[12:06:29 AM] [INFO] Google Pay Type: GATEWAY - Using payment gateway tokenization
[12:06:29 AM] [WARN]
Google Pay Merchant ID is missing. Google Pay will not be available.
[12:06:29 AM] [INFO] Square Web Payments SDK loaded successfully
[12:06:29 AM] [INFO] Initializing Square Apple Pay - AppId: sandbox-sq0idb-Cy6QuV_eqqgldwD2kwrABQ, LocationId: 733JJPMXQA97X
[12:06:29 AM] [INFO] Square Apple Pay params — requestId: 69f1ad01e60a3f0d9d95396e, amount: 6.36, currency: USD, tip: 0, subTotal: 6.36
[12:06:29 AM] [WARN]
SANDBOX mode detected (appId starts with “sandbox-”). Apple Pay requires Apple Pay sandbox test cards — real cards will show “payment not completed”. Add sandbox tester cards via Apple Developer portal to test end-to-end.
[12:06:29 AM] [INFO] Square.payments() initialized
[12:06:29 AM] [INFO] Square paymentRequest config: {“countryCode”:“US”,“currencyCode”:“USD”,“lineItems”:[{“label”:“Subtotal”,“amount”:“6.36”,“pending”:false}],“total”:{“label”:“Total”,“amount”:“6.36”,“pending”:false}}
[12:06:29 AM] [INFO] Square applePay instance ready — showing button
[12:06:36 AM] [INFO] Triggering Square Apple Pay tokenization…
[12:06:45 AM] [INFO] Square tokenize() full result: {“status”:“Cancel”}
[12:06:45 AM] [INFO] Apple Pay sheet dismissed (status: Cancel) — restoring UI
The device we are using is a Sandbox Account. And we have added Test Cards from Apple.
There’s no other information on why the payment doesn’t go through.
Please assist.