PayPal ACDC提交无回调:postMessage目标源无效问题求助
解决PayPal ACDC cardFields.submit无回调且postMessage origin错误的问题
问题根源
这个错误Uncaught DOMException: Failed to execute 'postMessage' on 'Window': Invalid target origin 'null',本质是页面在**本地文件协议(file://)**下运行导致的。PayPal Hosted Fields依赖浏览器跨域通信机制,本地file协议页面的origin为null,无法满足postMessage对有效目标源的要求,进而导致submit后的Promise回调(then/catch)无法正常触发。
解决方案
切换到HTTP/HTTPS环境运行页面
本地开发时必须用HTTP服务器托管页面,比如:- Node.js环境:安装
http-server后执行http-server ./启动 - Python环境:Python3执行
python -m http.server 8000,Python2执行python -m SimpleHTTPServer 8000 - 使用Vue CLI、Create React App等框架的内置开发服务器
- Node.js环境:安装
修复createOrder函数实现
代码中createOrder直接返回<order-id>是占位符,必须替换为实际的服务器端逻辑——订单必须通过后端创建,不能前端硬编码:createOrder: function() { // 调用后端接口生成PayPal订单ID return fetch('/api/create-paypal-order', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ amount: '10.00' }) // 替换为实际订单金额 }).then(res => res.json()).then(data => data.orderId); }额外排查项
- 确认PayPal脚本从官方CDN加载(如
<script src="https://www.paypal.com/sdk/js?client-id=你的客户端ID&components=hosted-fields"></script>) - 检查
#card-number、#cvv等字段容器是否存在,选择器是否正确 - 确保页面没有启用严格的CSP策略拦截PayPal跨域通信
- 确认PayPal脚本从官方CDN加载(如
修正后的核心代码示例
if (paypal.HostedFields.isEligible()) { paypal.HostedFields.render({ createOrder: function () { // 替换为实际后端订单创建接口 return fetch('/api/create-paypal-order', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ amount: '10.00' }) }).then(res => res.json()).then(data => data.orderId); }, styles: { '.valid': { 'color': 'green' }, '.invalid': { 'color': 'red' }, 'input': { 'box-sizing': 'border-box', 'width': '100%', 'height': '46px', 'margin-top': '8px', 'background': '#EBEBEB', 'border-radius': '6px', 'font-style': 'normal', 'font-weight': '400', 'font-size': '18px', 'line-height': '18px', 'color': '#333', 'padding-left': '10px', }, }, fields: { number: { selector: "#card-number", placeholder: "XXXX XXXX XXXX XXXX" }, cvv: { selector: "#cvv", placeholder: "XXX" }, expirationDate: { selector: "#expiration-date", placeholder: "MM/YY" } } }).then(function (cardFields) { document.querySelector("#card-form").addEventListener('submit', (event) => { event.preventDefault(); cardFields.submit({ cardholderName: document.getElementById('card-holder-name').value, billingAddress: { streetAddress: document.getElementById('card-billing-address-street').value, extendedAddress: document.getElementById('card-billing-address-unit').value, region: document.getElementById('card-billing-address-state').value, locality: document.getElementById('card-billing-address-city').value, postalCode: document.getElementById('card-billing-address-zip').value, countryCodeAlpha2: document.getElementById('card-billing-address-country').value } }).then(function () { console.log("CHECKOUT_SUCCESS") }).catch(function (error) { console.error("CHECKOUT_ERROR", error) }); }); }); } else { document.querySelector("#card-form").style = 'display: none'; }
内容的提问来源于stack exchange,提问作者Amit Chauhan
相关产品推荐
相关产品推荐

