Magento: Create Order Programmatically

This article show how you can create sales order programmatically through code in Magento 1.x.

This code example also includes creating new customer if the customer email is not already registered. It also shows how you can save customer address to the newly created customer. This code has been tested for simple products.

Here are the steps followed in the code below:

– The code has a predefined customer’s name, email, billing and shipping address.

– It also has predefined shipping and payment method.

– It also has predefined array of product id and quantity of each product to be ordered/purchased.

– The code first loads the customer by email.

– If the customer email is not present in the system (i.e. the customer is not yet registered) then it sets the name, email, website and store for the customer.

– And then, the code creates the new customer. It also adds the billing and shipping to the newly created customer. This section of code is optional. If you don’t create a new customer at this point, then the order will be placed as Guest.

– After that, the customer object is added to the quote.

– Then, the product-qty array is looped and the product and qty are added to the quote.

– Then, billing and shipping address are added to the quote along with payment and shipping method.

– Finally, the quote is saved and new order is created.

– Log message is saved in the log file after the order is created and a response data is displayed.

Here is the full source code to create new customer programmatically:


$store = Mage::app()->getStore();
$website = Mage::app()->getWebsite();

$firstName = 'John';
$lastName = 'Doe';
$email = 'johndoe@example.com';
$logFileName = 'my-order-log-file.log';

$billingAddress = array(
			'customer_address_id' => '',
			'prefix' => '',
			'firstname' => $firstName,
			'middlename' => '',
			'lastname' => $lastName,
			'suffix' => '',
			'company' => '', 
			'street' => array(
				 '0' => 'Your Customer Address 1', // compulsory
				 '1' => 'Your Customer Address 2' // optional
			 ),
			'city' => 'Culver City',
			'country_id' => 'US', // two letters country code
			'region' => 'California', // can be empty '' if no region
			'region_id' => '12', // can be empty '' if no region_id
			'postcode' => '90232',
			'telephone' => '888-888-8888',
			'fax' => '',
			'save_in_address_book' => 1
		);
		
$shippingAddress = array(
			'customer_address_id' => '',
			'prefix' => '',
			'firstname' => $firstName,
			'middlename' => '',
			'lastname' => $lastName,
			'suffix' => '',
			'company' => '', 
			'street' => array(
				 '0' => 'Your Customer Address 1', // compulsory
				 '1' => 'Your Customer Address 2' // optional
			 ),
			'city' => 'Culver City',
			'country_id' => 'US', // two letters country code
			'region' => 'California', // can be empty '' if no region
			'region_id' => '12', // can be empty '' if no region_id
			'postcode' => '90232',
			'telephone' => '888-888-8888',
			'fax' => '',
			'save_in_address_book' => 1
		);		

/**
 * You need to enable this method from Magento admin
 * Other methods: tablerate_tablerate, freeshipping_freeshipping, etc.
 */ 
$shippingMethod = 'flatrate_flatrate';

/**
 * You need to enable this method from Magento admin
 * Other methods: checkmo, free, banktransfer, ccsave, purchaseorder, etc.
 */ 
$paymentMethod = 'cashondelivery';

/** 
 * Array of your product ids and quantity
 * array($productId => $qty)
 * In the array below, the product ids are 374 and 375 with quantity 3 and 1 respectively
 */ 
$productIds = array(374 => 3, 375 => 1); 

// Initialize sales quote object
$quote = Mage::getModel('sales/quote')
			->setStoreId($store->getId());

// Set currency for the quote
$quote->setCurrency(Mage::app()->getStore()->getBaseCurrencyCode());

$customer = Mage::getModel('customer/customer')
				->setWebsiteId($website->getId())
				->loadByEmail($email);

/**
 * Setting up customer for the quote 
 * if the customer is not already registered
 */
if (!$customer->getId()) {
	$customer = Mage::getModel('customer/customer');
	
	$customer->setWebsiteId($website->getId())
			 ->setStore($store)
			 ->setFirstname($firstName)
			 ->setLastname($lastName)
			 ->setEmail($email);			 
	
	/**
	 * Creating new customer
	 * This is optional. You may or may not create/save new customer.
	 * If you don't need to create new customer, you may skip/remove the below try-catch blocks.
	 */ 							
	try {
		// you can write your custom password here instead of magento generated password
		$password = $customer->generatePassword(); 		
		$customer->setPassword($password);
		
		// set the customer as confirmed
		$customer->setForceConfirmed(true);
		
		// save customer
		$customer->save();
		
		$customer->setConfirmation(null);
		$customer->save();
		
		// set customer address
		$customerId = $customer->getId();		
		$customAddress = Mage::getModel('customer/address');			
		$customAddress->setData($billingAddress)
					  ->setCustomerId($customerId)
					  ->setIsDefaultBilling('1')
					  ->setIsDefaultShipping('1')
					  ->setSaveInAddressBook('1');
		
		// save customer address
		$customAddress->save();
		
		// send new account email to customer	
		//$customer->sendNewAccountEmail();
		$storeId = $customer->getSendemailStoreId();
		$customer->sendNewAccountEmail('registered', '', $storeId);
		
		// set password remainder email if the password is auto generated by magento
		$customer->sendPasswordReminderEmail();
		
		// auto login customer
		//Mage::getSingleton('customer/session')->loginById($customer->getId());
		
		Mage::log('Customer with email '.$email.' is successfully created.', null, $logFileName);
		
	} catch (Mage_Core_Exception $e) {
		if (Mage::getSingleton('customer/session')->getUseNotice(true)) {
			Mage::getSingleton('customer/session')->addNotice(Mage::helper('core')->escapeHtml($e->getMessage()));
		} else {
			$messages = array_unique(explode("\n", $e->getMessage()));
			foreach ($messages as $message) {
				Mage::getSingleton('customer/session')->addError(Mage::helper('core')->escapeHtml($message));
			}
		}
	} catch (Exception $e) {
		//Zend_Debug::dump($e->getMessage());
		Mage::getSingleton('customer/session')->addException($e, $this->__('Cannot add customer'));
		Mage::logException($e);
		//$this->_goBack();
	} 
}

