There is a simple solution for this. We should override the checkout success page in your custom theme: app/design/frontend/{Vendor}/{Theme}/Magento_Checkout/templates/success.phtml
.
Or, we can reference the container order.success.additional.info
{Vendor}/{Module}/view/frontend/layout/checkout_onepage_success.xml
<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<body>
<referenceContainer name="order.success.additional.info">
<block class="{Vendor}\{Module}\Block\YourCustomBlock" name="onepage.success.custom" template="your_custom_template.phtml"/>
</referenceContainer>
</body>
</page>
If it's checkout and it is displayed in console it's possible that is ajax. Maybe try to send back html with text of messages in json an then display it using javascript file responsible for this section of page. Search in core controllers for example of json response cooperating with message manager.
EDIT
Here you have my controller class for custom newsletter ajax module:
use \Magento\Customer\Api\AccountManagementInterface as CustomerAccountManagement;
use \Magento\Customer\Model\Session;
use \Magento\Customer\Model\Url as CustomerUrl;
use \Magento\Framework\App\Action\Context;
use \Magento\Framework\Controller\Result\JsonFactory;
use \Magento\Framework\View\LayoutFactory;
use \Magento\Newsletter\Controller\Subscriber\NewAction;
use \Magento\Newsletter\Model\SubscriberFactory;
use \Magento\Store\Model\StoreManagerInterface;
class NewAjax extends NewAction
{
/**
* @var \Magento\Framework\Controller\Result\JsonFactory
*/
protected $resultJsonFactory;
/**
* @var \Magento\Framework\View\LayoutFactory
*/
protected $layoutFactory;
/**
* Di.
*
* @param \Magento\Customer\Api\AccountManagementInterface $customerAccountManagement
* @param \Magento\Customer\Model\Session $customerSession
* @param \Magento\Customer\Model\Url $customerUrl
* @param \Magento\Framework\App\Action\Context $context
* @param \Magento\Framework\Controller\Result\JsonFactory $resultJsonFactory
* @param \Magento\Framework\View\LayoutFactory $layoutFactory
* @param \Magento\Newsletter\Model\SubscriberFactory $subscriberFactory
* @param \Magento\Store\Model\StoreManagerInterface $storeManager
*/
public function __construct(
CustomerAccountManagement $customerAccountManagement,
Session $customerSession,
CustomerUrl $customerUrl,
Context $context,
JsonFactory $resultJsonFactory,
LayoutFactory $layoutFactory,
SubscriberFactory $subscriberFactory,
StoreManagerInterface $storeManager
)
{
parent::__construct($context, $subscriberFactory, $customerSession,
$storeManager, $customerUrl, $customerAccountManagement);
$this->resultJsonFactory = $resultJsonFactory;
$this->layoutFactory = $layoutFactory;
}
/**
* Ajax way of adding subscription. Uses parent action for validation + response with '<div>' containing error/success
* messages.
*
* @return \Magento\Framework\Controller\Result\Json
*/
public function execute()
{
if ($this->getRequest()->isPost() && $this->getRequest()->getPost('email')) {
$email = (string)$this->getRequest()->getPost('email');
$block = $this->layoutFactory->create()->getMessagesBlock();
$error = false;
try {
$this->validateEmailFormat($email);
$this->validateGuestSubscription();
$this->validateEmailAvailable($email);
$status = $this->_subscriberFactory->create()->subscribe($email);
if ($status == \Magento\Newsletter\Model\Subscriber::STATUS_NOT_ACTIVE) {
$this->messageManager->addSuccessMessage(__('The confirmation request has been sent.'));
} else {
$this->messageManager->addSuccessMessage(__('Thank you for your subscription.'));
}
} catch (\Magento\Framework\Exception\LocalizedException $e) {
$error = true;
$this->messageManager->addExceptionMessage(
$e,
__('There was a problem with the subscription: %1', $e->getMessage())
);
} catch (\Exception $e) {
$error = true;
$this->messageManager->addExceptionMessage($e, __('Something went wrong with the subscription.'));
}
}
$block->setMessages($this->messageManager->getMessages(true));
$resultJson = $this->resultJsonFactory->create();
return $resultJson->setData([
'messages' => $block->getGroupedHtml(),
'error' => $error
]);
}
}
Key is here:
$block = $this->layoutFactory->create()->getMessagesBlock();
$error = false;
I get message block and prepare error flag. After that you can see that in case of any exception in catch
blocks I change value of error flag. In the end I set messages from messageManager
to my message block and add it to my json response:
$block->setMessages($this->messageManager->getMessages(true));
$resultJson = $this->resultJsonFactory->create();
return $resultJson->setData([
'messages' => $block->getGroupedHtml(),
'error' => $error
]);
After that in my javascript, which gets response from controller I inject into DOM block with messages if flag is true
- in block success
:
function addSubscription(newAjaxUrl)
{
$('body').on('click', '.newsletter-button', function() {
var email = getSubscriptionEmail();
if (validateEmail(email)) {
$.ajax({
showLoader: true,
url: newAjaxUrl,
type: 'post',
data: {'email': email},
dataType: 'json',
success: function (result) {
clearMessage();
$(result.messages).insertAfter('.foot-mess');
clearEmailInput();
fadeOutEmail();
},
error: function (jqXHR, textStatus, errorThrown) {
clearMessage();
console.error(textStatus + ' ' + jqXHR.status + ': ' + errorThrown);
}
});
} else {
clearMessage();
$('.newsletter-ajax-input').addClass('newsletter-ajax-input mage-error');
$(FRONTEND_VALIDATION_MESSAGE).insertAfter('.foot-mess');
}
});
Please note that it is done outside of checkout so it can give some directions and advices but you would not be able to adopt it completely. Although it show message manager can be used in ajax calls.
Best Answer
After so much investigation and implementation, I found a solution to display custom error message on checkout page.
1) Override a shipping.js file (vendor\magento\module-checkout\view\frontend\web\js\view\shipping.js) into your custom theme (app\design\frontend\Vendor\Theme\Module_Checkout\web\js\view\shipping.js):
2) Add your ajax call into setShippingInformation() function as follows:
3) Check pincode valid or not using ajax call (Namepsace/PincodeChecker/Controller/Ajax/CheckPincode) as follows:
4) Delete
var
folder, delete files and folder frompub/static/frontend/
5) Run php bin/magento setup:static-content:deploy -f in terminal.
I hope this solution may help to anyone. :)