Adding a “I received my order” button in Prestashop

For many types of business it is fundamental to know whether the order has been received by the client or not, especially when using non-traceable carriers. Today we will give our customers an option to mark an order as received, saving us time and trouble.

Download Project Files
  • Compatibility: Prestashop 1.5

Why asking customers if they received an order?

Depending on the type of business you run, you might want to be sure some items have actually been delivered to your customers, whether you ship with tracked carriers or free postage (without tracking number).

Unless you integrated the carrier’s API into Prestashop, so that an order status can automatically be updated upon destination reach (impossible in the latter case, anyway), you’d find yourself having to manually check each and every order, to make sure it has actually been received. Giving customers the chance to manually notify themselves whether an order was delivered or not can save us a huge amount of time, and partially overcome the non-tracked carrier’s flaws.

In this tutorial, we will make use of one override, and modify 2 theme files. Specifically:

  • OrderDetailController Override
  • order-detail.tpl
  • history.js

We will make use of the default order statuses Shipped and Delivered for the given example, but feel free to use your own, keeping in mind their ids as we add the necessary code snippets.

Next thing to notice is that, by default, the order detail page is grabbed using javascript, directly from the history page, and thus we have to account for an ajax call that points to the controller override.

Lastly, please note that the following applies to registered customers only, not to guests.

Step 1 – Adding the “I received this order” button

The very first thing we need to do is add some kind of button the customer can click. The ideal page for this is, of course, the order detail one, which can be accessed via the user account panel:

Prestashop order detail

As you can see, this order has been shipped already, and thus the customer should be able to tell us if it was delivered or not. Since there is a step-by-step order follow section already, let’s add our button there. After making sure you got a theme’s backup in case of failure, open order-detail.tpl, located, in my case, in themes/default/.

Look for:

<h3>{l s='Follow your order\'s status step-by-step'}</h3>

And add the following right after, but before the table_block div:

{if $order_history.0.id_order_state == 4}
	<form action="{$link->getPageLink('order-detail', true)|escape:'html'}" method="post" class="std" id="markAsReceived">
		<input type="hidden" class="hidden" value="{$order->id|intval}" name="id_order" />
		<input type="submit" class="exclusive" name="markAsReceived" id="markAsReceivedBtn" value="{l s='I have received this order'}">
		<p class="clear"></p>
	</form>

{/if}

Explanation: Remember we mentioned the default order statuses at the beginning of the article? Well, in this conditional if statement, we are taking advantage of the Shipped status, which has 4 as status ID. Therefore, customers will only see the button if the current order has been set to Shipped. We access it using the variable $order_history, which is an array. Therefore, we get the most recent element’s status (which is the first one of the stack).
Then, we open a form that points to the order-detail page (and relative controller), so that our markAsReceived parameter is sent to it. We also need to pass the order id to this form, as the system needs to know which order’s status needs to be updated later.

Prestashop order detail - adding the order received button

We are basically done with the template part. We’ll come back later to add a confirmation message upon successful order status change.

How to check order status IDs?

If you do not wish to use the default statuses, you can easily create your own, and check their IDs from the back office Orders > Statuses.

Prestashop Order Statuses

The IDs are, needless to say, the ones under the ID column.

Step 2 – OrderDetailController override

Create a new php file in override/controllers/front and call it OrderDetailController.php. Inside it, add the following within php tags:

class OrderDetailController extends OrderDetailControllerCore
{

	public function postProcess()
	{
		parent::postProcess();

		if (Tools::isSubmit('markAsReceived'))
		{
			$idOrder = (int)(Tools::getValue('id_order'));
			$order = new Order($idOrder);

			if(Validate::isLoadedObject($order))
			{
				if($order->getCurrentState() == 4) // if the order is shipped
				{
					$new_history = new OrderHistory();
					$new_history->id_order = (int)$order->id;
					$new_history->changeIdOrderState(5, $order); // 5: delivered
					$new_history->addWithemail(true);	
				}

				$this->context->smarty->assign('receipt_confirmation', true);

			} else $this->_errors[] = Tools::displayError('Error: Invalid order number');
			
		}		

	}


}


Explanation: uh, quite a heavy jump! However, nothing special here, really. We are overriding the core’s postProcess method, which occurs right after having loaded the controller’s basic properties, so that other data can be collected and stored. In this case, we first make sure to refer back to the original postProcess(), then check if our markAsReceived button has been pressed.
If it has, we grab the order ID we passed, then create a new order object using it. It’s fundamental to always make sure a Prestashop Object was correctly loaded every time, using Validate::isLoadedObject($object).

