Como: Crear una pagina de success diferente para un método de pago en Magento2
Esta semana, me asignaron la tarea de crear una página de success diferente para un método de pago específico.
La idea era que si un cliente seleccionaba el método de pago Transferencia Bancaria, fuese redirigido a
https://magento2.test/checkout/banktransfer/success
.
Por el contrario si el cliente selecciona cualquier otro método de pago, debería ser redirigido a la página de success por defecto,
es decir https://magento2.test/checkout/onepage/success/
.
Parece simple verdad?, veamos como se puede lograr esto.
Este post asume que existe ya un módulo de Magento con la ruta app/code/Vendor/BanckTransfer
. Si necesitas saber
como crear un nuevo module, te recomiendo que le eches un vistazo a Cómo crear un nuevo módulo para Magento 2.
Requerimientos
- Primero que nada necesitamos un controlador que responda a las peticiones en la Url
https://magento2.test/checkout/BanckTransfer/success
. - Luego, necesitaremos que el checkout redirija a la nueva Url, solo cuando Transferencia bancaria sea seleccionado como método de pago.
El Controlador
Antes de crear el controlador, primero especificamos el route.
<?xml version="1.0"?>
<!--//app/code/Vendor/BanTransfer/etc/frontend/routes.xml -->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd">
<router id="standard">
<route id="checkout">
<module name="Vendor_BanTransfer"/>
</route>
</router>
</config>
Nota: Debido a que estamos agregando una página adicional al pago, usamos checkout
para la ruta y no necesitamos especificar un frontName.
A continuación, debemos asegurarnos de que nuestro módulo extienda Magento_Checkout
. Si no lo hacemos, nuestra página de éxito personalizada no funcionará.
Además y debido a que vamos a modificar el comportamiento del método de pago Transferencia Bancaria, (método que viene con Magento), necesitamos cargar nuestro módulo personalizado DESPUÉS.
<?xml version="1.0"?>
<!--//app/code/Vendor/BanTransfer/etc/module.xml -->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
<module name="Vendor_BanTransfer" setup_version="1.0.0">
<sequence>
<module name="Magento_Checkout"/>
<module name="Magento_OfflinePayments"/>
</sequence>
</module>
</config>
Con estos dos cambios implementados, ahora podemos proceder a crear el Controlador.
<?php
/** app/code/Vendor/BanTransfer/Controller/BanTransfer/Success.php */
namespace Vendor\BanTransfer\Controller\BanTransfer;
use Magento\Checkout\Model\Session\SuccessValidator;
use Magento\Checkout\Model\Type\Onepage;
use Magento\Framework\App\Action\Action;
use Magento\Framework\App\Action\Context;
use Magento\Framework\App\ResponseInterface;
use Magento\Framework\Controller\Result\Redirect;
use Magento\Framework\Controller\ResultInterface;
use Magento\Framework\View\Result\Page;
use Magento\Framework\View\Result\PageFactory;
class Success extends Action
{
/**
* @var SuccessValidator
*/
private $successValidator;
/**
* @var Onepage
*/
private $onepage;
/**
* @var PageFactory
*/
private $resultPageFactory;
/**
* Success constructor.
* @param SuccessValidator $successValidator
* @param Onepage $onepage
* @param PageFactory $resultPageFactory
* @param Context $context
*/
public function __construct(
SuccessValidator $successValidator,
Onepage $onepage,
PageFactory $resultPageFactory,
Context $context
) {
$this->successValidator = $successValidator;
$this->onepage = $onepage;
$this->resultPageFactory = $resultPageFactory;
parent::__construct($context);
}
/**
* @return ResponseInterface|Redirect|ResultInterface|Page
*/
public function execute()
{
$checkout = $this->onepage->getCheckout();
if (!$this->successValidator->isValid()) {
return $this->resultRedirectFactory->create()->setPath('checkout/cart');
}
$checkout->clearQuote();
$resultPage = $this->resultPageFactory->create();
$this->_eventManager->dispatch(
'checkout_onepage_controller_success_action',
['order_ids' => [$checkout->getLastOrderId()]]
);
return $resultPage;
}
}
Puedes ver que esto es prácticamente una copia del controlador en vendor/magento/module-checkout/Controller/Onepage/Success.php
.
Ahora necesitamos crear un layout para especificar el archivo de plantilla.
<?xml version="1.0"?>
<!-- // app/code/Vendor/BanTransfer/view/frontend/layout/checkout_banTransfer_success.xml -->
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="1column" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<head>
<title>BanTransfer Success Page</title>
</head>
<body>
<referenceBlock name="page.main.title">
<block class="Magento\Checkout\Block\Onepage\Success" name="checkout.success.print.button" template="Magento_Checkout::button.phtml"/>
<action method="setPageTitle">
<argument translate="true" name="title" xsi:type="string">Thank you for your purchase!</argument>
</action>
</referenceBlock>
<referenceContainer name="content">
<block class="Magento\Checkout\Block\Onepage\Success" name="checkout.success" template="Vendor_BanTransfer::checkout/success.phtml" cacheable="false">
<container name="order.success.additional.info" label="Order Success Additional Info"/>
</block>
<block class="Magento\Checkout\Block\Registration" name="checkout.registration" template="Magento_Checkout::registration.phtml" cacheable="false"/>
</referenceContainer>
</body>
</page>
Nuevamente, esta es una copia del archivo en vendor/magento/module-checkout/view/frontend/layout/checkout_onepage_success.xml
. La única diferencia es el success.phtml
donde especificamos nuestra plantilla personalizada.
Finalmente, crearemos el archivo de plantilla que se renderizará cuando un cliente visite la nueva URL.
<?php /** app/code/Vendor/BanTransfer/view/frontend/templates/checkout/success.phtml */ ?>
<?php /** @var $block \Magento\Checkout\Block\Onepage\Success */ ?>
<div class="checkout-success">
<?php if ($block->getOrderId()):?>
<?php if ($block->getCanViewOrder()) :?>
<p><?= __('Your order number is: %1.', sprintf('<a href="%s" class="order-number"><strong>%s</strong></a>', $block->escapeHtml($block->getViewOrderUrl()), $block->escapeHtml($block->getOrderId()))) ?></p>
<?php else :?>
<p><?= __('Your order # is: <span>%1</span>.', $block->escapeHtml($block->getOrderId())) ?></p>
<?php endif;?>
<p><?= /* @escapeNotVerified */ __('We\'ll email you an order confirmation with details and tracking info.') ?></p>
<?php endif;?>
<?= $block->getAdditionalInfoHtml() ?>
<div class="actions-toolbar">
<div class="primary">
<a class="action primary continue" href="<?= /* @escapeNotVerified */ $block->getContinueUrl() ?>"><span><?= /* @escapeNotVerified */ __('Continue Shopping') ?></span></a>
</div>
</div>
</div>
Hasta este punto, tenemos ya creado un controlador que responderá a la solicitud cuando el cliente visite la url https://magento2.test/checkout/banTransfer/success
ahora necesitamos un mecanismo para redirigir a los clientes a la nueva URL cuando se realice un pedido utilizando el método de pago mediante transferencia bancaria.
La Redirección (The Redirect)
<?xml version="1.0"?>
<!-- // app/code/Vendor/BanTransfer/view/frontend/layout/checkout_index_index.xml-->
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 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="renders" xsi:type="array">
<item name="children" xsi:type="array">
<item name="offline-payments" xsi:type="array">
<item name="component" xsi:type="string">Vendor_BanTransfer/js/view/payment/offline-payments</item>
<item name="methods" xsi:type="array">
<item name="banktransfer" xsi:type="array">
<item name="isBillingAddressRequired" xsi:type="boolean">true</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</argument>
</arguments>
</referenceBlock>
</body>
</page>
A continuación, creamos el archivo del componente
// app/code/Vendor/BanTransfer/view/frontend/web/js/view/payment/offline-payments.js
define([
'uiComponent',
'Magento_Checkout/js/model/payment/renderer-list'
], function (Component, rendererList) {
'use strict';
rendererList.push(
{
type: 'checkmo',
component: 'Magento_OfflinePayments/js/view/payment/method-renderer/checkmo-method'
},
{
type: 'banktransfer',
component: 'Vendor_BanTransfer/js/view/payment/method-renderer/banktransfer-method'
},
{
type: 'cashondelivery',
component: 'Magento_OfflinePayments/js/view/payment/method-renderer/cashondelivery-method'
},
{
type: 'purchaseorder',
component: 'Magento_OfflinePayments/js/view/payment/method-renderer/purchaseorder-method'
}
);
return Component.extend({});
});
Por último, agregamos el nuevo archivo banktransfer-method
.
// app/code/Vendor/Finance/view/frontend/web/js/view/payment/offline-payments.js
define([
'uiComponent',
'Magento_Checkout/js/model/payment/renderer-list'
], function (Component, rendererList) {
'use strict';
rendererList.push(
{
type: 'checkmo',
component: 'Magento_OfflinePayments/js/view/payment/method-renderer/checkmo-method'
},
{
type: 'banktransfer',
component: 'Vendor_Finance/js/view/payment/method-renderer/banktransfer-method'
},
{
type: 'cashondelivery',
component: 'Magento_OfflinePayments/js/view/payment/method-renderer/cashondelivery-method'
},
{
type: 'purchaseorder',
component: 'Magento_OfflinePayments/js/view/payment/method-renderer/purchaseorder-method'
}
);
return Component.extend({});
});
Antes de probar el resultado en el frontend, recuerda borrar la caché.