title: Magento change shipping rate in one page checkout for COD
body: <p>My question is quite simple. I need to change the shipping rate cost in one page checkout to "0" once the user select COD as payment method in one page checkout. I think I can do this easely with an observer. Could you please helpme to know what event should I observe?.</p>
  
  <p>Can I use checkout_controller_onepage_save_shipping_method ?. Any kind of help will be highly appreciated!!</p>
  
  <p><strong>Details Posted By OP as answer</strong></p>
  
  <p>I override the Mage_Checkout_Model_Type_Onepage class and modify the savePayment method. Then I did this:</p>
  
  <p>1.- A first try:</p>
  
  <pre><code>public function savePayment($data)
  {
  .....
  ....
  $payment = $quote-&gt;getPayment();
  $payment-&gt;importData($data);
  $quote-&gt;save();
  
  //My custom code
  if($data['method']=='cashondelivery'){
          $shipping = $quote-&gt;getShippingAddress();
          $address = $quote-&gt;getBillingAddress();
          $shipping-&gt;addData($address)-&gt;setShippingMethod('flatrate_flatrate');
      }
  </code></pre>
  
  <p>Where my flatrate_flatrate is 0. Unfortunately it doesn't work well. This snippet set to 0 my Grant Total.</p>
  
  <p>My second try was:</p>
  
  <pre><code>public function savePayment($data)
  {
  .....
  ....
  $payment = $quote-&gt;getPayment();
  $payment-&gt;importData($data);
  $quote-&gt;save();
  
  //My custom code
  if($data['method']=='cashondelivery'){
          $this-&gt;getQuote()-&gt;getShippingAddress()-&gt;setShippingAmount(0);
          $this-&gt;getQuote()-&gt;getShippingAddress()-&gt;setBaseShippingAmount(0);
      }
  </code></pre>
  
  <p>This code works but only a few times, I don't understand why ??.. Could somebody helpme to fix this please?.  Any kind of help will be highly appreciated. </p>
  
  <p>Kind regards!</p>
  
  <hr>
  
  <p>Ok. Now I have this and it works but it doesn't update the grand total amount. Even the order is processed with the normal shipping cost. I mean, finally it doesn't update anything. Could somebody in someway give me a hand on this please?.</p>
  
  <pre><code>     if($data['method']=='cashondelivery'){
          $quote-&gt;getShippingAddress()-&gt;setShippingMethod('flatrate_flatrate');
          $quote-&gt;getShippingAddress()-&gt;setShippingAmount(0);
          $quote-&gt;getShippingAddress()-&gt;setBaseShippingAmount(0);
          $quote-&gt;getShippingAddress()-&gt;setShippingInclTax(0);
          $quote-&gt;getShippingAddress()-&gt;setBaseShippingInclTax(0);
          $quote-&gt;collectTotals(); 
          $quote-&gt;save();
      }
  </code></pre>
  
  <p>Warming regards!</p>
  
  <hr>
  
  <p>Ok, I did something crazy but it seems it works (at least partially). I override Mage_Checkout_OnepageController too and add it a new method call actualizaShippingMethodAction. </p>
  
  <p>It looks like this:</p>
  
  <pre><code>public function actualizaShippingMethodAction()
  {
      if ($this-&gt;_expireAjax()) {
          return;
      }
      if ($this-&gt;getRequest()-&gt;isPost()) {
          $data = $this-&gt;getRequest()-&gt;getPost('shipping_method', '');
          $result = $this-&gt;getOnepage()-&gt;saveShippingMethod($data);
          // $result will contain error data if shipping method is empty
          if (!$result) {
              $this-&gt;getOnepage()-&gt;getQuote()-&gt;collectTotals();
          }
          $this-&gt;getOnepage()-&gt;getQuote()-&gt;collectTotals()-&gt;save();
      }
  }
  </code></pre>
  
  <p>Now in my original class that is overriding (Mage_Checkout_Model_Type_Onepage) I did this.</p>
  
  <pre><code>if($data['method']=='cashondelivery'){
          $cliente = new Varien_Http_Client();
          $_configuracion = array('maxredirects'=&gt;5, 'timeout'=&gt;30);
          $llamada = Mage::getBaseUrl()."checkout/onepage/actualizaShippingMethod/";
          $cliente-&gt;setUri($llamada)
          -&gt;setConfig($_configuracion)
          -&gt;setMethod(Zend_Http_Client::POST)
          -&gt;setParameterPost('shipping_method','flatrate_flatrate');
  
          $respuesta = $cliente-&gt;request();
          $quote-&gt;getShippingAddress()-&gt;setShippingAmount(0);
          $quote-&gt;getShippingAddress()-&gt;setBaseShippingAmount(0);
          $quote-&gt;getShippingAddress()-&gt;setShippingInclTax(0);
          $quote-&gt;getShippingAddress()-&gt;setBaseShippingInclTax(0);
          $quote-&gt;collectTotals()-&gt;save();
      }
  
      $this-&gt;getCheckout()
          -&gt;setStepData('payment', 'complete', true)
          -&gt;setStepData('review', 'allow', true);
  
      return array();
  </code></pre>
  
  <p>Now the order is passing without shipping cost as spected but the order review (summary) is not updating the final costs. And I thinks this solution has a bug because if the user returns and select another payment method the shipping cost is 0 again. </p>
  
  <p>Any kind of help, whatever, will be highly, highly appreciated</p>
  
  <p>THANKS </p>