Magento’s Onepage Checkout in a nutshell

Magento’s Onepage Checkout in a nutshell

For the last two days I’ve been working on a custom checkout page for one of our clients. Basicaly a page can be shown in Magento using simple Core_Template type. Basically all code is set inside the .phtml file so it can be shown on every possible page or block, meaning it’s object independent, no inheritance. Something you can call from with your layout files like

<block type="core/template" name="checkout_customcart" template="checkout/customcart.phtml" />

To complete my work, I had two mayor requirements. One was to manage my way around programmable adding a simple products to cart, plus their quantity and other was to do checkout with items in cart. Checkout was to be made with predefined payment method as well as shipping method. After reviewing a lot of Magento’s code involved in checkout process and process of adding products to cart and so on I’ve put together what I see as the most short example one can use to do a checkout with such predefined conditions.

If you have such special requirements for your site below is the code that you can place on whatever file you wish and include it yout tempalte as block type core/template.

$checkout = Mage::getSingleton('checkout/type_onepage');
/**
 * One page checkout consists of following steps
 * (1) Customer login method aka Checkout method
 * (2) Billing information (address)
 * (3) Shipping information (address)
 * (4) Shipping method
 * (5) Payment information
 * (6) Order review, in short: DO THE ORDER
 */
 
// STEP(1)
$checkout->saveCheckoutMethod('guest');
 
// STEP(2)
$checkout->saveBilling($billingAddress, false);
 
// STEP(3)
$checkout->saveShipping($shippingAddress, false);
 
// STEP(4)
$checkout->saveShippingMethod('flatrate_flatrate');
 
// STEP(5)
$checkout->savePayment(array('method'=>'checkmo'));
 
// STEP(6)
/**
 * $checkout->saveOrder() returns array holding empty object
 * of type Mage_Checkout_Model_Type_Onepage
 */
$checkout->saveOrder();

And here is the example of how the $address variables are supose to look

[billing] => Array(
    [address_id] => 5
    [firstname] => Branko
    [lastname] => Ajzele
    [company] => Inchoo
    [email] => ajzele@somemail.com
    [street] => Array(
        [0] => Address part 1
        [1] => Address part 2
    )
    [city] => Osijek
    [region_id] =>
    [region] =>
    [postcode] => 31000
    [country_id] => HR
    [telephone] => 0038531000331
    [fax] => 0038531000332
    [customer_password] =>
    [confirm_password] =>
    [save_in_address_book] => 1
)
 
[shipping] => Array(
    [address_id] => 6
    [firstname] => Ivan
    [lastname] => Weiller
    [company] => Inchoo
    [street] => Array(
        [0] => Address part 1
        [1] => Address part 2
    )
    [city] => Osijek
    [region_id] =>
    [region] =>
    [postcode] => 31000
    [country_id] => HR
    [telephone] => 0038531000333
    [fax] => 0038531000334
    [save_in_address_book] => 1
)

And you can wrapp the above checkout code into something like

if($this->getRequest()->getParam('submitCustomCheckout')) {
    //Checkout code from above...
}

Where ubmitCustomCheckout is the name of the submit button or submit input field. To extract addresses you can use something like

$billingAddress = $this->getRequest()->getParam('billing');
$billingAddress['use_for_shipping'] = 0;
$shippingAddress = $this->getRequest()->getParam('shipping');

That’s it. Simple, predefined checkout by whitch order can be make on one click.

You made it all the way down here so you must have enjoyed this post! You may also like:

Meet Magento Belarus features an Inchooer talking Magento 2 Checkout Ivona Namjesnik
Ivona Namjesnik, | 0

Meet Magento Belarus features an Inchooer talking Magento 2 Checkout

Tracking Onepage Checkout abandonment using Google Analytics Drazen Karacic-Soljic
Drazen Karacic-Soljic, | 70

Tracking Onepage Checkout abandonment using Google Analytics

CheckItOut, alternative checkout for Magento Branko Ajzele
Branko Ajzele, | 27

CheckItOut, alternative checkout for Magento