If it is a valid object, and then if the current state is shipped (ID = 4) we can add a new order status. To do this, we use the OrderHistory class, setting the current order id ($new_history->id_order = (int)$order->id;) and then changing its status to 5 (delivered). Lastly, we submit the order change with $new_history->addWithemail(true). In case an email is to be sent out, it will. After this, we confirm the order has been received and assign a variable to the template, in order to show a confirmation message.

On the other end, we display an error in case the order object was not valid, for any reason.

At this point, we can already test out the form. But remember to delete the class_index file, located inside the /cache/ folder first, for the override to take place.

If you did everything correctly, the whole page will be refreshed, redirecting you to the order-detail controller, but with the ‘delivered’ status added.

It’s fundamental to always make sure a Prestashop Object was correctly loaded every time, using Validate::isLoadedObject($object)

The confirmation message

As we want to be polite to our customers, right before the form we added to order-detail.tpl, insert the following snippets, to thank them for their feedback.

{if isset($receipt_confirmation) && $receipt_confirmation}
	<p class="success">
		{l s='Thank you for your feedback!'}
	</p>
{/if}

So it looks like:

<h3>{l s='Follow your order\'s status step-by-step'}</h3>
{if isset($receipt_confirmation) && $receipt_confirmation}
	<p class="success">
		{l s='Thank you for your feedback!'}
	</p>
{/if}
{if $order_history.0.id_order_state == 4}
	<form action="{$link->getPageLink('order-detail', true)|escape:'html'}" method="post" class="std" id="markAsReceived">


		<input type="hidden" class="hidden" value="{$order->id|intval}" name="id_order" />
		<input type="submit" class="exclusive" name="markAsReceived" id="markAsReceivedBtn" value="{l s='I have received this order'}">
		<p class="clear"></p>
	</form>

{/if}

We could stop here; however, to give our customers a better user experience, we will integrate this button to the ajax style of the order history page.

Step 3 – Adding some Ajax to history.js

Open up history.js, located in the theme folder, /js/. We have to catch the submit event of the new form first. a suitable place for this is right after the following:

				$('form#sendOrderMessage').submit(function(){
					return sendOrderMessage();
				
				});

That catches the submission of the “Send a message” form. You can find it at line 73 in Prestashop 1.5.6.2. Right after, add:

				$('form#markAsReceived').submit(function(){
					return markAsReceived();
				});

Okay, we are returning a function instead of submitting the page. We don’t have it yet, so let’s use the sendOrderMessage() one as a base for ours. Add this at the end of the file:

				
function markAsReceived()
{
	paramString = "ajax=true";
	$('#markAsReceived').find('input').each(function(){
		paramString += '&' + $(this).attr('name') + '=' + encodeURIComponent($(this).val());
	});
	$.ajax({
		type: "POST",
		headers: { "cache-control": "no-cache" },
		url: $('#markAsReceived').attr("action") + '?rand=' + new Date().getTime(),
		data: paramString,
		success: function (msg){
			$('#block-order-detail').fadeOut('slow', function() {
				$(this).html(msg);
				//catch the submit event of sendOrderMessage form
				
				$(this).find('#markAsReceivedBtn').fadeOut;
				$(this).fadeIn('slow');
			});
		}
	});
	return false;
}

Explanation: despite having a scary look, there is not much going on under the hood. We first tell the script we will be using ajax, then add each parameter in the form to the POST call we’ll do. In this case, they will be markAsReceived and id_order, as we need them in the controller.
Then, we do an ajax call to our override (the url being called is the same of the action property of the form!), passing a random parameter to avoid duplicate calls. At this point, all the previously mentioned operations occur. Upon success, we fade out the entire order detail block, change its content with the one retrieved from the ajax call, fade out the mark as received button and show the order detail block again. Don’t forget to return false, or call e.preventDefault() at the end, to avoid the page refresh!

Save & test, no page refresh will now occur anymore!

TIP: instead of creating dozens of new orders for testing purposes, after the status is set to delivered, take it back to shipped so our button is visible again! (as i did in the following image)

Prestashop - I received my order confirmed

Conclusion

Customers can now inform us when they receive an order. However, an ideal extension to this would be an automated system that sends out emails to all customers who have “shipped” but not “delivered” orders. Well, we might do it in another tutorial!

