This article presents an overview of “Order Confirmation page”. It is clear with the name what is a purpose of this page, but let me remind you one more time, what exactly this page should contain.
- Order Reference
- Order’s status step-by-step
- Delivery and invoice addresses
- Products list with total and shipping prices
- Carrier
- Payment method
Likewise, this page could be completed with the other elements (customers data, number of Reward Points that customer received, related products, etc.), depending on requirements of a client.
A while ago we released “Advanced Order Confirmation Page” PrestaShop module, which conforms to all requirement listed above. Further we will show you how to customize this module according to your needs.
“Advanced Order Confirmation Page” module uses order-detail.tpl template file to change a content of the page. We should relocate this file, and just copy order-detail.tpl file from the theme, and paste it to the front directory. Then add the following code into
/modules/order_confirmation/order_confirmation.php:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 |
public function hookDisplayOrderConfirmation($params) { return $this->getOrderDetail(); } /** * Assign template vars related to page content * @see FrontController::initContent() */ public function getOrderDetail() { if (!($id_order = (int)Tools::getValue('id_order')) || !Validate::isUnsignedId($id_order)) { $this->errors[] = Tools::displayError('Order ID required'); } else { $order = new Order($id_order); if (Validate::isLoadedObject($order) && $order->id_customer == $this->context->customer->id) { $id_order_state = (int)$order->getCurrentState(); $carrier = new Carrier((int)$order->id_carrier, (int)$order->id_lang); $addressInvoice = new Address((int)$order->id_address_invoice); $addressDelivery = new Address((int)$order->id_address_delivery); $inv_adr_fields = AddressFormat::getOrderedAddressFields($addressInvoice->id_country); $dlv_adr_fields = AddressFormat::getOrderedAddressFields($addressDelivery->id_country); $invoiceAddressFormatedValues = AddressFormat::getFormattedAddressFieldsValues($addressInvoice, $inv_adr_fields); $deliveryAddressFormatedValues = AddressFormat::getFormattedAddressFieldsValues($addressDelivery, $dlv_adr_fields); if ($order->total_discounts > 0) { $this->context->smarty->assign('total_old', (float)$order->total_paid - $order->total_discounts); } $products = $order->getProducts(); /* DEPRECATED: customizedDatas @since 1.5 */ $customizedDatas = Product::getAllCustomizedDatas((int)$order->id_cart); Product::addCustomizationPrice($products, $customizedDatas); OrderReturn::addReturnedQuantity($products, $order->id); $order_status = new OrderState((int)$id_order_state, (int)$order->id_lang); $customer = new Customer($order->id_customer); $cart = new Cart($order->id_cart); $base_total_tax_inc = $cart->getOrderTotal(true, Cart::BOTH); $total_products_wt = $cart->getOrderTotal(true, Cart::ONLY_PRODUCTS); $total_products = $cart->getOrderTotal(false, Cart::ONLY_PRODUCTS); $total_tax = $total_products_wt - $total_products; $p = $products[array_rand($products)]; $product = new Product($p['id_product'], true, $this->context->language->id); $accessories = $product->getAccessories($this->context->language->id); $tpl = $this->context->smarty->createTemplate(_PS_MODULE_DIR_.'order_confirmation/views/templates/front/order-detail.tpl', $this->context->smarty); $tpl->assign(array( 'shop_name' => strval(Configuration::get('PS_SHOP_NAME')), 'accessories' => $accessories, 'order' => $order, 'total_order' => $base_total_tax_inc, 'total_products' => $base_total_tax_inc-$total_tax, 'return_allowed' => (int)$order->isReturnable(), 'currency' => new Currency($order->id_currency), 'order_state' => (int)$id_order_state, 'invoiceAllowed' => (int)Configuration::get('PS_INVOICE'), 'invoice' => (OrderState::invoiceAvailable($id_order_state) && count($order->getInvoicesCollection())), 'logable' => (bool)$order_status->logable, 'order_history' => $order->getHistory($this->context->language->id, false, true), 'products' => $products, 'discounts' => $order->getCartRules(), 'carrier' => $carrier, 'address_invoice' => $addressInvoice, 'invoiceState' => (Validate::isLoadedObject($addressInvoice) && $addressInvoice->id_state) ? new State($addressInvoice->id_state) : false, 'address_delivery' => $addressDelivery, 'inv_adr_fields' => $inv_adr_fields, 'dlv_adr_fields' => $dlv_adr_fields, 'invoiceAddressFormatedValues' => $invoiceAddressFormatedValues, 'deliveryAddressFormatedValues' => $deliveryAddressFormatedValues, 'deliveryState' => (Validate::isLoadedObject($addressDelivery) && $addressDelivery->id_state) ? new State($addressDelivery->id_state) : false, 'is_guest' => false, 'messages' => CustomerMessage::getMessagesByOrderId((int)$order->id, false), 'CUSTOMIZE_FILE' => Product::CUSTOMIZE_FILE, 'CUSTOMIZE_TEXTFIELD' => Product::CUSTOMIZE_TEXTFIELD, 'isRecyclable' => Configuration::get('PS_RECYCLABLE_PACK'), 'use_tax' => Configuration::get('PS_TAX'), 'group_use_tax' => (Group::getPriceDisplayMethod($customer->id_default_group) == PS_TAX_INC), /* DEPRECATED: customizedDatas @since 1.5 */ 'customizedDatas' => $customizedDatas, /* DEPRECATED: customizedDatas @since 1.5 */ 'reorderingAllowed' => !(bool)Configuration::get('PS_DISALLOW_HISTORY_REORDERING') )); if ($carrier->url && $order->shipping_number) { $this->context->smarty->assign('followup', str_replace('@', $order->shipping_number, $carrier->url)); } $this->context->smarty->assign('HOOK_ORDERDETAILDISPLAYED', Hook::exec('displayOrderDetail', array('order' => $order))); Hook::exec('actionOrderDetail', array('carrier' => $carrier, 'order' => $order)); unset($carrier, $addressInvoice, $addressDelivery); } else { $this->errors[] = Tools::displayError('This order cannot be found.'); } unset($order); } return $tpl->fetch(); } |
And now you can modify template file according to your needs.
For example, you want to add Related Products block, what can stimulate customers for further purchase.
/modules/order_confirmation/order_confirmation.php:
1 2 3 4 5 6 7 |
$p = $products[array_rand($products)]; $product = new Product($p['id_product'], true, $this->context->language->id); $accessories = $product->getAccessories($this->context->language->id); $this->context->smarty->assign(array( 'accessories' => $accessories )); |
/modules/order_confirmation/views/templates/front/order-detail.tpl:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
{if isset($accessories) && $accessories} <!--Accessories --> <section class="page-product-box"> <h3 class="page-product-heading">{l s='Accessories'}</h3> <div class="block products_block accessories-block clearfix"> <div class="block_content"> <ul id="bxslider" class="bxslider clearfix"> {foreach from=$accessories item=accessory name=accessories_list} {if ($accessory.allow_oosp || $accessory.quantity_all_versions > 0 || $accessory.quantity > 0) && $accessory.available_for_order && !isset($restricted_country_mode)} {assign var='accessoryLink' value=$link->getProductLink($accessory.id_product, $accessory.link_rewrite, $accessory.category)} <li class="item product-box ajax_block_product{if $smarty.foreach.accessories_list.first} first_item{elseif $smarty.foreach.accessories_list.last} last_item{else} item{/if} product_accessories_description"> <div class="product_desc"> <a href="{$accessoryLink|escape:'html':'UTF-8'}" title="{$accessory.legend|escape:'html':'UTF-8'}" class="product-image product_image"> <img class="lazyOwl" src="{$link->getImageLink($accessory.link_rewrite, $accessory.id_image, 'home_default')|escape:'html':'UTF-8'}" alt="{$accessory.legend|escape:'html':'UTF-8'}" /> </a> <div class="block_description"> <a href="{$accessoryLink|escape:'html':'UTF-8'}" title="{l s='More'}" class="product_description"> {$accessory.description_short|strip_tags|truncate:25:'...'} </a> </div> </div> <div class="s_title_block"> <h5 itemprop="name" class="product-name"> <a href="{$accessoryLink|escape:'html':'UTF-8'}"> {$accessory.name|truncate:20:'...':true|escape:'html':'UTF-8'} </a> </h5> {if $accessory.show_price && !isset($restricted_country_mode) && !$PS_CATALOG_MODE} <span class="price"> {if $priceDisplay != 1} {displayWtPrice p=$accessory.price} {else} {displayWtPrice p=$accessory.price_tax_exc} {/if} {hook h="displayProductPriceBlock" product=$accessory type="price"} </span> {/if} {hook h="displayProductPriceBlock" product=$accessory type="after_price"} </div> <div class="clearfix" style="margin-top:5px"> {if !$PS_CATALOG_MODE && ($accessory.allow_oosp || $accessory.quantity > 0) && isset($add_prod_display) && $add_prod_display == 1} <div class="no-print"> <a class="exclusive button ajax_add_to_cart_button" href="{$link->getPageLink('cart', true, NULL, "qty=1&id_product={$accessory.id_product|intval}&token={$static_token}&add")|escape:'html':'UTF-8'}" data-id-product="{$accessory.id_product|intval}" title="{l s='Add to cart'}"> <span>{l s='Add to cart'}</span> </a> </div> {/if} </div> </li> {/if} {/foreach} </ul> </div> </div> </section> <!--end Accessories --> {/if} |
So here is the result on a frontend:
As you can see we achieved additional functionality for an Advanced Order Confirmation Page in quite easy and fast way.
Advanced Order Confirmation Page module is rather flexible and could be easily extended according to the requirements of your web store. For more Prestashop modules check our shop.
Hi,
to confirm an order by link, implement the payment modules:
Pay by Check
Pay by Bank Wire
These modules generate the page, where a user should confirm an order. There is also a button with a link on the page.
In case you want to check an order, the ‘Orders History’ Page provides all the information according to the particular user.
Is it possible in prestashop 1.6 to confirm order by link?