4

When using standard checkout in magento 2, I want to place checkbox with address above my payment methods: enter image description here

I think I have to meddle with knockout JS which I have no experience in. Anyone knows where to start?

6 Answers 6

12

Starting from Magento 2.1.4 release, the checkout configuration has additional Display Billing Address On option (Stores -> Configuration -> Checkout -> Checkout Options). It has two possible values:

  • Payment Method - billing address is displayed per payment method

  • Payment Page - billing address is displayed above payment methods

The second option should solve your problem without any changes in the code base. Also, it might be useful for some methods like PayPal Express Checkout and allows to set billing address different to shipping.

3
5

I found it myself. Here is the solution

We have to override the payment.html in the checkout module. Copy this file;

\magento\module-checkout\view\frontend\web\template\payment.html 

and place it in your custom theme (we have to create a custom theme for this) with the following structure;

\your-theme\Magento_Checkout\web\template\payment.html

In this file we place

  <!-- ko foreach: getRegion('afterMethods') -->
      <!-- ko template: getTemplate() --><!-- /ko -->
  <!-- /ko -->

just underneath the beforeMethods Like this:

 <!-- ko foreach: getRegion('beforeMethods') -->
    <!-- ko template: getTemplate() --><!-- /ko -->
 <!-- /ko -->
 <!-- ko foreach: getRegion('afterMethods') -->
    <!-- ko template: getTemplate() --><!-- /ko -->
 <!-- /ko -->

Delete your caches in var/view_processed/ and the contents inside pub/static/frontend/.

Do a php bin/magento setup:static-content:deploy in your root and after that a php bin/magento cache:flush

2
  • What to do if want to move below payment methods section not inside payment methods? Commented Jan 12, 2018 at 6:10
  • It works! Thank you for sharing
    – Silver
    Commented Oct 21, 2019 at 17:05
4

The checked answer might work but is not correct itself. You can't just move the place of the methods. Instead you must move the form itself to beforeMethods.

See https://magento.stackexchange.com/a/170732/42007 You need to create a plugin like in that answer but instead of moving the billing form to the shipping step you just need to move it from the afterMethods to beforeMethods of the billing-step. Something like this:

$jsLayout['components']['checkout']['children']['steps']['children']['billing-step']['children']['payment']['children']['beforeMethods']['children']['billing-address-form'] = $jsLayout['components']['checkout']['children']['steps']['children']['billing-step']['children']['payment']['children']['afterMethods']['children']['billing-address-form'];

unset($jsLayout['components']['checkout']['children']['steps']['children']['billing-step']['children']['payment']['children']['afterMethods']['children']['billing-address-form']);

return $jsLayout;
1
  • Thanks @steros your solution is solved my problem Commented May 31, 2019 at 10:14
1

You can use flexbox css :

#co-payment-form .fieldset {
display: -webkit-flex;
-webkit-flex-direction: column;
display: flex;
flex-direction: column;
}

.checkout-billing-address {
 flex:1;
 order: 1;
}

.opc-payment {
flex:1;
order: 2;
}

.opc-payment-additional {
flex:1;
order: 3;
}

Job done !! Must be adapted to your magento configuration and theme.

0

Display Billing Address On Payment Method + PayPal Method

If like me, you are required to set Display Billing Address On = Payment Method in

Admin > Stores > Configuration > Sales > Checkout > Checkout Options

But want to force display billing addresses for the PayPal payment method as well. Then you can do the following:

Overwrite: Magento_Paypal::payment/paypal-express.html within your theme:

......
    <div class="payment-method-content">
        <!-- ko foreach: getRegion('messages') -->
        <!-- ko template: getTemplate() --><!-- /ko -->
        <!--/ko-->
        <div class="payment-method-billing-address">
            <!-- ko foreach: $parent.getRegion(getBillingAddressFormName()) -->
            <!-- ko template: getTemplate() --><!-- /ko -->
            <!--/ko-->
        </div>
......

Overwrite: Magento_Paypal::view/payment/method-renderer/paypal-express.js within your theme:

define([
    'Magento_Paypal/js/view/payment/method-renderer/paypal-express-abstract'
], function (Component) {
    'use strict';

    return Component.extend({
        defaults: {
            template: 'Magento_Paypal/payment/paypal-express'
        },
        
        /**
         * @return {String}
         */
        getBillingAddressFormName: function () {
            
            // Hijack the Money / Cheque order billing address functionality here.
            return 'billing-address-form-checkmo';
        }
    });
});