You like the tuts and want to say "thank you"? Well, you can always feel free to donate:

  • Lyion

    Hello. is it able to use for Prestashop 1.7?

    • NemoPS

      Not as it is out of the box, templates are different

  • SatishMasani

    Hello Nemo,
    I just want a little enhancement, i am using multiple seller module, when my customer changes the status to delieverd a mail should get delivered to Admin, Vendor and customer. How do i do that.
    Thank You.

  • Mitesh

    Hello Nemo Really Great Job!!

    I’m Facing a Problem that The Button Dosen’t Show up on Order history Page
    and i’m using this button to allow users cancel the order if mistakenly ordered
    so i’ve changed the calling methods to those of the cancel button
    but still no luck with that and yes
    im using
    ps version 1.6.1.2
    it would be Great if u guide me for the same
    Thanks in Advance
    Regards,
    Mitesh

    • NemoPS

      Hi Mitesh,
      Hard to tell what’s going on. Did you clear cache in the first place?

      • Mitesh

        Bro I followed each and Every instruction of urs as u have mentioned here and still no luck

        • SatishMasani

          Hello Nemo,
          Thanks for posting its very helpful.
          i followed each and every step like you have mentioned.
          i m getting the markAsRecievedBtn on my oderdetails page , but when i click on it refresh the page , but no status changes.

      • Mitesh

        Bro I followed each and Every instruction of urs as u have mentioned here and still no luck

        please help me out as this function is needed for indian market

      • SatishMasani

        Hi Nemo,

        I followed your steps and i was able to use this button to allow my login users cancel the order if mistakenly ordered and change the order status to “Cancelled”, but when i use this same button for guest user’s to cancel i m not able to cancel the order and the status of order also remains unchanged ,and When i click on that button it takes to me to the login page of the website.

        It would be glad if you help me for the above problem

        Thank You.

  • luidiremerci

    Hi, there is a proble in STEP 2.
    Replace
    if($order->getCurrentState() = 4)
    by :

    if($order->getCurrentState() == 4)

    Best regards and thank you for your nice job.

    • NemoPS

      Uh! Thanks for spotting! Fixed :)

      • Sorin Alexandru Dinu

        Hello,I use PrestaShop 1.6.0.6.After clicking button, page is refreshing by ajax and nothing happened. Order status is still the same, feedback is also not displayed.
        What can be wrong?

        Please help me with this, I really need this.
        Thank you.

        • Sorin Alexandru Dinu

          Sorry.

          Everything works just fine now.

          “But remember to delete the class_index file, located inside the /cache/folder first, for the override to take place.”

          Thanks,
          Alex.

  • lordbdp

    I am on PS 1.5.6.2 and at the end nothing new on the orders history…

  • Francisco Javier

    Thank you, you do a fantastic job with your tutorials. On this tutorial, you should not get the store manager alerts when the customer confirms the order. Sorry for my English.

  • Samuel Lee

    Hi! First of all, thanks for creating this guide! However, i’m encountering problem adding this feature.

    Everything is fine when I add the button to order-detail.tpl, however, the problem comes in when I create the new OrderDetailController.php override file. After creating, I was not able to view my order details anymore. Please advice? Thank you :)

  • http://www.toniagustian.com/ Tonie Agustusan

    Thank you so much, it really useful.

    but i have problem, nothing happen after I click the button. but when I refresh the page it is already delivered.
    so I didn’t know if the delivered button has work.
    How can I put something like popup dialog to show that I already clicked it?… or maybe auto refresh the page after click?.

    I use prestashop 1.6 with default-bootstraps

    • http://lokalnamanufaktura.pl Adrian Ratajczak

      I’ve got the same problem but with

      PrestaShop™ 1.5.6.1.
      After clicking button, page is refreshing by ajax and nothing happened. Order status is still the same, feedback is also not displayed.
      What can be wrong?

  • HTZ

    Dear Sir, I would like to know “Adding a “I received my order” button in Prestashop” in prestashop 1.6.0.6.Please Help me.Thanks.

    • NemoPS

      This works with 1.6 as well :)

      • HTZ

        Thanks, Great it working 1.6.0.6.

  • aron

    Dear sir,

    First,thanks for your nice work.
    I follow what you said step by step,but it doesn’t work.
    Ps. I change it not in original template,change it with other template.

    I checked two times.
    Thanks.

  • http://www.podemski.info/ Krystian Podemski

    Oh, really great idea :)

    One thing, you dont need to write something like form#markAsReceived
    it’s enough to write #markAsReceived :P

    • NemoPS

      Yeah it’s true it can be left out, I just wanted to be more descriptive :D

You like the tuts and want to say "thank you"? Well, you can always feel free to donate: