Magento 2 CMS is widely preferred to run online businesses in various niches.
As the CMS is flexible for customization, modern business requirements can be easily fulfilled. One such example is to add custom field in checkout page just after payment method list in Magento 2.
This post shows the programmatic solution for the same.
For example. you need the customer to agree with something apart from the default Magento 2 terms and conditions, you can implement a custom checkbox.
Or, you can add the gift wrap checkbox using the below code. If you want to encourage the customers to donate some amount with each purchase, you can add a checkbox field which when the customer will tick, a fixed amount will be added to the cart total automatically.
Any of the above scenarios can be implemented or other custom fields can be added as shown in the figure below:
The example here is about adding a custom checkbox in the checkout page, saving its value in the database table, and displaying the same in the admin panel.
Steps to Add custom field in checkout page just after payment method list in Magento 2:
Step 1: To add custom field in the table
Create InstallData.php file under Vendor\Module\Setup\
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 | <?php namespace Vendor\Module\Setup; use Magento\Framework\Setup\InstallDataInterface; use Magento\Framework\Setup\ModuleContextInterface; use Magento\Framework\Setup\ModuleDataSetupInterface; use Magento\Customer\Model\Customer; use Magento\Customer\Setup\CustomerSetupFactory; class InstallData implements InstallDataInterface { private $customerSetupFactory; /** * Constructor * * @param \Magento\Customer\Setup\CustomerSetupFactory $customerSetupFactory */ public function __construct( CustomerSetupFactory $customerSetupFactory ) { $this->customerSetupFactory = $customerSetupFactory; } /** * {@inheritdoc} */ public function install( ModuleDataSetupInterface $setup, ModuleContextInterface $context ) { $installer = $setup; $installer->startSetup(); $installer->getConnection()->addColumn( $installer->getTable('quote'), 'agree', [ 'type' => \Magento\Framework\DB\Ddl\Table::TYPE_BOOLEAN, 'visible' => true, 'default' => 0, 'comment' => 'Custom Condition' ] ); $installer->getConnection()->addColumn( $installer->getTable('sales_order'), 'agree', [ 'type' => \Magento\Framework\DB\Ddl\Table::TYPE_BOOLEAN, 'visible' => true, 'default' => 0, 'comment' => 'Custom Condition' ] ); } } |
Step 2: To Create extension attribute and add checkbox just after payment methods and Save that field in Quote table
Create extension_attributes.xml file under Vendor\Module\etc\
1 2 3 4 5 6 | <?xml version="1.0"?> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Api/etc/extension_attributes.xsd"> <extension_attributes for="Magento\Quote\Api\Data\AddressInterface"> <attribute code="agree" type="string" /> </extension_attributes> </config> |
Create checkout_index_index.xml file under Vendor\Module\view\frontend\layout\
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 | <?xml version="1.0"?> <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="1column" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd"> <body> <referenceBlock name="checkout.root"> <arguments> <argument name="jsLayout" xsi:type="array"> <item name="components" xsi:type="array"> <item name="checkout" xsi:type="array"> <item name="children" xsi:type="array"> <item name="steps" xsi:type="array"> <item name="children" xsi:type="array"> <item name="billing-step" xsi:type="array"> <item name="children" xsi:type="array"> <item name="payment" xsi:type="array"> <item name="children" xsi:type="array"> <item name="afterMethods" xsi:type="array"> <item name="children" xsi:type="array"> <item name="custom-checkbox" xsi:type="array"> <item name="component" xsi:type="string">Vendor_Module/js/checkout/customJs</item> <item name="displayArea" xsi:type="string">before-place-order</item> <item name="sortOrder" xsi:type="string">3</item> <item name="dataScope" xsi:type="string">checkoutcomments</item> <item name="provider" xsi:type="string">checkoutProvider</item> </item> </item> </item> </item> </item> </item> </item> </item> </item> </item> </item> </item> </argument> </arguments> </referenceBlock> </body> </page> |
Create customJs.js file under Vendor\Module\view\frontend\web\js\checkout
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 | define( [ 'ko', 'jquery', 'uiComponent', 'mage/url' ], function (ko, $, Component,url) { 'use strict'; return Component.extend({ defaults: { template: 'Vendor_Module/checkout/customCheckbox' }, initObservable: function () { this._super() .observe({ CheckVals: ko.observable(false) }); var checkVal=0; self = this; this.CheckVals.subscribe(function (newValue) { var linkUrls = url.build('module/checkout/saveInQuote'); if(newValue) { checkVal = 1; } else{ checkVal = 0; } $.ajax({ showLoader: true, url: linkUrls, data: {checkVal : checkVal}, type: "POST", dataType: 'json' }).done(function (data) { console.log('success'); }); }); return this; } }); } ); |
Create customCheckbox.html file under Vendor\Module\view\frontend\web\template\checkout
1 | <input type="checkbox" name="customCheckbox" value="" data-bind='checked: CheckVals'/><div> Check to Agree </div> |
Create saveInQuote.php file under Vendor\Module\Controller\Checkout
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 | <?php namespace Vendor\Module\Controller\Checkout; use Magento\Framework\App\Action\Context; use Magento\Framework\Controller\Result\ForwardFactory; use Magento\Framework\View\LayoutFactory; use Magento\Checkout\Model\Cart; use Magento\Framework\App\Action\Action; use Magento\Checkout\Model\Session; use Magento\Quote\Model\QuoteRepository; class saveInQuote extends Action { protected $resultForwardFactory; protected $layoutFactory; protected $cart; public function __construct( Context $context, ForwardFactory $resultForwardFactory, LayoutFactory $layoutFactory, Cart $cart, Session $checkoutSession, QuoteRepository $quoteRepository ) { $this->resultForwardFactory = $resultForwardFactory; $this->layoutFactory = $layoutFactory; $this->cart = $cart; $this->checkoutSession = $checkoutSession; $this->quoteRepository = $quoteRepository; parent::__construct($context); } public function execute() { $checkVal = $this->getRequest()->getParam('checkVal'); $quoteId = $this->checkoutSession->getQuoteId(); $quote = $this->quoteRepository->get($quoteId); $quote->setAgree($checkVal); $quote->save(); } } |
Step 3: To Save that custom field in Sales_Order table
Create event.xml file under Vendor\Module\etc\
1 2 3 4 5 6 | <?xml version="1.0"?> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd"> <event name="sales_model_service_quote_submit_before"> <observer name="custom_checkbox_code_order_place_before_action" instance="Vendor\Module\Observer\PlaceOrder"/> </event> </config> |
Create PlaceOrder.php file under Vendor\Module\Observer\
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 | <?php namespace Vendor\Module\Observer; use Magento\Framework\Event\Observer; use Magento\Framework\Event\ObserverInterface; use Magento\Quote\Model\QuoteFactory; use Psr\Log\LoggerInterface; class PlaceOrder implements ObserverInterface { /** * @var \Psr\Log\LoggerInterface */ protected $_logger; /** * @var \Magento\Customer\Model\Session */ protected $quoteFactory; /** * Constructor * * @param \Psr\Log\LoggerInterface $logger */ public function __construct(LoggerInterface $logger, QuoteFactory $quoteFactory) { $this->_logger = $logger; $this->quoteFactory = $quoteFactory; } public function execute(Observer $observer) { $order = $observer->getOrder(); $quoteId = $order->getQuoteId(); $quote = $this->quoteFactory->create()->load($quoteId); $order->setAgree($quote->getAgree()); $order->save(); } } |
Step 4: To Display custom field value in admin side order view
Create sales_order_view.xml file under Vendor\Module\view\adminhtml\layout
1 2 3 4 5 6 7 8 | <?xml version="1.0"?> <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="admin-2columns-left" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd"> <body> <referenceBlock name="order_info"> <block class="Vendor\Module\Block\Adminhtml\Order\View\DisplayCustomValue" name="sales_order_view_custom_value" template="order/view/displayCustomValue.phtml" /> </referenceBlock> </body> </page> |
Create displayCustomValue.phtml file under Vendor\Module\view\adminhtml\templates\order\view
1 2 3 | <h4>Custom Condition Added : <?php $CheckValue = $block->getAgree(); ($CheckValue) ? echo 'Yes' : echo 'No'; ?> </h4> |
Create displayCustomValue.php file under Vendor\Module\Block\Adminhtml\Order\View\
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | <?php namespace Vendor\Module\Block\Adminhtml\Order\View; use Magento\Sales\Api\Data\OrderInterface; class DisplayCustomValue extends \Magento\Backend\Block\Template { public function __construct( \Magento\Backend\Block\Widget\Context $context, OrderInterface $orderInterface, array $data = [] ) { $this->orderInterface = $orderInterface; parent::__construct($context, $data); } public function getAgree(){ $orderId = $this->getRequest()->getParam('order_id'); $order = $this->orderInterface->load($orderId); return $order->getAgree(); } } |
That’s it.
Any other doubts about this solution can be mentioned in the Comments section below.
I’d be happy to help.
Also, do share the solution with the Magento Community via social media.
Thank you.
Get Weekly Updates
Never miss Magento tips, tricks, tutorials, and news.
Thank you for subscribing.
Something went wrong.