79 comments

  1. Hi,

    We are setting shipping address with default if the customers choose free shipping, but if they change from free shipping i want to assign the shipping address in session, how can i do that. Please can anyone help me.

  2. wew.. thanks for the post.. this helps me a lot and it did works!!! i’m planning to create an extension and publish it for free. 🙂

  3. hay,

    what is the code for making OneStepCheckOut page in magento 1.4.2?

    also, can give me picture or demo to watch how it works?

    thanks,
    rami

  4. Thank you kris. What was happening the validate() function did not know the $ccNumber. I am awaiting confirmation from my client that they received my test payment in their Paypal account but the “Credit card number mismatch” disappeared once I added the following lines of code in the original code sample provided by Branko:

    $_quote = $checkout->getQuote();

    and

    $checkout->getPayment()->importData($payment);

  5. having now completed a totally custom one-page checkout (not even using prototype/jquery and varien’s js functions) there are definitely a number of things you have to do ‘yourself’ that would otherwise be handled by either the controllers or the observers instantiated by submitting each step via ajax.

    i don’t remember what exactly the remedy was for the incorrect cc number problem, however, i believe it was to repopulate and resubmit the payment info to the onepage model.

    in essence the payment info is submitted twice, once to validate the payment info, the second time to actually capture/authorize payment.

    also, instead of saveOrder i located and reimplemented the code that one of the controllers Would have executed during a checkout with the standard/default theme package.

    $_onepage = Mage::getSingleton(‘checkout/type_onepage’);
    $_quote = $_onepage->getQuote();

    $_onepage->savePayment($_POST[‘payment’]);
    $_quote->getPayment()->importData($_POST[‘payment’]);
    $_onepage->validate();

    $_service = Mage::getModel(‘sales/service_quote’,$_quote);
    $_order = $_service->submit();
    Mage::dispatchEvent(‘checkout_type_onepage_save_order_after’,array(‘order’ => $_order,’quote’ => $_quote));

    $_order_id = $_order->getIncrementId();
    $_order->sendNewOrderEmail();

    $_onepage->getCheckout()->clear();

    the other reason i had to do this was so that i could have access to the newly created Order object in order to ‘re-attach’ gift messages to it, copied from the Quote.

  6. “Credit card number mismatch with credit card type.”

    Same here, using paypal_direct as method.

    Something missing or not set properly in the $payment array?

    Any hints appreciated. Thanks!

  7. “Credit card number mismatch with credit card type.”

    ideas?

    this article definitely helped me out quite a bit with my custom onepage checkout process… tossed prototype/jquery out the window and we’ve been building a site with a totally custom theme, which also means we lost the built-in js & json tied to checkout and other functions…

    our goal seemed so close yet now seems so far thanks to this error.

  8. Dear All,

    I want to build a custom checkout page,customer can place the order on single click.
    Can I use above method to do this? I want to know which magento version will support it. I am using Magento 1.3.2 version.

    Thanks,
    Satish

  9. i am getting error on checkout page

    Card Verification
    Please verify the card with the issuer bank:

    any help

  10. Hi,
    actually Mage::getSingleton caused my magento setup to display an errorcode. I worked around that by editing the opcheckout.js in the skin directory to submit the values I want for method, shipping-method and payment. it works great.
    For example, to allow only guest checkout edit the saveMethod()-function and add this.saveMethod() in the init-function…
    Additionaly i prevented unwanted steps to be displayed, by adding:
    || $_stepId = = ‘login’ || $_stepId == …
    in the if-statement on line 45 of onepage.phtml.
    Editing the javascript saved me a lot of time, I guess, as debugging magento templates is a time-intensive job…

  11. I have a question that’s been plaguing me already. I’m using chase paymentech and all my transactions (whether success or declined by the credit card company) still goes to the success page of checkout. It doesnt tell the client their card has been declined. Thanks in advance!

  12. I have the same problem Dina has regarding Payment with Authorize.Net. Please let me know how the call savePayment($payment) should work. I also be ready to pay you for this stuff. Please let me know ASAP.

    Isy.

  13. I could find out how the cart is updated in the onepage checkout process:
    If the order has been saved, the customer is redirected to /checkout/onepage/success. The successAction of the onepage controller clears the shopping cart (to be precise: calls Mage::getModel(‘checkout/session’)->clear()).
    best,
    erik

  14. Hi,
    very useful article!
    Saving the order works well. Hower, do I have to manually remove the ordered products from shopping cart?
    Best,
    erik

  15. Hi Branko, can you assist me with the following which is related to checkout:

    What I am trying to do is the following:

    When a customer orders a product, before he/she clicks on “proceed to checkout”, I would like to check to see if what the customer is trying to order has already been ordered by him/her before. If it has, I would like to display a message to the customer that he/she can’t order the product again. This should be done before the order actually gets saved in the database. The other part that I would like to check for is if the customer has more than 1 of the same item in the cart and give them a “you can only order 1 of these items” message.

    I believe it should be possible, but I just don’t know php very well and I am still learning Magento.

    Thanks for you help in advance.

  16. Hi, thanks a lot for this tutorial. Actually I need to get total price for the whole order with shipping and taxes… But if I try to retrive this data from $this->getRequest()->getParam(’review’) on success page, there is only empty array. How can I get this total price via PHP or JS pls?

  17. Hi,
    How do I change the error message coming from the payment gateway e.g. Failed AVS Check: 10505-This transaction cannot be processed. It’s not the friendliest message and want to make it more informative.

  18. This works perfectly and thanks for the your code, Branko Ajzele and keep on doing good work. 🙂

    Regards,
    Ranga

  19. About the paypal redirecting, I did a separate script that reads the session and manually redirects to paypal.

    Thanks for this great tutorial,
    George

  20. Hello,

    I want to combine onepage checkout and cart together. How do I add onepage checkout to my cart page, so that the user basically sees just one page and is required to do just a single click to place the order?

    Thanks,
    Garima

  21. Thanks a lot for this article. It really helped me out. Although now I am having trouble in redirecting to Paypal after the order is placed. I replaced payment method with paypal_standard. In the worst case scenario I will make the sending data and redirection manually.

    Thanks,
    George

  22. hi Branko. thank you very much for identifying these checkout methods. I am trying to build a custom checkout page, but when I call savePayment($payment) I get an error ‘Credit card number mismatch with credit card type’.

    i am sending…

    $payment[“method”] = ‘plugnpay’;
    $payment[“cc_type”] = ‘MC’;
    $payment[“cc_number”] = ‘5105105105105100’;
    $payment[“cc_exp_month”] = ‘2’;
    $payment[“cc_exp_year”] = ‘2013’;
    $payment[“cc_cid”] = ‘123’;

    This is a test cc and it works when I checkout via the default install. what am i missing? I can provide code and pay for answers too.

    thanks,
    – dina

  23. Hi Branko,

    thank you very much for great article about magento checkout. It is perfect! I have created my own checkout module based on it.

    I have just one question – how should I redirect to the Payment gateway or checkout/onepage/success/ after submitting order?

    I can give you my code if you want and also pay for the answer.

  24. hi i would like to know how to add some amount say $1.0 to the grand total when use pays through certain payment method.
    Anyway to hack grandTotal() from payment module ??

  25. Hi I want to redirect the link Place Order to Payment Gateway of bank s site with
    passing some variables like grand total .

    thanks

  26. Hi
    I am using One step checkout method. but i am facing one problem during the submit order .In step 4
    $checkout->saveShippingMethod(’flatrate_flatrate’);

    In my site i have enabled United Parcel Service,United States Postal Service . I am getting error “Please specify shipping method”. when i replaced flatrate_flatrate with “United Parcel Service” .
    Can u tell me that how i can solve this problem.

    Thanks

  27. Excellent! Extremely concise, to-the-point and helpful! Thanks so much for taking the time that all of us developers should take to write down things as we learn them for each other to learn from… Awesome dude…

  28. @Branko: cool thanks, it’s good to know the checkout page will work for everybody.
    @Chinesedream: Nice, I’ll look into those. We actually managed to change the side nav to use jquery accordian and I’m hoping to replace all Prototype with jQuery (but it looks like a huge task).

  29. If it brings you confusion then do not mess with it. This is advanced stuff, and poking around checkout if you do not understand the basis is a no no. Above article is a basis. Took me 6 days to wrote fully functional version as per client request, it has around 800 lines of code. I have no time, or wish, to explain that in detail. Besides, Margarita seems to be ok with it.

    If you require such functionality, feel free to request a quote. Cheers…

  30. Forget it. It works. It works well.

    Now the problem is how to save the item for the sale from the product page and not from the shopping cart.

  31. regarding the last post, the submit button:
    input type=”submit” name=”submitCustomCheckout” value=”submit”

  32. Hi,

    I am trying to have the checkout page in the product page,
    so for each product viewed the customer will be able to complete the checkout, as guest, at the same page where the product is.
    (catalog/product/view.phtml)

    I was trying to follow the code here, and added this as submit button:

    I recived the following error:
    Use of undefined constant ?submitCustomCheckout? – assumed ‘?submitCustomCheckout?’

    How can I do that?

    Thanks

  33. @Spuff,

    I’d been working on improving accessibility and progressive enhancement on Magento store for projects. Things I have done concerning JS turns off that maybe helpful to you are:

    1. Use jQuery Superfish menu instead.
    2. Use jQuery for Tabs – the Modern theme has a Tabs Feature in Product page but it’s no good with JS turns off.

    Thanks Branko.

  34. @Spuff

    In the default Magento’s one page checkout you have these checkout steps like enter shipping address, choose shipping method, choose payment method and so on. HTML for each next step is retrieved using JS (AJAX). Therefore, you need JS.

    In my example you do not need JS because i throw each of those steps out and made custom checkout with predetermined values inside the code. In my example I never see “Choose your payment method” step because I have set it in code. Hope this clears some stuff for you.

    Cheers…

  35. @chinesedream and Branko:

    On the topic of JS I was under the impression that Magento didn’t function if JS was disabled. For example my add to cart buttons don’t work and the menu doesn’t drop down, little things like that. I’ve been told that this means if you use Magento you basically have to assume the user has JS installed so you don’t need to code workarounds for a situation that will never exist. Have I been misled? I’d love to see a working Magento with JS disabled if anyone has a link they’d like to share.

    @Branko: I think I speak for everybody when I say your tutorials are very much appreciated

  36. Branko,

    Will it works if JS disables?

    Looks exciting! I was still eager waiting for Varien releases the single page checkout that one of the team member mentioned.

    Can I copy your code and play with it?

  37. Hi,

    I want when user click the “Continue” button in billing section after filling the billing details, then on click of continue button, I want to send mail to my sales team with billing details, without stopping the checkout process, it should be using AJAX,

    Can you please tell me how to do this?

    Thanks

  38. Hi Joseph

    Above example is the checkout in it’s simplest form. It took me almost whole day to figure the steps. Above steps are not all that make checkout process. They simple represent somewhat of a hooked state where I went behind few functions and “tapped” the right stuff in the right place.

    Answer to your question simply cannot fit into two or three sentence. Best advice I can give right now is to use the method I described in this article http://ajzele.net/utilize-firebug-and-firephp-to-speed-up-magento-development/ and start playing and debugging the Mage_Checkout_Model_Type_Onepage class if you are a developer. If you are more of a frontend user (the client :)) I suggest you hire someone to implement custom checkout for you if you require one.

    Not sure how helpful this was. Wish you all the best. Cheers.

  39. Hello,

    How can I add some more fields to this Checkout form ? And without changing the core files needed to do the checkout process?

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <blockquote cite=""> <code> <del datetime=""> <em> <s> <strike> <strong>. You may use following syntax for source code: <pre><code>$current = "Inchoo";</code></pre>.

Tell us about your project

Drop us a line. We'd love to know more about your project.