Next, we need to assign the quote address to the order - because this involves manipulating the order data before save, a "before" Plugin (Interceptor) will be appropriate here: In your custom module's di.xml:

......
<type name="Magento\Sales\Api\OrderRepositoryInterface">
        <plugin name="checkout_order_repository_plugin" type="MyVendor\MyModule\Plugin\Api\OrderRepositoryInterfacePlugin" sortOrder="10" />
</type>
......

MyVendor\MyModule\Plugin\Api\OrderRepositoryInterfacePlugin.php

<?php

namespace MyVendor\MyModule\Plugins\Api;

use Magento\Sales\Model\Order;
use Magento\Sales\Api\OrderRepositoryInterface;
use Magento\Quote\Api\CartRepositoryInterface;
use Magento\Quote\Model\Quote\Address\ToOrderAddress;
use Magento\Quote\Model\Quote\Address as QuoteAddress;

class OrderRepositoryInterfacePlugin
{
    /** @var CartRepositoryInterface */
    private $quoteRepository;

    /** @var ToOrderAddress */
    private $addressConverter;

    public function __construct(
        CartRepositoryInterface $quoteRepository,
        ToOrderAddress $addressConverter
    ) {
        $this->quoteRepository = $quoteRepository;
        $this->addressConverter = $addressConverter;
    }

    public function beforeSave(OrderRepositoryInterface $subject, ...$args): array
    {
        /** @var Order $order */
        $order = $args[0];
        if (!$order->getBillingAddress()) {
            if ($order->getShippingAddress()) {
                $order->setBillingAddress($order->getShippingAddress());
            } else if ($order->getQuoteId()) {
                $quote = $this->quoteRepository->get($order->getQuoteId());
                if ($quote && $quote->getBillingAddress()) {
                    $address = ($quote->getBillingAddress() instanceof QuoteAddress) 
                        ? $this->addressConverter->convert($quote->getBillingAddress())
                        : $quote->getBillingAddress();

                    $order->setBillingAddress($address);
                }
            }
        }
        return [$order];
    }
}

0

If you wants to Display Billing Address before Payment Section in Magento 2.4, then you can do it like below

In Magento, the Checkout page is rendered using JS Layout, You need to create a Plugin for the afterProcess to change the position of the billing address.

Vendor\Module\etc\frontend\di.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">

    <!-- Set Billing address above the payment method plugin -->
    <type name="Magento\Checkout\Block\Checkout\LayoutProcessor">
        <plugin name="move_billing_address_above_payment_method"
                type="Vendor\Module\Plugin\Block\Checkout\LayoutProcessor"/>
    </type>
</config>

Vendor\Module\Plugin\Block\Checkout\LayoutProcessor.php

<?php declare(strict_types=1);

namespace Vendor\Module\Plugin\Block\Checkout;

use Magento\Checkout\Block\Checkout\LayoutProcessor as CheckoutLayoutProcessor;

/**
 * Move Billing address to top
 */
class LayoutProcessor
{
    /**
     * @param CheckoutLayoutProcessor $subject
     * @param array $jsLayout
     * @return array
     */
    public function afterProcess(
        CheckoutLayoutProcessor $subject,
        array $jsLayout
    ): array {
        $paymentLayout = $jsLayout['components']['checkout']['children']['steps']
        ['children']['billing-step']['children']['payment']['children'];

        if (isset($paymentLayout['afterMethods']['children']['billing-address-form'])) {
            // Move Billing Address Before the Payment Method
            $jsLayout['components']['checkout']['children']['steps']
            ['children']['billing-step']['children']['payment']['children']
            ['beforeMethods']['children']['billing-address-form']
                = $paymentLayout['afterMethods']['children']['billing-address-form'];

            // remove Billing Address From `Payment Method`
            unset($jsLayout['components']['checkout']['children']['steps']
            ['children']['billing-step']['children']['payment']
            ['children']['afterMethods']['children']['billing-address-form']);
        }

        return $jsLayout;
    }
}

& then we need to change one store config option

Go to Store Config> Sales > Checkout Section & find "Display Billing Address On" Option field in "Checkout Options" & set this field value as a Payment Page

I hope this one helps to anyone

Reference from :- https://www.rakeshjesadiya.com/move-billing-address-before-the-payment-method-checkout-magento/

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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