branko ajzele, senior developer / project manager

Posts / Articles

Programatically create customer and order in Magento with full blown One Page Checkout process under the hood

Its been a while since my last article. Figured I might write one before Google search punishes me :) -Recently I was working on a task that, among other things, required an order to be created programatically alongside with the customer and its billing and shipping address. Example I will demonstrate is just one way of doing things. If you have extra time on your hands, feel free to trace the code for more elegant solution.

For starters, lets create a customer and establish a login session right away for this newly created customer. Here is the code sample that does just that.

$customer = Mage::getModel('customer/customer');
//$customer  = new Mage_Customer_Model_Customer();
 
 
$password = '123456';
$email = 'ajzele@mymail.com';
 
$customer->setWebsiteId(Mage::app()->getWebsite()->getId());
$customer->loadByEmail($email);
//Zend_Debug::dump($customer->debug()); exit;
 
if(!$customer->getId()) {
 
	$customer->setEmail($email);
	$customer->setFirstname('Johnny');
	$customer->setLastname('Doels');
	$customer->setPassword($password);
}
 
try {
	$customer->save();
	$customer->setConfirmation(null);
	$customer->save();
 
	//Make a "login" of new customer
	Mage::getSingleton('customer/session')->loginById($customer->getId());
}
 
catch (Exception $ex) {
	//Zend_Debug::dump($ex->getMessage());
}

You can run this code from anywhere in Magento (model, view, controller…), it should do the trick.

At this point we have created new customer and made him “look like” he is logged in, or shall I say we established a session with his new credentials.

Now lets add a shipping and billing address to customer. Remember, these are needed in order to do checkout. Here is the code that programatically adds the shipping and billing address. In my case, I am using same address for both shipping and billing. If you prefer you can extend the logic and create two separate addresses and make one default for billing, other for shipping.

//Build billing and shipping address for customer, for checkout
$_custom_address = array (
	'firstname' => 'Branko',
	'lastname' => 'Ajzele',
	'street' => array (
		'0' => 'Sample address part1',
		'1' => 'Sample address part2',
	),
 
	'city' => 'Osijek',
	'region_id' => '',
	'region' => '',
	'postcode' => '31000',
	'country_id' => 'HR', /* Croatia */
	'telephone' => '0038531555444',
);
 
$customAddress = Mage::getModel('customer/address')
//$customAddress = new Mage_Customer_Model_Address();
$customAddress->setData($_custom_address)
			->setCustomerId($customer->getId())
			->setIsDefaultBilling('1')
			->setIsDefaultShipping('1')
			->setSaveInAddressBook('1');
 
try {
	$customAddress->save();
}
catch (Exception $ex) {
	//Zend_Debug::dump($ex->getMessage());
}
 
Mage::getSingleton('checkout/session')->getQuote()->setBillingAddress(Mage::getSingleton('sales/quote_address')->importCustomerAddress($customAddress));

Now that we have a logged in newly created customer with assigned addresses, lets add some products to the cart in his name. Here is the sample code.

/* If we wish to load some product by some attribute value diferent then id */
$product = Mage::getModel('catalog/product')->getCollection()
	/* Remember, you can load/find product via any attribute, better if its attribute with unique value */
	->addAttributeToFilter('sku', 'some-sku-value')
	->addAttributeToSelect('*')
	->getFirstItem();
 
/* Do a full product load, otherwise you might get some errors related to stock item */
$product->load($product->getId());
 
$cart = Mage::getSingleton('checkout/cart');
 
/* We want to add only the product/products for this user and do so programmatically, so lets clear cart before we start adding the products into it */
$cart->truncate();
$cart->save();
$cart->getItems()->clear()->save();			
 
try {
	/* Add product with custom oprion? =>  some-custom-option-id-here: value to be read from database or assigned manually, hardcoded? Just example*/
	//$cart->addProduct($product, array('options'=> array('some-custom-option-id-here' => 'Some value goes here');
	$cart->save();				
}
catch (Exception $ex) {
	echo $ex->getMessage();
}
 
unset($product);

And for the very end, the actual process of going trough “One Page Checkout” under the hood. Here is the sample code.

$storeId = Mage::app()->getStore()->getId();
 
$checkout = Mage::getSingleton('checkout/type_onepage');
 
$checkout->initCheckout();
 
$checkout->saveCheckoutMethod('register');
 
$checkout->saveShippingMethod('flatrate_flatrate');
 
$checkout->savePayment(array('method'=>'checkmo'));
 
try {
	$checkout->saveOrder();
}
catch (Exception $ex) {
	//echo $ex->getMessage();
}			
 
/* Clear the cart */
$cart->truncate();
$cart->save();
$cart->getItems()->clear()->save();		
 
/* Logout the customer you created */
Mage::getSingleton('customer/session')->logout();

And thats it. This code was tested on Magento 1.3 version, but I see no reason why it would not work on latest (as of time of this writing) 1.4.0.1 version.

In any case, you hope you find it useful. As always, word of advice, this is just for testing/education purpose so please do not blindly embed it on live sites.

Cheers.

  • http://www.avs-webentwicklung.de/ Andreas von Studnitz

    Wow, many thanks! That would have been a lot of work when I would have tried to find out all this on my next project… Thanks for sharing!
    Just one suggestion: you didn't show the code for adding a product to the cart without options. I assume it is
    $cart->addProduct($product);
    before
    $cart->save();
    .

  • raiz_meno

    In my magneto store I have 2 type of product and 2 type of shipping carriers for that.If suppose the user added both product to his cart he should be able to select shipping carrier corresponding to the product(here 2 shipping carrier at a time).What I will do? how can I implement that?

  • damien

    Hello, thanks for this work, it helped me a lot.
    But (there is always a 'but'), i've some problems when i'm trying to put an article to the cart.
    After hours, whatever the way i try, my card is stille empty. My “product” contains informations, it's ok but when i'm adding it to the cart, the cart is still empty
    Could you help me ? After hours on internet, i only found the same way to do

    code like :
    $cart->addProduct(2,2,array('qty' => 1));
    $cart->addProduct($product, array('qty' => 1));
    $cart->addProduct($productId, array('qty' => 1));

    Thanks

  • damien

    More details :
    if I display the cart, it's empty
    but in my new customer's cart, there is the good item, with the good quantity but no price
    And after, during OPC, i've an error with $checkout->saveShippingMethod('flatrate_flatrate');

    It seems to me that the item is added with errors (no price) and during the OPC, errors are reveleated

    (PS : sorry for my english)

  • raiz_meno

    Can you please help me checkout using the payment method paypal-direct ?

  • http://stepicorp.com Isy

    Could you modify and show the code using Authorize.Net instead of Check or Money Order? Your help is really appreciated.

    Thanks!

  • Jithesh Pk

    Thanks for the posting
    Really fixed my automatic group change …. thanks a lot

blog comments powered by Disqus