
Reviewed and updated June 2026 — the lack of a native order-delete action and the invoice-counter reset verified on PrestaShop 1.7, 8 and 9.
The day before launch, your PrestaShop database is a crime scene of your own making. You placed orders to test the carrier prices, ran a card through the payment gateway twice to be sure, created "asdf asdf" to check the address form, and triggered every order status to watch the emails fire. All of that worked — which is exactly the problem. Every one of those test orders is now baked into your statistics, your invoice sequence, and your customer list, and on the first morning of real trading it will quietly lie to you about how the store is doing. This guide is about one specific job: removing test orders cleanly before you go live, on a store that has never taken a real order — because once genuine orders and invoices exist, deleting them is something PrestaShop deliberately makes hard, for legal and accounting reasons.
It is deliberately narrow. Cleaning carts, logs and connection tables for ongoing performance is a different routine — the difference between "I'm launching next week" and "my database has grown for two years" — and we keep them separate so you delete only what a launch actually requires.
Why a leftover test order is more expensive than it looks
Deleting an order feels cosmetic. It isn't. In PrestaShop an order is not one row — it's a small graph of rows spread across a dozen tables, several of which feed reports and counters you'll rely on from day one. Leave them in and here's what breaks, concretely:
- Your first revenue figure is wrong, and you can't tell. The dashboard and Stats pages sum ps_orders (and ps_order_detail) with no idea which rows were you testing carrier prices. Day-one revenue, average order value and conversion rate are all inflated by orders that never happened, so the one moment you most want a clean signal — "is the new store actually selling?" — is the moment your data is dirtiest.
- Your first real invoice is numbered #38. Invoice numbers in PrestaShop are assigned from a running counter, not from the order. Forty test orders that generated invoices consume forty numbers, so your accountant's first genuine invoice is a non-sequential mid-thirties number with thirty-seven invisible predecessors. That's the kind of gap a tax audit asks about.
- Your customer list is salted with ghosts. "Test User", "asdf asdf" and your own three throwaway accounts sit in ps_customer next to real people. Every segment, export and "number of customers" stat counts them. Export that list to an email tool and the test addresses — if you used real ones — get marketing mail.
- Stock moved for sales that never occurred. If your test orders were placed against real products with stock management on, each one wrote a row to ps_stock_mvt and decremented quantity. Delete the order badly and the stock movement stays, so your launch-day inventory is quietly off. (Reconciling that is a stock-data job in its own right — see inventory management when spreadsheets stop working.)
So what? A test order you forget to delete doesn't just clutter a screen — it corrupts the three things a launch is supposed to give you: an honest revenue number, a clean invoice sequence, and a customer list you can trust. Removing them is fifteen minutes of work that buys you a database you can actually read.
There is no clean "delete order" button — and why that matters

