Developing a seamless checkout experience is one of the most critical tasks for any Magento or Adobe Commerce developer. However, there is a recurring frustration: the order success page. By default, Magento clears the checkout session as soon as the page loads. If you try to refresh the page to check a CSS change or debug a tracking pixel, you are immediately redirected back to an empty cart.

Constantly placing new orders just to see a single UI change is a massive waste of time. In this guide, we will explore several methods to keep the order success page active, allowing you to style and test efficiently in both Magento 1 and Magento 2.

Why Magento Redirects You to the Cart

Magento uses a session-based validator to ensure that the success page is only visible immediately after a successful transaction. Once the page is rendered, the checkout/session is cleared of the order data. This is a security and user-experience feature designed to prevent users from accidentally refreshing and seeing sensitive order details or triggering multiple conversion events.

To bypass this for development, we need to prevent the session from clearing or manually re-injecting order data into the session.

Method 1: Testing in Magento 1 (Legacy Projects)

If you are still maintaining a Magento 1 store, the logic resides in the OnepageController.php. You can temporarily modify the core (or preferably create a local override) to stop the session from clearing.

Disabling Session Clearing

Navigate to /app/code/core/Mage/Checkout/controllers/OnepageController.php and locate the successAction(). Comment out the line that clears the session:

public function successAction()
{
    $session = $this->getOnepage()->getCheckout();
    // ... validation logic ...

    // $session->clear(); // Comment this out to keep the page active

    $this->loadLayout();
    $this->renderLayout();
}

Manually Injecting Order IDs

If you want to view the success page for a specific historical order without placing a new one at all, you can manually set the IDs in the session. First, find an entity_id and quote_id from your sales_flat_order table.

Then, modify the beginning of the successAction():

$session = $this->getOnepage()->getCheckout();

// Replace these with real IDs from your database
$session->setLastSuccessQuoteId(12345);
$session->setLastQuoteId(12345);
$session->setLastOrderId(67890);

Method 2: Testing in Magento 2 (Adobe Commerce)

In Magento 2, the logic is handled by the Success controller and a SuccessValidator. There are two main ways to handle this: the quick hack and the professional plugin approach.

The Quick Hack (Development Only)

Open vendor/magento/module-checkout/Controller/Onepage/Success.php. You will see a block of code that checks if the session is valid. If you comment this out, the redirect will stop:

/* 
if (!$this->_objectManager->get('Magento\Checkout\Model\Session\SuccessValidator')->isValid()) {
    return $this->resultRedirectFactory->create()->setPath('checkout/cart');
}
*/

Additionally, you should comment out the line that clears the quote to ensure the data persists across refreshes:

// $session->clearQuote();

Note: After making these changes, you will need to place one last order to "prime" the session. After that, you can refresh as much as you like.

The Professional Approach: Using a Plugin

Modifying vendor files is never recommended. Instead, you can create a small development module that uses an interceptor (plugin) to inject a specific order ID into the session via a URL parameter, such as checkout/onepage/success?order=1000001.

In your module's etc/frontend/di.xml:

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
  <type name="Magento\Checkout\Controller\Onepage\Success">
    <plugin name="dev_debug_success_page" type="Vendor\Module\Plugin\SuccessPlugin" sortOrder="10" />
  </type>
</config>

In your plugin class SuccessPlugin.php:

public function afterExecute(\Magento\Checkout\Controller\Onepage\Success $subject, $result)
{
    $orderIncrementId = $subject->getRequest()->getParam('order');
    if ($orderIncrementId) {
        $this->_checkoutSession->setLastRealOrderId($orderIncrementId);
        // Additional logic to load the order and dispatch events
    }
    return $result;
}

Testing Order Confirmation Emails

Styling the success page is only half the battle; you often need to style the order confirmation email as well. Instead of actually sending emails (which can be slow or blocked on local environments), you can dump the email HTML directly to a file.

In Mage_Core_Model_Email_Template::send(), you can add a snippet to catch the processed template:

$text = $this->getProcessedTemplate($variables, true);
$filePath = Mage::getBaseDir() . DS . 'email_debug.html';
file_put_contents($filePath, $text);

Now, every time an order is placed or an admin clicks "Send Email," the full HTML output will be saved to your Magento root as email_debug.html, which you can open directly in your browser.

Frequently Asked Questions

Why does my success page show no order information after refreshing?

Even if you stop the redirect, the block responsible for displaying the order number (Magento\Checkout\Block\Onepage\Success) relies on the session's last_real_order_id. If the session has already been cleared once, the block will find nothing. You must ensure you comment out the session clearing code before placing the order you intend to use for testing.

Is it safe to leave these changes in production?

Absolutely not. These modifications bypass security checks that prevent users from viewing session data. Always use a dedicated development environment or wrap your logic in a check for Magento\Framework\App\State::MODE_DEVELOPER.

Can I use a third-party extension for this?

Yes, there are several developer toolkits and "Checkout Tester" extensions available (such as those from Yireo) that provide a dedicated UI for previewing success pages for any order ID. These are excellent for QA teams who may not want to touch the code.

Wrapping Up

Styling the Magento order success page doesn't have to be a repetitive cycle of adding items to the cart and checking out. By temporarily disabling the SuccessValidator in Magento 2 or commenting out $session->clear() in Magento 1, you can freeze the page in place.

For a more robust workflow, consider building a small debug plugin that allows you to view any order's success page via a URL parameter. This keeps your core files clean and your development process fast.

Key Takeaways:

  • Magento 1: Disable $session->clear() in OnepageController.php.
  • Magento 2: Disable the SuccessValidator check in Success.php or use a Plugin.
  • Email Testing: Intercept the email template and write the HTML to a local file for instant preview.
  • Security: Never deploy these session-clearing bypasses to a live production environment.