订单能在后台打开,付款看起来也成功,却找不到“创建发票”按钮。按钮不是由订单状态标签简单控制的,Magento 最终会调用订单的 canInvoice()。只要其中一个条件不满足,界面就不会显示。
先确认订单是不是已经被自动开票
进入 Invoices 标签,看是否已有发票。很多网关配置 Capture 时,会在回调成功后自动创建发票;管理员再找按钮属于重复操作。对照每个 order item 的 qty_ordered、qty_invoiced 和 qty_canceled,剩余可开票数量为零时按钮本来就不该出现。
状态标签正常,不代表内部state允许开票
自定义 status 可以挂在错误的 state 下。页面显示“已付款”只是文本,内部如果是 canceled、closed、holded 或 payment review,canInvoice() 仍会返回 false。用订单 ID 对照 sales_order 的 state/status,并检查是否处于 hold 或支付审核。
SELECT entity_id, increment_id, state, status,
total_qty_ordered, total_invoiced
FROM sales_order
WHERE increment_id = '000000123';
不要直接在数据库里把 state 改成 processing。订单、支付、发票和库存是一组状态机,手改一列可能让按钮出现,却留下金额和交易记录不一致。
Payment Action决定什么时候生成发票
Authorize Only 通常保留后续 Capture;Authorize and Capture 往往由支付模块自动开票。第三方网关若在回调里只改订单状态、没有正确登记 transaction 或 invoice,也会产生“看似支付成功但不能开票”的半状态。
查看 payment additional_information、authorization transaction 和网关回调日志,确认是否还有可捕获金额。退款、部分开票和虚拟商品也要分别计算,不要只看 grand_total。
定位时我会在测试环境记录 canInvoice() 返回前各项条件,而不是用插件强行让按钮显示。修复支付回调或订单状态映射后,新订单应能按预期自动开票或显示按钮;旧订单则需要按真实交易状态做数据修复。最终拿全新订单测试,避免历史脏数据让结论失真。

