Apple Pay Web JS支付未完成问题:onValidateMerchant执行后触发onCancel且事件执行顺序异常
问题根源分析
你遇到的核心问题是事件绑定时机错误:你在调用session.begin()启动Apple Pay会话之后,才给ApplePaySession实例绑定各类事件回调。而begin()方法会立即触发支付流程的初始化,这时候那些事件还没被注册,导致后续的onpaymentmethodselected、onpaymentauthorized根本不会被触发,最终流程直接进入oncancel。
从你的日志也能看出端倪:onpaymentmethodselected和onpaymentauthorized的打印在onvalidatemerchant之前,这是因为你在绑定这些事件的代码块里直接执行了printMessage,但实际的事件回调函数根本没被注册到会话上——当支付流程走到对应阶段时,没有回调可执行,自然就触发了取消逻辑。
修复方案
你需要调整代码顺序:先给ApplePaySession绑定所有事件回调,再调用session.begin()启动会话。这样当支付流程触发对应事件时,回调函数已经准备就绪,可以正常执行。
修改后的代码如下:
applePayButton.addEventListener("click", function(){ const request = { countryCode: 'US', currencyCode: 'USD', merchantCapabilities: [ 'supports3DS' ], supportedNetworks: [ 'visa', 'masterCard', 'amex', 'discover' ], lineItems: [{ label: 'Amount', amount: 0.95, }, { label: 'Tax', amount: 0.05, } ], total: { label: 'Total', amount: 10, } }; var session = new ApplePaySession(10, request); // 1. 先绑定所有事件回调 try{ session.onvalidatemerchant = function(event){ printMessage("starting session.onvalidatemerchant" + JSON.stringify(event)); var promise = performValidation(event.validationURL); promise.then(function(merchantSession) { printMessage("Merchant Session: "+ JSON.stringify(merchantSession)); session.completeMerchantValidation(merchantSession); }); } } catch(error){ printMessage("On Validate Merchant Error: " + error) } try{ session.onpaymentmethodselected = function(event) { printMessage("In On Payment Method Selected"); const update = {}; session.completePaymentMethodSelection(update); }; printMessage("onpaymentmethodselected callback registered"); } catch(error){ printMessage("On Payment Method Selected Error: " + error) } try{ session.onpaymentauthorized = function(event) { printMessage("starting session.onpaymentauthorized"); var applePaymentToken = event.payment.token; printMessage("Token: " + JSON.stringify(applePaymentToken)); // 转成字符串才能看到具体内容 session.completePayment(session.STATUS_SUCCESS); }; printMessage("onpaymentauthorized callback registered"); } catch(error){ printMessage("On Payment Authorized Error: " + error) } try{ session.oncancel = function(event) { printMessage("starting session.oncancel" + JSON.stringify(event)); }; } catch(error){ printMessage("On Cancel Error: " + error) } // 2. 最后启动会话 session.begin(); });
额外提示
- 我把你原来直接打印的
onpaymentmethodselected改成了onpaymentmethodselected callback registered,避免和事件实际触发的打印混淆; - 打印
applePaymentToken时加上了JSON.stringify,不然直接打印对象会显示[object Object],看不到具体的token内容。
内容的提问来源于stack exchange,提问作者Dev Team
相关产品推荐
相关产品推荐