// Assign customer to quote
$quote->assignCustomer($customer);

// Add products to quote
foreach($productIds as $productId => $qty) {
	$product = Mage::getModel('catalog/product')->load($productId);
	$quote->addProduct($product, $qty);
	
	/**
	 * Varien_Object can also be passed as the second parameter in addProduct() function like below:
	 * $quote->addProduct($product, new Varien_Object(array('qty' => $qty)));
	 */ 
}

// Add billing address to quote
$billingAddressData = $quote->getBillingAddress()->addData($billingAddress);

// Add shipping address to quote
$shippingAddressData = $quote->getShippingAddress()->addData($shippingAddress);

/**
 * Billing or Shipping address for already registered customers can be fetched like below
 * 
 * $customerBillingAddress = $customer->getPrimaryBillingAddress();
 * $customerShippingAddress = $customer->getPrimaryShippingAddress();
 * 
 * Instead of the custom address, you can add these customer address to quote as well
 * 
 * $billingAddressData = $quote->getBillingAddress()->addData($customerBillingAddress);
 * $shippingAddressData = $quote->getShippingAddress()->addData($customerShippingAddress);
 */

// Collect shipping rates on quote shipping address data
$shippingAddressData->setCollectShippingRates(true)
					->collectShippingRates();

// Set shipping and payment method on quote shipping address data
$shippingAddressData->setShippingMethod($shippingMethod)
					->setPaymentMethod($paymentMethod);

// Set payment method for the quote
$quote->getPayment()->importData(array('method' => $paymentMethod));

try {
	// Collect totals of the quote
	$quote->collectTotals();

	// Save quote
	$quote->save();
	
	// Create Order From Quote
	$service = Mage::getModel('sales/service_quote', $quote);
	$service->submitAll();
	$incrementId = $service->getOrder()->getRealOrderId();
	
	Mage::getSingleton('checkout/session')
		->setLastQuoteId($quote->getId())
		->setLastSuccessQuoteId($quote->getId())
		->clearHelperData();
	
	/**
	 * For more details about saving order
	 * See saveOrder() function of app/code/core/Mage/Checkout/Onepage.php
	 */ 
	
	// Log order created message
	Mage::log('Order created with increment id: '.$incrementId, null, $logFileName);
			
	$result['success'] = true;
	$result['error']   = false;
	
	//$redirectUrl = Mage::getSingleton('checkout/session')->getRedirectUrl();
	//$redirectUrl = Mage::getUrl('checkout/onepage/success');
	//$result['redirect'] = $redirectUrl;
	
	// Show response
	Mage::app()->getResponse()				   
				 ->setBody(Mage::helper('core')->jsonEncode($result))
				 //->setRedirect($redirectUrl)
				 ->sendResponse();
				   
	//$this->_redirect('checkout/onepage/success', array('_secure'=>true));
	//$this->_redirect($redirectUrl);		
	
} catch (Mage_Core_Exception $e) {
	$result['success'] = false;
	$result['error'] = true;
	$result['error_messages'] = $e->getMessage();	
	Mage::app()->getResponse()->setBody(Mage::helper('core')->jsonEncode($result));
	
	if (Mage::getSingleton('checkout/session')->getUseNotice(true)) {
		Mage::getSingleton('checkout/session')->addNotice(Mage::helper('core')->escapeHtml($e->getMessage()));
	} else {
		$messages = array_unique(explode("\n", $e->getMessage()));
		foreach ($messages as $message) {
			Mage::getSingleton('checkout/session')->addError(Mage::helper('core')->escapeHtml($message));
		}
	}
} catch (Exception $e) {
	$result['success']  = false;
	$result['error']    = true;
	$result['error_messages'] = $this->__('There was an error processing your order. Please contact us or try again later.');
	Mage::app()->getResponse()->setBody(Mage::helper('core')->jsonEncode($result));
	
	Mage::logException($e);
	//$this->_goBack();
} 

Hope this helps. Thanks.