1

I followed this for buy now

Module Directory:

|   registration.php
|   
+---Controller
|   \---Cart
|           Add.php
|           
+---etc
|   |   module.xml
|   |   
|   \---frontend
|           routes.xml
|           sections.xml
|           
\---view
    \---frontend
        +---layout
        |       catalog_product_view.xml
        |       
        +---templates
        |       buynow.phtml
        |       
        \---web
            \---js
                    buy-now.js

Add.php

<?php

namespace AAllen\BuyNow\Controller\Cart;


class Add extends \Magento\Checkout\Controller\Cart\Add
{
    /**
     * Add product to shopping cart action
     *
     * @return \Magento\Framework\Controller\Result\Redirect
     * @SuppressWarnings(PHPMD.CyclomaticComplexity)
     */
    public function execute()
    {
        if (!$this->_formKeyValidator->validate($this->getRequest())) {
            return $this->resultRedirectFactory->create()->setPath('*/*/');
        }

        $params = $this->getRequest()->getParams();
        try {
            if (isset($params['qty'])) {
                $filter = new \Zend_Filter_LocalizedToNormalized(
                    ['locale' => $this->_objectManager->get('Magento\Framework\Locale\ResolverInterface')->getLocale()]
                );
                $params['qty'] = $filter->filter($params['qty']);
            }

            $product = $this->_initProduct();
            $related = $this->getRequest()->getParam('related_product');

            /**
             * Check product availability
             */
            if (!$product) {
                return $this->goBack();
            }

            // empty the cart.
            $this->cart->truncate();

            $this->cart->addProduct($product, $params);
            if (!empty($related)) {
                $this->cart->addProductsByIds(explode(',', $related));
            }

            $this->cart->save();

            /**
             * @todo remove wishlist observer \Magento\Wishlist\Observer\AddToCart
             */
            $this->_eventManager->dispatch(
                'checkout_cart_add_product_complete',
                ['product' => $product, 'request' => $this->getRequest(), 'response' => $this->getResponse()]
            );

            if (!$this->_checkoutSession->getNoCartRedirect(true)) {
                $baseUrl = $this->_objectManager->get('\Magento\Store\Model\StoreManagerInterface')
                        ->getStore()->getBaseUrl();
                // redirect to checkout page
                return $this->goBack($baseUrl.'checkout/', $product);
            }
        } catch (\Magento\Framework\Exception\LocalizedException $e) {
            if ($this->_checkoutSession->getUseNotice(true)) {
                $this->messageManager->addNotice(
                    $this->_objectManager->get('Magento\Framework\Escaper')->escapeHtml($e->getMessage())
                );
            } else {
                $messages = array_unique(explode("\n", $e->getMessage()));
                foreach ($messages as $message) {
                    $this->messageManager->addError(
                        $this->_objectManager->get('Magento\Framework\Escaper')->escapeHtml($message)
                    );
                }
            }

            $url = $this->_checkoutSession->getRedirectUrl(true);

            if (!$url) {
                $cartUrl = $this->_objectManager->get('Magento\Checkout\Helper\Cart')->getCartUrl();
                $url = $this->_redirect->getRedirectUrl($cartUrl);
            }

            return $this->goBack($url);

        } catch (\Exception $e) {
            $this->messageManager->addException($e, __('We can\'t add this item to your shopping cart right now.'));
            $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
            return $this->goBack();
        }
    }
}

routes.xml

<?xml version="1.0"?>

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd">
    <router id="standard">
        <route id="buynow" frontName="buynow">
            <module name="AAllen_BuyNow"/>
        </route>
    </router>
</config>

sections.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Customer:etc/sections.xsd">
    <action name="buynow/cart/add">
        <section name="cart"/>
    </action>
</config>

catalog_product_view.xml

<?xml version="1.0"?>
<page layout="1column" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <body>
        <referenceBlock name="product.info.addtocart">

            <block class="Magento\Framework\View\Element\Template" template="AAllen_BuyNow::buynow.phtml"/>
        </referenceBlock>
        <referenceBlock name="product.info.addtocart.additional">

            <block class="Magento\Framework\View\Element\Template" template="AAllen_BuyNow::buynow.phtml"/>
        </referenceBlock>
    </body>
</page>

buynow.phtml

<button type="submit" title="<?php /* @escapeNotVerified */ echo __('Buy Now') ?>" id="buy-now" class="action buynow primary" data-mage-init='
{
    "AAllen_BuyNow/js/buy-now": {
        "form": "#product_addtocart_form"
    }
}
'>
    <span><?php /* @escapeNotVerified */ echo __('Buy Now') ?></span>
</button>

buy-now.js

