
Overview
To tell whether a Magento 2 order has been paid, look at Total Due on the order, not at the status label.
An order can display a payment-pending status while Total Due reads 0.00, because the status label reflects the last state the payment method recorded in Magento, while Total Due reflects the amounts Magento has actually invoiced.
The key point: When the status label and the totals disagree, the totals are the reliable one.
This matters most for orders created in the admin and paid through an emailed payment link, because those orders often take a different route through the payment integration than a normal storefront checkout.
The Three Places to Look, in Order
1. The Order Totals
Compare Total Paid, Total Refunded, and Total Due.
Total Due of 0.00 means Magento has recorded full payment. A non-zero Total Due with no invoice means Magento has recorded nothing, whatever the gateway shows.
2. The Invoices Tab
Magento treats an invoice as the record of captured money. No invoice means no recorded payment, and it also means the order contributes nothing to sales reporting.
This is why a paid order can leave the dashboard showing zero revenue for the day.
3. The Comments History
Payment integrations write gateway responses and webhook callbacks here. A successful capture normally leaves a comment naming the transaction.
Silence in this section, when the gateway dashboard shows a completed charge, points at the callback never arriving.
Why an Admin-Created Order Behaves Differently
Storefront checkout and an emailed payment link are two different flows.
The customer completes the payment on the gateway's page, and the gateway then has to tell Magento about it, usually through a webhook or a callback URL. If that webhook is not configured, is pointed at the wrong environment, or is being blocked before it reaches Magento, the money moves and Magento never hears about it. The order sits at pending payment indefinitely.
A useful diagnostic: if storefront orders are updating correctly and only admin-created orders are stuck, the problem is in the mapping for that specific flow, not in the gateway integration as a whole.
After a Platform or Payment Module Upgrade
Upgrades are the most common trigger.
A payment module update can change:
- The callback URL
- The webhook event names it subscribes to
- The payment method code that the admin order form uses
If stuck orders start appearing on a datable boundary that matches a deployment, compare the payment method code recorded on a working order with the one on a stuck order before looking anywhere else.
Also check that the webhook endpoint registered at the gateway points at your production store and not at a staging environment cloned from it. Cloned environments inheriting production webhook configuration is a classic way to lose confirmations quietly.
Reconciling an Order That Really Was Paid
Once you have confirmed at the gateway that the money was taken:
- Capture the payment in Magento so an invoice exists. Use the capture mode that matches reality: if the gateway already holds the funds, an offline capture records the invoice without asking the gateway to take the money a second time.
- Confirm Total Due drops to 0.00.
- Confirm the order now appears in sales reporting for its date.
Reconcile the orders you already have, then fix the callback, or you will be reconciling the same way next week.
Do Not Train Your Team on the Status Label
Status labels are configurable, and payment methods set them for their own reasons.
A team that reads "pending" as "unpaid" will chase customers who have already paid. Teach one rule instead: check Total Due.
If the gateway confirms payment, tell the customer their payment went through and that the order status on their side will catch up. Never ask for a second payment while the two systems disagree. A duplicate charge costs far more in trust than a late status update.
FAQs
Why does my Magento order say pending payment when it has been paid?
The status label reflects what the payment method recorded, not the money. Check Total Due.
Where do I see if a Magento order is paid?
The order totals block. Total Due of 0.00 means paid in full.
Why is my dashboard revenue zero when orders came in?
Magento's sales reports count invoiced amounts. Uninvoiced orders contribute nothing.
Why are only my manually created orders affected?
Admin-created orders paid by link use a different payment path from storefront checkout, so the gateway callback for that path can fail on its own.
Should I capture online or offline?
Offline, when the gateway already holds the funds. Online capture asks the gateway to take the money again.
Next Steps
To stop this recurring:
- Teach the team to read Total Due, not the status label
- Reconcile the existing backlog by capturing so invoices exist
- Verify the gateway webhook points at production, not a clone
- Re-test the admin payment-link flow after every payment module update
- Watch for uninvoiced orders as a standing report, not a customer complaint
