Adding a step to the Onepage Checkout

本文介绍如何在Magento中增加自定义结账步骤,例如收集特殊配送说明。文章详细讲解了修改核心文件、创建新的模板文件及调整布局配置等步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


链接地址:http://www.fontis.com.au/blog/magento/adding-step-onepage-checkout

The default Magento onepage checkout includes six steps for the customer to complete. However, sometimes you may have a requirement to create an extra checkout step. An example of this might be an option for your customer to choose a free gift as part of their order, or an extra step to collect special delivery instructions. Using delivery instructions as an example, we'll demonstrate how this can be achieved.

The first file we need to modify is app/code/core/Mage/Checkout/Block/Onepage.php. Obviously we don't want to modify the code in the core context, so copy the file to app/code/local/Mage/Checkout/Block/Onepage.php. Magento will use this file automatically.

In the getSteps() method of this class there is an array of the step codes, in order of viewing. We need to add our own step code in this array, in the relevant place. For this example, the code will be deliveryinstructions so we will change the line to be this:

$stepCodes = array('billing', 'shipping', 'shipping_method', 'deliveryinstructions', 'payment', 'review');

Next, we need to create a new file - app/code/local/Mage/Checkout/Block/Onepage/Deliveryinstructions.php. As you can see from the name, this is the block file that runs our new step. You can use this class to do any special setup work for your block, but more than likely all you'll need is this:

<?php
class Mage_Checkout_Block_Onepage_Deliveryinstructions extends Mage_Checkout_Block_Onepage_Abstract
{
    protected function _construct()
    {
        $this->getCheckout()->setStepData('deliveryinstructions', array(
            'label'     => Mage::helper('checkout')->__('Delivery Instructions'),
            'is_show'   => $this->isShow()
        ));
        parent::_construct();
    }
}

Now we need to make the actual template. The file we need is: <THEME DIRECTORY>/template/checkout/onepage/deliveryinstructions.phtml. Often the best way to create this file is to copy one of the other files, perhaps billing.phtml or shipping.phtml. Then, just modify the file to suit your needs.

With the template created, we need to tell Magento about it by editing the <THEME DIRECTORY>/layout/checkout.xml file. This will tell Magento when to load our new template file. Below the multishipping sections in this file the <checkout_onepage_index> context begins. Look through it until you find the references to the login, billing, shipping, shipping method, payment and review templates. These are all inside the content reference area. At the position between all these files that you want your step to show, you need to add a reference to your new template. It should look something like this:

<block type="checkout/onepage_deliveryinstructions" name="checkout.onepage.deliveryinstructions" as="deliveryinstructions" template="checkout/onepage/deliveryinstructions.phtml"/>

Following on from that, we need to override the onepage controller to put in our extra step. How to actually override a controller is beyond the scope of this post, however the Magento wiki article on overriding controllers should tell you everything you need to know.

There are two parts we need to work with in our overridden controller, and the first one is the save<STEP>Action method for the step before ours. In this example, I'm putting my new step between the Shipping Method step and the Payment Method step, so I'm going to override the saveShippingMethodAction method. We need to change the goto_section in the method to be our new step, so it should look like this:

$result['goto_section'] = 'deliveryinstructions';

We also need to remove the following code, as we don't need to update our delivery instructions section. We will need the code again for the next part, so keep it handy:

$result['update_section'] = array(
        'name' => 'payment-method',
        'html' => $this->_getPaymentMethodsHtml()
);

The next change to this controller should be to add a new method, called saveDeliveryinstructionsAction. This method must perform two functions; it should call the method on the Onepage Model, and also pass any data back to the browser. The following code is an example of what we need, copied and modified from the saveShippingMethodAction method:

public function saveDeliveryinstructionsAction()
{
	$this->_expireAjax();
	if ($this->getRequest()->isPost()) {
		$data = $this->getRequest()->getPost('deliveryinstructions', '');
		$result = $this->getOnepage()->saveDeliveryinstructions($data);
		/*
		$result will have error data if shipping method is empty
		*/
		if(!$result) {
			Mage::dispatchEvent('checkout_controller_onepage_save_deliveryinstructions', array('request'=>$this->getRequest(), 'quote'=>$this->getOnepage()->getQuote()));
			$this->getResponse()->setBody(Zend_Json::encode($result));

			$result['goto_section'] = 'payment';
			$result['update_section'] = array(
			    'name' => 'payment-method',
			    'html' => $this->_getPaymentMethodsHtml()
			);

		}
		$this->getResponse()->setBody(Zend_Json::encode($result));
	}
}

In the last step we called a method that we haven't defined yet, so we'll do that now. This method is in the app/code/core/Mage/Checkout/Model/Type/Onepage.php file. Like the past few files, we are going to modify the saveShippingMethod method and also copy it to a new method. The saveShippingMethod code should be modified to look like this:

public function saveShippingMethod($shippingMethod)
{
    if (empty($shippingMethod)) {
        $res = array(
            'error' => -1,
            'message' => Mage::helper('checkout')->__('Invalid shipping method.')
        );
        return $res;
    }
    $rate = $this->getQuote()->getShippingAddress()->getShippingRateByCode($shippingMethod);
    if (!$rate) {
        $res = array(
            'error' => -1,
            'message' => Mage::helper('checkout')->__('Invalid shipping method.')
        );
        return $res;
    }
    $this->getQuote()->getShippingAddress()->setShippingMethod($shippingMethod);
    $this->getQuote()->collectTotals()->save();

    $this->getCheckout()
        ->setStepData('shipping_method', 'complete', true)
        ->setStepData('deliveryinstructions', 'allow', true);

    return array();
}

Unfortunately, there is no simple way to save the data that we collect. For example, information about a customer will be saved completely differently to shipping information like our delivery instructions; the delivery instructions will be saved differently again to how we would add a free gift to the order.

Because of this I won't show you any code for actually saving the data you've captured, though we may address this in a follow up post at a later date. The following code is the new method that does not save anything:

public function saveDeliveryinstructions($deliveryinstructions)
{
    // Save the data here

    $this->getCheckout()
        ->setStepData('deliveryinstructions', 'complete', true)
        ->setStepData('payment', 'allow', true);

    return array();
}

Next, we need to make a couple of JavaScript changes. These changes will be made in the <SKIN DIRECTORY>/js/opcheckout.js> file. In the Checkout class, we need to change the setShippingMethod method to go to the delivery information block, similar to the way we have in the files above. Then we need to make a setDeliveryinstructions method which will be exactly the same as the setShippingMethod method before we modified it.

There is a class further down in the file called ShippingMethod, inside of which is a method called nextStep. We need to change it as per the above method so that the step goes to the delivery instructions step rather than the payment step. Then, again like before, we need to copy the whole class and modify it so that it's now a DeliveryInstructions class, making sure to set the next step to be the payment step.

There is now one final requirement, which is to add in our step in the progress meter on the right side of the checkout. To do this we need to edit <THEME DIRECTORY>/template/checkout/onepage/progress.phtml. If you look at the file, you'll have a pretty good idea of how the template should be laid out and below is an example of what to add in for our example delivery instructions:

<?php if ($this->getCheckout()->getStepData('deliveryinstructions', 'is_show')): ?>
	<?php if ($this->getCheckout()->getStepData('deliveryinstructions', 'complete')): ?>
		<li>
			<h4 class="complete"><?php echo $this->__('Delivery Instructions') ?> <span class="separator">|</span> <a href="#deliveryinstructions" οnclick="checkout.accordion.openSection('opc-deliveryinstructions');return false;"><?php echo $this->__('Change') ?></a></h4>
			<div class="content">
				<!-- Here write code to display the data the customer enters -->
			</div>
		</li>
	<?php else: ?>
		<li>
			<h4><?php echo $this->__('Delivery Instructions') ?></h4>
		</li>
	<?php endif; ?>
<?php endif; ?>

We have now added a new step to our checkout and made it accessible in the same way as the rest of the checkout steps. Using this as a base, you can develop the concept further to provide additional information or options to the customer during checkout. Of course, too many steps will likely turn people away, so it's a matter of balancing the need to collect extra information with the need to make the checkout as quick and easy to complete as possible.


Magento Compatibility
Post originally written for Magento version:1.4.0.1
Tested with Magento versions:1.4.0.1

AI Overview Implementing selective checkout with checkboxes on a cart page typically involves allowing users to select specific items in their cart for purchase, rather than requiring them to purchase all items. This functionality is not a standard feature in most e-commerce platforms and usually requires custom development or the use of specialized plugins/apps. General Approach: Modify the Cart Template: Add a checkbox next to each item in the cart. Ensure the checkbox is linked to the specific product or line item. Handle User Selections: Use JavaScript to detect changes in checkbox states (checked/unchecked). When a checkbox is selected or deselected, update the cart's subtotal and potentially the items that will be included in the checkout process. Adjust the Checkout Process: When the user proceeds to checkout, ensure that only the items corresponding to the selected checkboxes are passed to the order. This may involve modifying the platform's core checkout logic or using hooks/filters provided by the platform. Platform-Specific Considerations: WooCommerce (WordPress): Requires custom code in functions.php or a custom plugin to add checkboxes, manage selections, and modify the checkout process. You might use AJAX to update the cart dynamically as selections are made. Shopify: Involves modifying theme files (e.g., cart-template.liquid, theme.js) to add checkboxes and JavaScript to handle the logic. This often requires familiarity with Liquid (Shopify's templating language) and JavaScript. Other Platforms: The specific implementation will vary based on the platform's architecture and extensibility options. It may involve similar approaches of template modification and custom code. Important Notes: Complexity: Implementing selective checkout can be complex and may require advanced coding skills. User Experience: Carefully consider the user experience implications of selective checkout to ensure it is intuitive and does not cause confusion. Testing: Thoroughly test the functionality to ensure that selected items are correctly processed and that no loopholes exist (e.g., refreshing the page causing issues with selected items). I want to achieve this selective checkbox function in my cart page. Im using woocommerce and woodmart theme. Please advice on what to do
07-30
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值