define([
    'jquery'
], function ($) {
    "use strict";

    return function (config, element) {

        $(element).click(function () {
            var form = $(config.form);

            // change form action
            var baseUrl = form.attr('action'),
                buyNowUrl = baseUrl.replace('checkout/cart/add', 'buynow/cart/add');

            form.attr('action', buyNowUrl);

            form.trigger('submit');

            // set form action back
            form.attr('action', baseUrl);

            return false;
        });
    }
});

it working fine but on click buy now button it triger add to cart then it change adding then it redirect to Checkout

enter image description here

1

Add To Cart button is bind with form. When form.trigger('submit'); this fire submit form, it will call original submit.

Open following js:

vendor/magento/module-catalog/view/frontend/web/js/catalog-add-to-cart.js

ajaxSubmit: function (form) {
    var self = this,
        productIds = idsResolver(form),
        formData;

    $(self.options.minicartSelector).trigger('contentLoading');
    self.disableAddToCartButton(form);
    formData = new FormData(form[0]);

    $.ajax({
        url: form.attr('action'),
        data: formData,
        type: 'post',
        dataType: 'json',
        cache: false,
        contentType: false,
        processData: false,

        /** @inheritdoc */
        beforeSend: function () {
            if (self.isLoaderEnabled()) {
                $('body').trigger(self.options.processStart);
            }
        },

        /** @inheritdoc */
        success: function (res) {
            var eventData, parameters;

            $(document).trigger('ajax:addToCart', {
                'sku': form.data().productSku,
                'productIds': productIds,
                'form': form,
                'response': res
            });

            if (self.isLoaderEnabled()) {
                $('body').trigger(self.options.processStop);
            }

            if (res.backUrl) {
                eventData = {
                    'form': form,
                    'redirectParameters': []
                };
                // trigger global event, so other modules will be able add parameters to redirect url
                $('body').trigger('catalogCategoryAddToCartRedirect', eventData);

                if (eventData.redirectParameters.length > 0) {
                    parameters = res.backUrl.split('#');
                    parameters.push(eventData.redirectParameters.join('&'));
                    res.backUrl = parameters.join('#');
                }

                self._redirect(res.backUrl);

                return;
            }

            if (res.messages) {
                $(self.options.messagesSelector).html(res.messages);
            }

            if (res.minicart) {
                $(self.options.minicartSelector).replaceWith(res.minicart);
                $(self.options.minicartSelector).trigger('contentUpdated');
            }

            if (res.product && res.product.statusText) {
                $(self.options.productStatusSelector)
                    .removeClass('available')
                    .addClass('unavailable')
                    .find('span')
                    .html(res.product.statusText);
            }
            self.enableAddToCartButton(form);
        },

        /** @inheritdoc */
        error: function (res) {
            $(document).trigger('ajax:addToCart:error', {
                'sku': form.data().productSku,
                'productIds': productIds,
                'form': form,
                'response': res
            });
        },

        /** @inheritdoc */
        complete: function (res) {
            if (res.state() === 'rejected') {
                location.reload();
            }
        }
    });
},

Where changed the add to cart button text and submitted form by ajax.

disableAddToCartButton: function (form) {
    var addToCartButtonTextWhileAdding = this.options.addToCartButtonTextWhileAdding || $t('Adding...'),
        addToCartButton = $(form).find(this.options.addToCartButtonSelector);

    addToCartButton.addClass(this.options.addToCartButtonDisabledClass);
    addToCartButton.find('span').text(addToCartButtonTextWhileAdding);
    addToCartButton.attr('title', addToCartButtonTextWhileAdding);
},

Now in your controller

$baseUrl = $this->_objectManager->get('\Magento\Store\Model\StoreManagerInterface')
    ->getStore()->getBaseUrl();
// redirect to checkout page
return $this->goBack($baseUrl.'checkout/', $product);

Which return redirected to checkout page.

[Updated]

You need to unbind form. Modify buy-now.js the following way:

define([
    'jquery'
], function ($) {
    "use strict";

    return function (config, element) {

        $(element).click(function (event) {
            event.preventDefault();
            event.stopImmediatePropagation();
            $(config.form).unbind();
            var form = $(config.form);
            // change form action
            var baseUrl = form.attr('action'),
                buyNowUrl = baseUrl.replace('checkout/cart/add', 'buynow/cart/add');

            form.attr('action', buyNowUrl);

            form.trigger('submit');

            // set form action back
            form.attr('action', baseUrl);

            return false;
        });
    }
});
  • What is the solution on this – Magento 2 Apr 13 at 17:27
  • What is your question? – Sohel Rana Apr 13 at 17:32
  • that adding should not come on click buy now – Magento 2 Apr 13 at 17:33
  • Check updated answer. – Sohel Rana Apr 13 at 18:01
  • Also change the button type from submit to button – Sohel Rana Apr 13 at 18:08

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.