.. rst-class:: outdated How to customize Sylius Checkout? ================================= .. danger:: We're sorry but **this documentation section is outdated**. Please have that in mind when trying to use it. You can help us making documentation up to date via Sylius Github. Thank you! Why would you override the Checkout process? -------------------------------------------- This is a common problem for many Sylius users. Sometimes the checkout process we have designed is not suitable for your custom business needs. Therefore you need to learn how to modify it, when you will need to for example: * remove shipping step - when you do not ship the products you sell, * change the order of checkout steps, * merge shipping and addressing step into one common step, * or even make the whole checkout a one page process. See how to do these things below: How to remove a step from checkout? ----------------------------------- Let's imagine that you are trying to create a shop that does not need shipping - it sells downloadable files only. To meet your needs you will need to adjust checkout process. **What do you have to do then?** See below: Overwrite the state machine of Checkout ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Open the `CoreBundle/Resources/config/app/state_machine/sylius_order_checkout.yml `_ and place its content in the ``src/Resources/SyliusCoreBundle/config/app/state_machine/sylius_order_checkout.yml`` which is a `standard procedure of overriding configs in Symfony `_. Remove the ``shipping_selected`` and ``shipping_skipped`` states, ``select_shipping`` and ``skip_shipping`` transitions. Remove the ``select_shipping`` and ``skip_shipping`` transition from the ``sylius_process_cart`` callback. .. code-block:: yaml # app/Resources/SyliusCoreBundle/config/app/state_machine/sylius_order_checkout.yml winzou_state_machine: sylius_order_checkout: class: "%sylius.model.order.class%" property_path: checkoutState graph: sylius_order_checkout state_machine_class: "%sylius.state_machine.class%" states: cart: ~ addressed: ~ payment_skipped: ~ payment_selected: ~ completed: ~ transitions: address: from: [cart, addressed, payment_selected, payment_skipped] to: addressed skip_payment: from: [addressed] to: payment_skipped select_payment: from: [addressed, payment_selected] to: payment_selected complete: from: [payment_selected, payment_skipped] to: completed callbacks: after: sylius_process_cart: on: ["address", "select_payment"] do: ["@sylius.order_processing.order_processor", "process"] args: ["object"] sylius_create_order: on: ["complete"] do: ["@sm.callback.cascade_transition", "apply"] args: ["object", "event", "'create'", "'sylius_order'"] sylius_save_checkout_completion_date: on: ["complete"] do: ["object", "completeCheckout"] args: ["object"] sylius_skip_shipping: on: ["address"] do: ["@sylius.state_resolver.order_checkout", "resolve"] args: ["object"] priority: 1 sylius_skip_payment: on: ["address"] do: ["@sylius.state_resolver.order_checkout", "resolve"] args: ["object"] priority: 1 .. tip:: To check if your new state machine configuration is overriding the old one run: ``php bin/console debug:winzou:state-machine`` and check the configuration of ``sylius_order_checkout``. Adjust Checkout Resolver ~~~~~~~~~~~~~~~~~~~~~~~~ The next step of customizing Checkout is to adjust the Checkout Resolver to match the changes you have made in the state machine. .. code-block:: yaml # config/packages/sylius_shop.yaml sylius_shop: checkout_resolver: pattern: /checkout/.+ route_map: cart: route: sylius_shop_checkout_address addressed: route: sylius_shop_checkout_select_payment payment_selected: route: sylius_shop_checkout_complete payment_skipped: route: sylius_shop_checkout_complete Adjust Checkout Templates ~~~~~~~~~~~~~~~~~~~~~~~~~ After you have got the resolver adjusted, modify the templates for checkout. You have to remove shipping from steps and disable the hardcoded ability to go back to the shipping step and the number of steps being displayed in the checkout navigation. You will achieve that by overriding two files: * `ShopBundle/Resources/views/Checkout/_steps.html.twig `_ * `ShopBundle/Resources/views/Checkout/SelectPayment/_navigation.html.twig `_ .. code-block:: twig {# templates/SyliusShopBundle/Checkout/_steps.html.twig #} {% if active is not defined or active == 'address' %} {% set steps = {'address': 'active', 'select_payment': 'disabled', 'complete': 'disabled'} %} {% elseif active == 'select_payment' %} {% set steps = {'address': 'completed', 'select_payment': 'active', 'complete': 'disabled'} %} {% else %} {% set steps = {'address': 'completed', 'select_payment': 'completed', 'complete': 'active'} %} {% endif %} {% set order_requires_payment = sylius_is_payment_required(order) %} {% set steps_count = 'three' %} {% if not order_requires_payment %} {% set steps_count = 'two' %} {% endif %}
{{ 'sylius.ui.address'|trans }}
{{ 'sylius.ui.fill_in_your_billing_and_shipping_addresses'|trans }}
{% if order_requires_payment %}
{{ 'sylius.ui.payment'|trans }}
{{ 'sylius.ui.choose_how_you_will_pay'|trans }}
{% endif %}
{{ 'sylius.ui.complete'|trans }}
{{ 'sylius.ui.review_and_confirm_your_order'|trans }}
.. code-block:: twig {# templates/SyliusShopBundle/Checkout/SelectPayment/_navigation.html.twig #} {% set enabled = order.payments|length %}
Overwrite routing for Checkout ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Unfortunately there is no better way - you have to overwrite the whole routing for Checkout. To do that copy the content of `ShopBundle/Resources/config/routing/checkout.yml `_ to the ``app/Resources/SyliusShopBundle/config/routing/checkout.yml`` file. **Remove routing** of ``sylius_shop_checkout_select_shipping``. The rest should remain the same. .. code-block:: yaml # app/Resources/SyliusShopBundle/config/routing/checkout.yml sylius_shop_checkout_start: path: / methods: [GET] defaults: _controller: Symfony\Bundle\FrameworkBundle\Controller\RedirectController:redirectAction route: sylius_shop_checkout_address sylius_shop_checkout_address: path: /address methods: [GET, PUT] defaults: _controller: sylius.controller.order:updateAction _sylius: event: address flash: false template: SyliusShopBundle:Checkout:address.html.twig form: type: Sylius\Bundle\CoreBundle\Form\Type\Checkout\AddressType options: customer: expr:service('sylius.context.customer').getCustomer() repository: method: find arguments: - "expr:service('sylius.context.cart').getCart()" state_machine: graph: sylius_order_checkout transition: address sylius_shop_checkout_select_payment: path: /select-payment methods: [GET, PUT] defaults: _controller: sylius.controller.order:updateAction _sylius: event: payment flash: false template: SyliusShopBundle:Checkout:selectPayment.html.twig form: Sylius\Bundle\CoreBundle\Form\Type\Checkout\SelectPaymentType repository: method: find arguments: - "expr:service('sylius.context.cart').getCart()" state_machine: graph: sylius_order_checkout transition: select_payment sylius_shop_checkout_complete: path: /complete methods: [GET, PUT] defaults: _controller: sylius.controller.order:updateAction _sylius: event: complete flash: false template: SyliusShopBundle:Checkout:complete.html.twig repository: method: find arguments: - "expr:service('sylius.context.cart').getCart()" state_machine: graph: sylius_order_checkout transition: complete redirect: route: sylius_shop_order_pay parameters: tokenValue: resource.tokenValue form: type: Sylius\Bundle\CoreBundle\Form\Type\Checkout\CompleteType options: validation_groups: 'sylius_checkout_complete' .. tip:: If you do not see any changes run ``php bin/console cache:clear``. Learn more ---------- * :doc:`Checkout - concept Documentation ` * :doc:`State Machine - concept Documentation ` * :doc:`Customization Guide `