Magento – Magento, programmatical checkout not including shipping rates

checkoutmagento-1onepage-checkoutshipping-methodstotals

I'm trying to write this script to checkout using the cart. The problem is that the shipping rates aren't being factored into the totals and when the order goes through the order details say there is no shipping method available.
Thanks for taking a look.

PROBLEM UPDATE

First time I run this, I get:

Fatal error: Uncaught exception 'Mage_Core_Exception' with message
'Please check shipping address information. Please enter the first
name. Please enter the last name. Please enter the street. Please
enter the city. Please enter the telephone number. Please enter the
zip/postal code. Please enter the country.' in /vagrant/app/Mage.php
on line 594

refresh the page again and order goes through with rates and everything. Can someone fix/explain that for me?

<?php
ini_set('display_errors', 1);
error_reporting(E_ALL);
$_SERVER['MAGE_IS_DEVELOPER_MODE'] = true;
require_once 'app/Mage.php';
Mage::app();

$_customer = Mage::getModel('customer/customer');
Mage::register('isSecureArea', true);
if ($_customer->getCollection()->getLastItem()->getemail() == 'test@test.com') {
    $_customer->getCollection()->getLastItem()->delete();
};
Mage::unregister('isSecureArea');

$_customer = Mage::getModel('customer/customer');
$_customer_session = Mage::getSingleton('customer/session');
$_checkout_session = Mage::getSingleton('checkout/session');
$_checkout_cart =  Mage::getSingleton('checkout/cart');
$_checkout_page = Mage::getSingleton('checkout/type_onepage');
$_sales_address = Mage::getSingleton('sales/quote_address');
$_customer_address = Mage::getModel('customer/address');
$_catalog_products = Mage::getModel('catalog/product');

$_customer->setWebsiteId(1)
    ->setEmail('test@test.com')
    ->setFirstname('Emma')
    ->setLastname('Peel')
    ->setPassword('password')
    ->setGender(1)
    ->setConfirmation(null)
    ->save();

$_customer_session->loginById($_customer->getId());

$address = array(
    'firstname' => 'Emma',
    'lastname' => 'Peel',
    'city' => 'Portland',
    'region' => 'Oregon',
    'postcode' => '97214',
    'country_id' => 'US',
    'telephone' => '0038531555444',
    'region_id' => '49',
    'street' => array(
      '0' => '501 SE 14th Ave'),
);

$_customer_address->setData($address)
    ->setCustomerId($_customer->getId())
    ->setIsDefaultBilling('1')
    ->setIsDefaultShipping('1')
    ->setSaveInAddressBook('1')
    ->save();

$_checkout_session->getQuote()
    ->setBillingAddress($_sales_address->importCustomerAddress($_customer_address))
    ->setShippingAddress($_sales_address->importCustomerAddress($_customer_address));

$_checkout_cart->init();
$_checkout_cart->addProduct(634887, array('qty' => $qty));
$_checkout_cart->save();
$_checkout_session->setCartWasUpdated(true);

$shippingAddress = $_checkout_session->getQuote()->getShippingAddress();
$shippingAddress->setCollectShippingRates(true)->setShippingMethod('flatrate_flatrate');
$shippingAddress->collectShippingRates();
$rates = $shippingAddress->getShippingAmount();
echo "rates = " . $rates;

$_checkout_session->getQuote()->collectTotals()->save();

$_checkout_page->initCheckout();
$_checkout_page->saveCheckoutMethod('register');
$_checkout_page->getQuote()->getShippingAddress()->setShippingMethod('flatrate_flatrate');
$_checkout_page->savePayment(array('method'=>'checkmo'));
$_checkout_page->saveOrder();

print '</br>';
print $_checkout_page->getQuote()->getGrandTotal();

//clean up 
Mage::register('isSecureArea', true);
Mage::getModel('customer/customer')->getCollection()->getLastItem()->delete();
Mage::unregister('isSecureArea');
//logout the customer
$_customer_session->logout();
// //clear the checkout session
$_checkout_session->clear();
$_checkout_session->resetCheckout();
// //empty the cart
$_checkout_cart->truncate();
$_checkout_cart->save();
$_checkout_cart->getItems()->clear()->save();

echo 'hate hate hate hate hate magento';

UPDATE:

Ok, this is my first question so let me try to do this right. I've updated the code so if it is copied into a file in the root directory of a magento project it can be run in a browser by going to the magento url / filename. Also I realize that I could achieve a checkout using the sales/service_quote model, but orders from this code are being created in the DB.

Best Answer

