I have a checkout_cart_product_add_after event that calls to a observer file in which i want to check a condition. If that condition is false i block the product from adding to the cart and want to return a error message to the frontend.

I'm using this code if the condition is true:

            $this->_messageManager->addError(__('your custom message'));
            //set false if you not want to add product to cart
            $observer->getRequest()->setParam('product', false);
            return $this;

but if i do that i get a console error 500 with an error: jQuery.parseJSON requires a valid JSON string.

And the add button to cart button stays on adding...

How can i block the product from adding to the cart but the button also refreshes?


Try using a plugin.


<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    <type name="Magento\Checkout\Controller\Cart\Add">
        <plugin name="sr_product_add" type="SR\MagentoCommunity\Plugin\Checkout\Controller\Cart\Add" sortOrder="1"/>


namespace SR\MagentoCommunity\Plugin\Checkout\Controller\Cart;

use Magento\Framework\Message\ManagerInterface;
use Magento\Framework\Serialize\Serializer\Json;
use Magento\Catalog\Api\ProductRepositoryInterface;
use Magento\Store\Model\StoreManagerInterface;

class Add
     * @var ManagerInterface
    private $messageManager;

     * @var Json
    private $json;

     * @var ProductRepositoryInterface
    private $productRepository;

     * @var StoreManagerInterface
    private $storeManager;

     * Add constructor.
     * @param ManagerInterface $messageManager
     * @param Json $json
     * @param ProductRepositoryInterface $productRepository
     * @param StoreManagerInterface $storeManager
    public function __construct(
        ManagerInterface $messageManager,
        Json $json,
        ProductRepositoryInterface $productRepository,
        StoreManagerInterface $storeManager
    ) {
        $this->messageManager = $messageManager;
        $this->json = $json;
        $this->productRepository = $productRepository;
        $this->storeManager = $storeManager;

    public function aroundExecute(
        \Magento\Checkout\Controller\Cart\Add $subject,
        \Closure $proceed
    ) {
        $productId = (int) $subject->getRequest()->getParam('product');
        if ($productId) {
            try {
                return $this->productRepository->getById($productId, false, $this->storeManager->getStore()->getId());
            } catch (\Exception $e) {

        if (false) {
            $this->messageManager->addErrorMessage('your custom message');
            $result = [];

            return $subject->getResponse()->representJson(

        return $proceed();
| improve this answer | |
  • Thanks for replying, but how do i use this in my observer function? – Tom291 Mar 7 '19 at 8:00
  • You can't handle this by the observer, because all observers are fire after product add. So if you try by observer then you need to call delete again that product from cart. It easy to handle by plugin. – Sohel Rana Mar 7 '19 at 8:25
  • Okay i understand how it works now. The problem is that i want to get the product object like in observer($observer->getEvent()->getProduct();). Any idea if i can also do that in the Add class? – Tom291 Mar 7 '19 at 8:32
  • Nevermind, i found out that you can retrieve the product id with $product_id = $this->request->getPostValue("product"); and after you can use $product = $objectManager->create('Magento\Catalog\Model\Product')->load($product_id); to retrieve the product object. Thanks! – Tom291 Mar 7 '19 at 11:27
  • Hey, don't use object manager. Try to use repository. – Sohel Rana Mar 7 '19 at 11:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.