En Magento, aunque disponenos de un tipo de producto virtual, no siempre se adapta del todo a nuestras necesidades.
Dado esto nos vemos obligados a modificar partes del core y del onepage checkout para poder quitar la dirección de envio de nuestras compras.

Como nunca es recomendable tocar el core,  todos los pasos que comentamos implican copiar los ficheros a code/local o crear un override.

Para empezar modificaremos app\code\core\Mage\Checkout\Block\Onepage.php donde eliminaremos el paso que nos sobra, es decir dirección de envío y método de envio.

public function getSteps()
 {
 $steps = array();
 if (!$this->isCustomerLoggedIn()) {
 $steps['login'] = $this->getCheckout()->getStepData('login');
 }
//$stepCodes = array('billing', 'shipping', 'shipping_method', 'payment', 'review');
 $stepCodes = array('billing', 'payment', 'review');
 foreach ($stepCodes as $step) {
 $steps[$step] = $this->getCheckout()->getStepData($step);
 }
 return $steps;
 }

 

El siguiente paso será modificar app\code\core\Mage\Checkout\controllers\OnepageController.php modficando dos partes.

Lo primero eliminando una línea

protected $_sectionUpdateFunctions = array(
 'payment-method' => '_getPaymentMethodsHtml',
 // 'shipping-method' => '_getShippingMethodsHtml',
 'review' => '_getReviewHtml',
 );

 

Lo segundo será quitar de saveBillingAction la opción que carga el paso de envío saltando directamente a pagar.

public function saveBillingAction()
 {
 if ($this->_expireAjax()) {
 return;
 }
 if ($this->getRequest()->isPost()) {
 //$postData = $this->getRequest()->getPost('billing', array());
 //$data = $this->_filterPostData($postData);
 $data = $this->getRequest()->getPost('billing', array());
 $customerAddressId = $this->getRequest()->getPost('billing_address_id', false);
 if (isset($data['email'])) {
 $data['email'] = trim($data['email']);
 }
 $result = $this->getOnepage()->saveBilling($data, $customerAddressId);
 if (!isset($result['error'])) {
 /* check quote for virtual */
 if ($this->getOnepage()->getQuote()->isVirtual()) {
 $result['goto_section'] = 'payment';
 $result['update_section'] = array(
 'name' => 'payment-method',
 'html' => $this->_getPaymentMethodsHtml()
 );
 }
 /*elseif (isset($data['use_for_shipping']) && $data['use_for_shipping'] == 1) {
 $result['goto_section'] = 'shipping_method';
 $result['update_section'] = array(
 'name' => 'shipping-method',
 'html' => $this->_getShippingMethodsHtml()
 );
 $result['allow_sections'] = array('shipping');
 $result['duplicateBillingInfo'] = 'true';
 }*/
 else {
 //$result['goto_section'] = 'shipping';
 $result['goto_section'] = 'payment';
 }
 }
 $this->getResponse()->setBody(Mage::helper('core')->jsonEncode($result));
 }
 }

 

El siguiente fichero a editar será \app\code\core\Mage\Sales\Model\Service\Quote.php donde quitaremos la validación de la dirección de envío.

protected function _validate()
 {
 $helper = Mage::helper('sales');
 if (!$this->getQuote()->isVirtual()) {
 /*$address = $this->getQuote()->getShippingAddress();
 $addressValidation = $address->validate();
  if ($addressValidation !== true) {
  Mage::throwException(
 $helper->__('Please check shipping address information. %s', implode(' ', $addressValidation))
 );
 }
  $method= $address->getShippingMethod();
 $rate = $address->getShippingRateByCode($method);
 if (!$this->getQuote()->isVirtual() && (!$method || !$rate)) {
 Mage::throwException($helper->__('Please specify a shipping method.'));
 */}
 }

 

Ahora eliminaremos el radio button de "usar dirección de facturación como dirección de envío" modificando la plantilla
app\design\frontend\default\template\persistent\checkout\onepage\billing,phtml
o
app\design\frontend\default\template\checkout\onepage\billing,phtml

Finalmente quitaremos el envio del progreso del carrito en nuestra plantilla
app\design\frontend\default\template\checkout\onepage\progess,phtml

No hay que olvidar modificar también los correos automáticos, ya sea desde el administrador o desde app\locale\es_ES\template\email\sales\order_new.html