If you follow your written procedure as a human using the interface. Does the rate show up with the correct information? Is that user able to use that rate? Are the rate settings correct?

To me it looks like your trying to replicate the checkout process which might not be your way to go. Can you tell me some more about where and how you try to run this code? Custom module, template file, php file in root etc. Be as specific as possible when asking questions here. I ran your code and it doesn't work at all on my end as i expected. There are some odd things going on. I suggest you take a good look at a working example. I found this article, now the article itself doesn't have the example. i'm talking about but one of the commentors who posted a really nice example which you can run from your root directory. I tested it on magento 1.9.1 with sample data and it works like a charm.

The developers at Inchoo write really good articles like this one: http://inchoo.net/magento/programmatically-create-order-in-magento/

Following the code which works in my demo shop. I'm sure if you look closely at this you'll solve your problem. Just let me know if you get stuck again. Good luck ;)

//these lines are required to run this php file from root. If you include it somewhere within magento you won't need it.
require_once 'app/Mage.php';
Mage::app();

//set the store
$quote = Mage::getModel('sales/quote')
    ->setStoreId(Mage::app()->getStore('default')->getId());

//load a customer or go for guest, known or unknown customer it works
if ('do customer orders') {
    // for customer orders:
    $customer = Mage::getModel('customer/customer')
        ->setWebsiteId(1)
        ->loadByEmail('customerrr@example.com');
    $quote->assignCustomer($customer);
} else {
    // for guesr orders only:
    $quote->setCustomerEmail('customerrr@example.com');
}

// add product(s)
$product = Mage::getModel('catalog/product')->load(231);
$buyInfo = array(
    'qty' => 1,
    // custom option id => value id
    // or
    // configurable attribute id => value id
);
$quote->addProduct($product, new Varien_Object($buyInfo));

$addressData = array(
    'firstname' => 'Test',
    'lastname' => 'Test',
    'street' => 'Sample Street 1000',
    'city' => 'Somewhere',
    'postcode' => '123456789',
    'telephone' => '123456789',
    'country_id' => 'US',
    'region_id' => 12, // id from directory_country_region table
);

//set shipping and billing address
$billingAddress = $quote->getBillingAddress()->addData($addressData);
$shippingAddress = $quote->getShippingAddress()->addData($addressData);

//get and set methods
$shippingAddress->setCollectShippingRates(true)->collectShippingRates()
    ->setShippingMethod('flatrate_flatrate')
    ->setPaymentMethod('checkmo');


$quote->getPayment()->importData(array('method' => 'checkmo'));

$quote->collectTotals()->save();

$service = Mage::getModel('sales/service_quote', $quote);
$service->submitAll();
$order = $service->getOrder();

//these lines are required to run this php file from root. If you include it somewhere within magento you won't need it.
require_once 'app/Mage.php';
Mage::app();

//set the store
$quote = Mage::getModel('sales/quote')
    ->setStoreId(Mage::app()->getStore('default')->getId());

//load a customer or go for guest, known or unknown customer it works
if ('do customer orders') {
    // for customer orders:
    $customer = Mage::getModel('customer/customer')
        ->setWebsiteId(1)
        ->loadByEmail('customerrr@example.com');
    $quote->assignCustomer($customer);
} else {
    // for guesr orders only:
    $quote->setCustomerEmail('customerrr@example.com');
}

// add product(s)
$product = Mage::getModel('catalog/product')->load(231);
$buyInfo = array(
    'qty' => 1,
    // custom option id => value id
    // or
    // configurable attribute id => value id
);
$quote->addProduct($product, new Varien_Object($buyInfo));

$addressData = array(
    'firstname' => 'Test',
    'lastname' => 'Test',
    'street' => 'Sample Street 1000',
    'city' => 'Somewhere',
    'postcode' => '123456789',
    'telephone' => '123456789',
    'country_id' => 'US',
    'region_id' => 12, // id from directory_country_region table
);

//set shipping and billing address
$billingAddress = $quote->getBillingAddress()->addData($addressData);
$shippingAddress = $quote->getShippingAddress()->addData($addressData);

//get and set methods
$shippingAddress->setCollectShippingRates(true)->collectShippingRates()
    ->setShippingMethod('flatrate_flatrate')
    ->setPaymentMethod('checkmo');


$quote->getPayment()->importData(array('method' => 'checkmo'));

$quote->collectTotals()->save();

$service = Mage::getModel('sales/service_quote', $quote);
$service->submitAll();
$order = $service->getOrder();

printf("Created order %s\n", $order->getIncrementId());
Related Topic