Post purchase

How to customise the WooCommerce thank you page

It is the only page on your store that every paying customer sees, and on most WooCommerce stores it is a table and a total. Here is what belongs on it, the hooks that put it there, and the tracking mistake that quietly doubles your reported conversions.

What this article covers

  • Every single buyer sees this page. It has a 100% view rate among the people who have already given you money, which no other page on your site can claim.
  • The job is answering "what happens now?" The default page does not, which is why the next thing most buyers do is email you asking.
  • The tracking trap is real. The main hook fires on every load of the URL, so a conversion pixel placed there double counts on a refresh.
  • You cannot preview it without an order. Which is why so many of these pages ship broken.

Why this page is worth an hour of your time

The order received page has a property nothing else on your site has: everyone who reaches it has already paid. There is no persuasion left to do, no bounce risk, and no competing call to action. You have the buyer's full attention at the single highest trust moment in the relationship, and the default WooCommerce page spends it on a table.

What the default gives you is accurate and joyless: "Thank you. Your order has been received", an order number, a date, a total, the payment method, and a summary table. Nothing false about it. It just answers the wrong question.

The buyer is not asking what they bought. They know what they bought, they chose it ten minutes ago. They are asking:

  • Did that actually work, or did I just pay twice?
  • When is it coming?
  • What happens next, and do I need to do anything?
  • Who do I contact if something is wrong?

Every one of those questions, unanswered, becomes a support email. This page is the cheapest support deflection you will ever build, and it happens to also be where repeat purchases start.

What to actually put on it

In priority order. The first three are the job; the rest are upside.

  1. Unambiguous confirmation. Large, clear, and above the fold on a phone. A tick, a heading, the order number. The buyer's first emotion after paying is mild anxiety, and your first job is to end it in under a second.
  2. What happens next, as a sequence. Not a paragraph, a short timeline: confirmation email sent, packed within one working day, dispatched with tracking, delivered in three to five days. This one block removes more support email than anything else on the page.
  3. When to expect delivery, as concretely as you honestly can. "Arriving between Tuesday and Thursday" is worth more than a tracking link that does not exist yet.
  4. How to get help, with a real route. An email address a human reads beats a contact form the buyer has to go and find.
  5. The account offer, now rather than earlier. "Create a password to track this order and reorder faster" converts far better here than as a wall in front of the payment button, because the buyer now has a concrete reason to want one.
  6. One reason to come back. A discount code for the next order, a related collection, or a referral offer. Exactly one, below everything above.

The order number deserves special treatment. Make it large and easy to copy. It is the one string the buyer will need if anything goes wrong, and it is usually rendered at body text size inside a table, which is where people fail to find it and email you instead.

What not to put on it

  • A second checkout. If you want a post purchase upsell, it belongs on a dedicated step before the receipt, not competing with the confirmation. A buyer who cannot tell whether their order went through will not buy again on the same screen. The offer that belongs before payment is a different mechanic, covered in WooCommerce order bumps that actually convert.
  • Your full site navigation, prominently. The buyer is done. Sending them back into the shop mid confirmation is how you get "did my order go through?" tickets.
  • A newsletter signup above the order details. Ask after you have answered their questions, or ask in the confirmation email.
  • Anything that implies the order is incomplete. Progress bars, "one more step", pending language for an order that is not pending. Buyers read these as failure.
  • Theme furniture that outranks the confirmation. On a lot of stores the theme drops a page title bar, breadcrumbs and a hero above the confirmation, so the first thing the buyer sees after paying is the word "Checkout" again. Look at your own page on a phone before assuming this is not you, and see why your WooCommerce checkout breaks on mobile for how to look properly.

The three ways to change it

1. Hooks, for adding to the default

The simplest route, and it survives WooCommerce updates. The main one runs inside the page with the order id:

add_action( 'woocommerce_thankyou', 'oc_next_steps', 20 );
function oc_next_steps( $order_id ) {
	$order = wc_get_order( $order_id );
	if ( ! $order ) { return; }

	echo '<h2>What happens next</h2>';
	echo '<ol class="oc-next">'
		. '<li>A confirmation email is on its way to ' . esc_html( $order->get_billing_email() ) . '</li>'
		. '<li>We pack your order within one working day</li>'
		. '<li>You get a tracking link the moment it ships</li>'
		. '</ol>';
}

Add a block to the order received page

Others worth knowing: woocommerce_before_thankyou for content above the confirmation, woocommerce_order_details_after_order_table for content under the summary, and woocommerce_thankyou_{gateway_id} when you need gateway specific instructions, such as bank transfer details for a direct deposit order.

2. A template override, for full control

Copy woocommerce/templates/checkout/thankyou.php to yourtheme/woocommerce/checkout/thankyou.php and edit it. Complete control, and the same drift trap as any other override: WooCommerce updates the original, your copy silently stays behind, and the only signal is the outdated templates list under WooCommerce, Status. Keep every do_action line you find in the original, because deleting one quietly disables other plugins, including your conversion tracking.

3. A plugin, when you want it designed rather than assembled

Worth it if you want a laid out page rather than blocks bolted onto the default. In OptiCheckout the thank you page is a designed surface with two layouts, a full width banded one and an editorial single column, plus a configurable "what happens next" timeline, a confirmation icon, a custom message and an optional reward code, all inheriting your checkout's brand colours. Whether that is worth paying for depends entirely on whether the hook route above already gets you what you want, and for a lot of stores it does.

The tracking trap that costs people real money

This is the section to read even if you skip the rest, because the failure is invisible and it corrupts the numbers you make decisions with.

woocommerce_thankyou fires on every load of that URL. Not once per order. If a buyer refreshes, hits back and forward, or opens the link again from their email, your conversion pixel fires again. Your ad platform now believes you got two orders. Your reported cost per acquisition halves, your return on ad spend looks great, and you scale spend on a number that is not real.

The fix is to make firing idempotent by recording that you already did it, on the order itself:

add_action( 'woocommerce_thankyou', 'oc_fire_conversion_once' );
function oc_fire_conversion_once( $order_id ) {
	$order = wc_get_order( $order_id );
	if ( ! $order ) { return; }

	// Already counted? Do nothing.
	if ( $order->get_meta( '_oc_conversion_fired' ) ) { return; }

	$order->update_meta_data( '_oc_conversion_fired', '1' );
	$order->save();

	// ... output your tracking snippet here, once ...
}

Fire a conversion tag exactly once per order

Two related things worth checking while you are in there:

  • Not every paid order reaches this page. Offline gateways, some redirect gateways and failed returns from a payment provider can all land the buyer elsewhere. If your revenue reporting depends entirely on this page, it is undercounting. Order status changes are the more reliable signal.
  • Check the page still fires your tags after any redesign. Analytics gaps are a well documented casualty of checkout changes, and the failure is silent. Verify the tag fires before you trust a fortnight of data.

How to test a page you cannot preview

The reason so many of these pages ship broken is simple: you cannot see it without placing an order, so people change it and assume.

  • Place a real order. Use a cheap product or a 100% coupon, go through a real gateway, then refund it. This is the only way to see what the buyer sees, including the theme furniture above your content.
  • Or open an existing order's received URL. WooCommerce builds it from the order id and order key, and as an admin you can load an existing order's confirmation page directly. Fast for design iteration, though it does not exercise the gateway return path.
  • Look at it on a phone, at the top of the page. Take a viewport screenshot at scroll position zero rather than a full page one. What you need to know is whether the confirmation is visible before any scrolling, and a full page screenshot is exactly the tool that cannot tell you.
  • Test a second payment method. Bank transfer and cash on delivery orders show different instructions, and those are the orders where the buyer most needs telling what to do next.
  • Refresh it once, and confirm your conversion tag did not fire twice.

See a designed confirmation page

OptiCheckout's thank you page is rendered from the real plugin in the demo below, including the what happens next timeline and the reward block. Open it on your phone and compare it with your own.