结账信息都已填写,点击 Place Order 后按钮变灰、加载图标一直不消失,这是 Magento 2 结账中很常见、也很容易误判的问题。页面转圈只是前端状态,真正原因可能是请求根本没发出、REST 接口返回异常、支付 SDK 没有回调,或者订单已经创建但前端没有收到成功跳转。
先看有没有网络请求
打开 Network,点击一次 Place Order,重点观察 payment-information、set-payment-information 或支付模块自定义接口。如果完全没有请求,查看 Console 中最早出现的 JavaScript 错误。RequireJS 依赖加载失败、mixin 返回值错误、Knockout 校验异常,都可能让 action 的 Promise 在发送请求前中断。
如果请求返回 400,展开响应 JSON。地址字段缺失、支付 method code 不一致、extension_attributes 结构错误都可能触发输入校验。如果返回 500,立刻按请求时间查看 var/log/exception.log、var/log/system.log 和 PHP-FPM 日志,不要只看浏览器里笼统的服务器错误。
确认订单到底有没有创建
用户多次点击或刷新页面前,先在后台按客户邮箱、购物车和时间查找新订单。也可以只读查询最近订单:
SELECT entity_id, increment_id, quote_id, state, status, created_at
FROM sales_order
WHERE quote_id = 12345
ORDER BY entity_id DESC;
如果订单已存在但页面仍在结账,问题位于成功响应、重定向或支付回调。此时让按钮重新可点可能造成重复订单。修复前要确保支付请求有幂等键,订单创建也能识别已提交的 quote。
第三方支付常卡在 Promise 和回调
很多支付模块在下单前执行 tokenization、3DS、设备指纹或风控。SDK 弹窗被 CSP 拦截、回调域名不允许、用户关闭验证窗口后没有 reject Promise,都会让 full-screen-loader 永久显示。查看 Console 的 CSP、跨域和未捕获 Promise 错误,并在支付模块日志中对照同一 transaction reference。
不要把 full-screen-loader.stopLoader() 加到任意位置当作修复。加载动画消失不代表下单链路恢复,反而可能让客户重复提交。正确做法是每条成功、失败、取消分支都明确 resolve 或 reject,并向用户返回可理解的错误。
排除 totals 与库存锁等待
接口长时间 pending 而不是立即报错时,检查数据库 processlist、库存 reservation、优惠规则和运费重新计算。复杂购物车在 place order 时会再次 collect totals;自定义 total collector 如果查询远程接口或重复保存 quote,会明显放大耗时。
SHOW FULL PROCESSLIST;
SHOW ENGINE INNODB STATUS\G
若只有高并发时卡住,重点查看行锁、外部支付超时和 PHP-FPM 工作进程是否耗尽。
验证修复不能只下一个普通订单。至少覆盖访客、登录客户、优惠券、不同配送方式、支付成功、支付拒绝和用户取消 3DS。每种路径都应恢复按钮状态,只创建一笔订单,并让 quote、支付交易和订单状态保持一致。