Here's the first surprise: native PrestaShop (1.7, 8, 9) does not give you a normal back-office action to delete an order. Orders are treated as financial records and are meant to be preserved for legal and accounting integrity, so the bulk-action and row menus you'll reach for simply don't offer a "Delete" the way the product or customer lists do. That's by design, not an oversight.
This is exactly why the only safe way to remove test orders is to do it before any real ones exist. Your realistic options are:
- Restore a clean pre-launch backup. The simplest and safest reset: take your snapshot from before you started testing and roll back to it. Everything below assumes you'd rather not, but this is the option with zero orphan-row risk.
- Work on a staging database. Test on a copy, then deploy a clean production database that never saw a test order in the first place.
- Use a dedicated order-cleanup module or script. Removing an order properly means walking the whole graph of related rows, which is why this belongs in a version-tested tool, not a hand-clicked admin action. Only run it on a store with zero real orders.
And even when an order is removed (by a module or by PrestaShop's own Order::delete() object logic), it never cleans up everything that orbits the order at one remove:
- The customer (ps_customer) and their addresses (ps_address) — removing an order never deletes the person who placed it. Your fake customers survive.
- The originating cart (ps_cart, ps_cart_product) — the cart that became the order is left behind as an "abandoned" cart.
- The invoice row (ps_order_invoice) and the invoice-number counter — removing the order does not roll back the number it consumed.
- Any stock movement (ps_stock_mvt) already written against real products.
So order removal is only the first step, not the whole job. The pattern that actually leaves you clean is: remove the orders on a pre-launch store, then delete their customers and carts, then set the next invoice number explicitly. Below is how to do each part deterministically.
The pre-launch cleanup, step by step
- Back up the database first — non-negotiable. Take a real database dump: your host's backup tool, phpMyAdmin or Adminer, or a
mysqldumpif you have shell access. (Note: SQL Manager under Advanced Parameters is for running saved queries against your data, not for taking a full backup — don't rely on it for this.) Order removal is destructive and there is no undo. If anything below surprises you, you restore and try again. - Make a definitive list of test order IDs. In Orders → Orders, sort by date and identify every order from before launch. Note the ID range — they're almost always a contiguous block at the start (1 to whatever). The trap here is a soft launch: if you took any genuine early orders, those IDs are mixed in with tests. List the real ones explicitly so you never delete a paying customer.
- Remove the orders. Because native PrestaShop has no back-office order-delete action, this is the step that needs a dedicated cleanup module or a small script calling
Order::delete()on each test ID — or, simplest of all, restoring your clean pre-launch backup instead. Only do this on a store with zero real orders. - Delete the test customers. Go to Customers → Customers, find the obviously fake accounts, and delete them — this also removes their addresses. Again, watch for soft-launch buyers you want to keep.
- Set the next invoice number explicitly to 1. Go to Orders → Invoices, and in Invoice options set Next available invoice number to
1— do this only on a store where no genuine invoice has ever been issued, and confirm no legal invoice sequence has already begun. (This sets the start number outright; don't expect setting it to0to "auto-start at 1.") Do the same for delivery-slip numbering if you tested deliveries (Orders → Delivery Slips). This is the step almost everyone forgets, and it's the one your accountant notices — but if real invoices already exist, leave the sequence alone and consult your accounting requirements instead. - Clear the cache. Advanced Parameters → Performance → Clear cache. Counters and list views are cached; without this the admin can still show stale totals.
- Verify against the numbers, not your memory. Open Orders → Orders (should be empty or only real soft-launch orders), Customers, and the dashboard. If revenue isn't zero (or your true soft-launch figure), something didn't delete — go back to your backup-and-list before you launch on dirty data.
When you have dozens of test orders: the SQL route
Clicking through fifty orders one at a time is tedious and error-prone. If you're comfortable in Advanced Parameters → Database → SQL Manager (which is fine for read-only investigation queries) you can at least scope the test data precisely — but, as the next section explains, the actual removal should go through tested code, not a hand-written DELETE. The reason is PrestaShop's schema: many tables don't have cascading foreign keys, so deleting a parent first orphans the children rather than removing them, and the full set of related tables is easy to under-count.
First, find the test orders so you're working from real IDs, not guesses. For example, everything placed before your launch date:
SELECT id_order, reference, total_paid, date_add FROM ps_orders WHERE date_add < '2026-06-13 00:00:00' ORDER BY id_order;
Strongly prefer letting PrestaShop's own Order::delete() handle the child rows (run it from a small script over your test IDs) rather than writing the deletion by hand. A real PrestaShop order touches far more than the obvious half-dozen tables — order details and history, but also order carriers, order messages, returns and slips, customizations, invoices, taxes, and ps_order_payment rows that are associated by order reference rather than a tidy id_order child link — plus whatever module-owned tables your install adds. That's precisely why a hand-written DELETE list is dangerous: any table you forget becomes an invisible orphan.
So this guide deliberately does not hand you a partial "delete these N tables in this order" SQL recipe — that recipe would be incomplete for almost any real store. Use the object logic (Order::delete()) or a version-tested cleanup script that enumerates every related table, including the payment rows it has to look up by reference. Then mop up the satellites — customers, carts, invoice counter — separately.
So what? Skipping a related table isn't pedantry — get it wrong and you leave invisible orphan rows that keep polluting reports while looking deleted in the admin. That's the exact failure mode this whole exercise is meant to prevent, and it's why we lean on tested code rather than a copy-paste SQL block.
One honest caveat: truncating the order tables (TRUNCATE ps_orders and friends) is the brute-force option you'll see suggested online. It's fast and it resets auto-increment IDs to 1 — appealing for a launch — but it bypasses every safeguard, doesn't touch the satellite tables, and will happily destroy a soft-launch order. Only consider it on a store with zero real data, and only with a backup you've confirmed restores.
Cleaning up demo data while you're in there
Test orders are the launch-blocker, but if you installed PrestaShop with demo data, the sample catalogue is its own pre-launch problem — and worth handling in the same session. Installed with demo data, PrestaShop may include sample products, categories, suppliers, brands and CMS pages (the "Delivery", "Legal Notice", "About us" placeholders) — exactly which ones varies by version, distribution and language. Leaving them risks two things: a real product accidentally sitting in a demo category, and Google indexing a "Terms and conditions" page that's still Lorem-ipsum boilerplate.
Remove or rewrite, in Catalog and Design → Pages: the demo products and categories, and the placeholder CMS pages (replace with your real legal text, don't just hide them). Do this through the back office or a controlled import process — don't hand-delete files under /img, which holds your live product, category, brand, supplier, theme and system images, not just demo ones. Removing the demo products through the BO clears their image records the safe way; if you then want to reclaim disk space, regenerate or prune unused images only with a backup in hand. If you're starting from a large demo catalogue and importing your real one, doing it cleanly via CSV is its own task — see product import and export in PrestaShop.
Prevention: stop creating the mess next time
You'll test again — for every theme change, payment-module update and PrestaShop upgrade. The goal is to make future testing leave no residue in your live data:
- Test on a staging copy, not the live store. A duplicate install where every test order, refund and status change happens off to the side. This is the single biggest win: your live ps_orders only ever contains real sales, so there's nothing to clean.
- Use sandbox mode for payments. Stripe, PayPal and most gateways offer a test/sandbox key that processes fake transactions with no real charge. Test the checkout flow without ever touching a live card — and remember to flip every gateway back to live mode before launch (a forgotten sandbox key is the mirror-image launch bug).
- Tag the unavoidable live test. If you must test against production, use a recognisable marker — a customer named
ZZ-TEST, a dedicated email pattern, a note in the order — so a single sortable filter surfaces every test row for deletion. The point of clearly-marked test orders ties into how you handle order states generally; if you find yourself testing status emails repeatedly, automating those transitions is covered in order status workflow customization and automation.
Frequently asked questions
How do I delete a test order in PrestaShop?
Native PrestaShop (1.7, 8, 9) has no back-office "Delete order" action — orders are treated as financial records and preserved by design. The only safe way to remove test orders is before any real ones exist: restore a clean pre-launch backup, deploy a staging database that never saw a test order, or run a version-tested cleanup module/script that calls Order::delete() over your test IDs. Back up the database first; order removal is destructive and there's no undo.
Why does my first real invoice start at number 38 instead of 1?
Invoice numbers come from a running counter, not from the order, so every test order that generated an invoice consumed a number. After clearing tests, go to Orders → Invoices → Invoice options and set Next available invoice number to 1 — but only on a store where no genuine invoice has ever been issued. Setting it to 0 does not "auto-start at 1"; set the start number outright. If real invoices already exist, leave the sequence alone.
Does deleting an order also remove the customer and cart?
No. Removing an order never deletes the person who placed it (ps_customer) or their addresses (ps_address), and the cart that became the order is left behind as an "abandoned" cart (ps_cart). It also doesn't roll back the invoice-number counter or any stock movement already written. So order removal is the first step, not the whole job — you then delete the test customers and carts and reset the counter separately.
Can I just run a DELETE query or TRUNCATE the order tables?
Avoid it. A real order touches far more than the obvious half-dozen tables — order details and history, carriers, messages, returns, slips, customizations, invoices, taxes, and ps_order_payment rows linked by order reference rather than id_order — plus module-owned tables. A hand-written DELETE that forgets one leaves invisible orphan rows that keep polluting reports while looking deleted. TRUNCATE is faster and resets IDs to 1, but bypasses every safeguard and will destroy a soft-launch order. Use Order::delete() or a tested cleanup script instead. A read-only SELECT to find the test IDs first is fine.
How do I avoid creating this mess next time?
Test on a staging copy, not the live store — then your live ps_orders only ever contains real sales. Use each gateway's sandbox/test mode for payment testing (and remember to flip every gateway back to live before launch). If you must test against production, tag the orders with a recognisable marker (a ZZ-TEST customer name or dedicated email pattern) so one sortable filter surfaces every test row for deletion.
Where this sits in the bigger picture
Deleting test orders is a one-time launch gate. The habits that keep an order database clean and trustworthy after launch are a separate, ongoing discipline — fixing the occasional real order that went out wrong via order editing, getting a confirmation back to a customer who lost theirs through resending order confirmations, pulling clean figures out for your accountant with CSV exports for orders and invoices, and the day-to-day routine that keeps it all moving in order management workflows that save you hours.
The principle for launch day is simple: the only orders in your database should be ones a customer actually placed. Get the test orders out — in the right order, with the invoice counter reset and the backup safely aside — and your store's first revenue number tells you the truth. After that, every clean report you read is a small reward for the fifteen minutes you spent now. If a tidy database and accurate statistics matter to how you run the shop, that's exactly the kind of behind-the-scenes reliability our PrestaShop modules are built to protect.
Comments
No comments yet. Be the first!
Be the first to ask a question or share useful feedback.
Leave a comment
Share a question, an installation detail, or feedback that could help another reader.