Web Payments specific help

Hi all — reposting here per Square Support (case #120571149), since this needs Web Payments SDK-specific help rather than general account support.

Environment: Web Payments SDK, production, App ID sq0idp-TlA8WMXpfx-qcPhJlDgXuA, Location ID LE8PYM3ATV635.

Symptom: Clicking the Apple Pay button produces an immediate tokenize() result of {status: “Cancel”}. No payment sheet ever appears, not even briefly. No error is thrown anywhere. Network tab shows only small Square telemetry “beacon” requests to pci-connect (squareup) — no actual validate-merchant request ever fires. Google Pay and Cash App Pay both work correctly through the same integration, same checkout page, same App ID.

Already ruled out: no card in Apple Wallet; domain verification (confirmed “Verified” in the Developer Dashboard, file downloaded and inspected directly — valid); sandbox/production mismatch; www vs. non-www; a second wallet button physically overlapping and intercepting the click; Safari’s own site permissions; Touch ID/Apple Pay activation at the OS level; swapping to a second Location ID under the same App ID (identical failure on both, ruling out anything location-specific); ApplePaySession.canMakePayments() returns true directly in the browser; rebuilt the click handler using a native DOM onclick assignment rather than a framework’s event system, with tokenize() called as the first operation with no async work before it, matching your own documented Apple Pay pattern exactly — no change in behavior.

What we haven’t been able to verify ourselves: payments.paymentRequest() doesn’t expose merchantCapabilities or supportedNetworks as configurable options (confirmed against the official PaymentRequestOptions reference in your Web Payments SDK docs) — so these must be generated internally by the SDK. We have no visibility into what values are actually being generated for this specific App ID, or whether they’re valid.

Instrumented session output — see below:

[APPLEPAY] session constructed — {version: 3, supportedNetworks: [“visa”, “masterCard”, “jcb”, …], merchantCapabilities: [“supports3DS”], …}

[APPLEPAY] onshippingcontactselected property set

[APPLEPAY] oncancel property set

[APPLEPAY] onvalidatemerchant property set

[APPLEPAY] onpaymentauthorized property set

[APPLEPAY] begin() called

Nothing fires after begin() — including oncancel. The request itself is well-formed (Visa is included in supportedNetworks, standard merchantCapabilities). All handlers are registered correctly before begin() runs, and begin() throws no error. But no native session event of any kind is ever dispatched, even after waiting several seconds.

Despite this, our application’s tokenize() call still eventually resolves with {status: “Cancel”} — which, given oncancel itself never fires, suggests that resolution isn’t coming from the native session’s own callback at all, but from some other internal mechanism in the SDK.

Would appreciate any insight into what could cause begin() to produce no native session response whatsoever, or where Square’s SDK might independently resolve tokenize() as cancelled without oncancel ever actually firing.

One more note: we attempted to independently verify card eligibility via ApplePaySession.canMakePaymentsWithActiveCard(), but this requires the actual Apple Pay merchant identifier tied to this account — which, since Square manages the Apple Pay merchant relationship on our behalf rather than us holding our own Apple Developer merchant account, isn’t something we have access to or any way to look up ourselves. If there’s a way to obtain this, or if someone on Square’s side could run this check directly, that would help rule this in or out definitively.

@govcondev could you provide more details around how you are implementing apple pay on the page? Here is our guide on how to do it: Take an Apple Pay Payment . You can also find the full example code here: web-payments-quickstart/public/examples/apple-pay.html at main · square/web-payments-quickstart · GitHub

Thanks for the resources — I reviewed the guide and the example code directly and compared it against our implementation line by line. One structural difference stood out: your example’s Apple Pay button lives inside a element and explicitly calls event.preventDefault() (since an unhandled submit-type button inside a form would trigger a page navigation). I confirmed our checkout page has no element anywhere, so that specific difference doesn’t apply to us.

Here’s our actual implementation, for reference:

Initialization (matches your example’s shape closely — payments.applePay(paymentRequest), no attach() call):

javascript

const ap = await payments.applePay(paymentRequest)
if (mounted) {
appleInstance.current = ap
setAppleReady(true)
}

Click handler — wired via native element.onclick, not a framework’s event system, with tokenize() called first, no async work before it:

javascript

btn.onclick = async () => {
if (!appleInstance.current) return
const result = await appleInstance.current.tokenize()
setLoading(true)
onError(null)
await completePayment(result)
}

Button markup:

html

This matches your reference implementation in every structural way I can find. The specific behavior we’re still trying to explain: begin() is called successfully (confirmed via instrumentation, posted above), but no session event ever fires afterward — not even oncancel — and yet tokenize() still eventually resolves as cancelled in our own application code. Is there a scenario where begin() would produce no native session response at all?