WooCommerce Multi-Step Checkout Pro – Documentation

Installation and Updates

  • Download the .zip file from the email you received.
  • Go to: WordPress Admin > Plugins > Add New to upload the file you downloaded with Choose File.
  • Activate the plugin.

More information at: Installing and Managing Plugins.

If you already have the free version of the plugin installed on your website, the PRO version will automatically overtake the configurations from the free version and will disable the free version plugin during the activation. You can choose to keep the disabled free version on your website or you can delete it.

In order to receive unlock all the plugin’s functionality and receive the updates, don’t forget to activate your license, as shown below.

For updates you’ll be notified in the WorPress Admin -> Plugins page and by clicking update now you will receive the latest version.


You can add/remove/modify the steps with the help of PHP snippet that you can add to your child theme’s functions.php file. If you don’t feel comfortable modifying the child theme’s functions.php file, then you can use a plugin similar to Code Snippets.

Removing a step

The following PHP snippet will remove the Billing step:

if ( ! function_exists( 'wmsc_delete_billing_step' ) ) {
	function wmsc_delete_billing_step( $steps ) {
	    unset( $steps['billing'] );
	    return $steps;
add_filter( 'wpmc_modify_steps', 'wmsc_delete_billing_step' );
If you want to remove any of the other steps, then you need to replace the “billing” string with the id of the appropriate step. See “The default step ids and positions” subsection further down in the documentation.

Modifying a step

Any of the steps can be modified by copying the “wmsc_step_content_{id}” function from the plugin’s /includes/settings-array.php file to your child theme’s functions.php file. Then you’ll need to rename the function to something else, for example “wmsc_step_content_{your_id}”. And then use the “wpmc_modify_steps” action to load the step’s content from the new “wmsc_step_content_{your_id}” function. The {id} stands for the step’s id that you wish to change.

For example, to modify the Payment step, you’ll need to copy the wmsc_step_content_payment function from the plugin’s /includes/settings-array.php file to your child theme’s functions.php file and then modify the function’s title from wmsc_step_content_payment to wmsc_step_content_payment_modified:

if ( ! function_exists( 'wmsc_step_content_payment_modified' ) ) {
    function wmsc_step_content_payment_modified() {
        echo '<h3 id="payment_heading">' . __( 'Payment', 'woocommerce' ) . '</h3>';
        echo 'Modify the "Payment" step by adding this message after the "Payment" step header';
        do_action( 'wpmc-woocommerce_checkout_payment' );
        do_action( 'woocommerce_checkout_after_order_review' );
add_action( 'wmsc_step_content_payment_modified', 'wmsc_step_content_payment_modified' );

Now the $steps array needs to be modified in order for it to load the content from the new wmsc_step_content_payment_modified function instead of from the wmsc_step_content_payment function:

if ( ! function_exists( 'wpmc_review_modify_payment_step' ) ) {
    function wpmc_review_modify_payment_step( $steps ) {
        $steps['payment']['sections'] = array( 'payment_modified' );
        return $steps;
add_filter( 'wpmc_modify_steps', 'wpmc_review_modify_payment_step' );

Adding a step

You can use the “wpmc_modify_steps” filter to add a custom step and the “wmsc_step_content_{step_id}” action to add the content to your {step_id} step. The {step_id} is defined by in the “sections” parameter within the the”wpmc_modify_steps” filter. For example the following PHP snippet will add the custom step called “Delivery Time” after the Shipping step:

 * Add the Delivery Time step
if ( ! function_exists( 'wpmc_add_delivery_time_step' ) ) {
	function wpmc_add_delivery_time_step( $steps ) {
	    $steps['delivery'] = array(
		'title'     => __( 'Delivery Time' ),
		'position'  => 25,
		'class'     => 'wpmc-step-delivery',
		'sections'  => array( 'delivery' ),
	    return $steps;
add_filter( 'wpmc_modify_steps', 'wpmc_add_delivery_time_step' );
 * Add content to the Delivery Time step
if ( ! function_exists( 'wmsc_step_content_delivery' ) ) {
    function wmsc_step_content_delivery() {
        echo 'The content of the Delivery Time step';

        // Add the date field called "Choose Date"
        $checkout = WC()->checkout();
        woocommerce_form_field( 'delivery_time', array(
            'type'  => 'date',
            'class' => array('my-field-class form-row-wide'),
            'label' => __('Choose Date'),
        ), $checkout->get_value( 'delivery_time' ) );
add_action( 'wmsc_step_content_delivery', 'wmsc_step_content_delivery' );

* Add your validation rules to the `delivery_time` field
function wmsc_validate_delivery_time_field() {
    if ( ! $_POST['delivery_time'] || empty( $_POST['delivery_time'] ) ) {
        wc_add_notice( __( 'Please enter the delivery time.' ), 'error' );
add_action( 'woocommerce_checkout_process', 'wmsc_validate_delivery_time_field' );

 * Save the `delivery_time` field with the order
function wmsc_save_delivery_time_field( $order_id ){
    if ( ! empty( $_POST['delivery_time'] ) ) {
        update_post_meta( $order_id, 'delivery_time', sanitize_text_field( $_POST['delivery_time'] ) );
add_action( 'woocommerce_checkout_update_order_meta', 'wmsc_save_delivery_time_field' );

As the step’s position is 25, it will be shown between the Shipping and Payment step.

Note that the new step’s content will be inside the checkout <form> element and the HTML standard doesn’t allow to nest forms inside each other. You can add static content to the new step, dynamic content (like Up-Sells) or custom checkout form fields. But you cannot add another form inside the step, as for example a form generated with the Contact 7, Gravity Form or Ninja Forms plugin.

Modifying a step’s position

The following PHP snippet will move the Shipping step into the last position:

if ( ! function_exists( 'wmsc_shipping_step_last' ) ) {
	function wmsc_shipping_step_last( $steps ) { 
	    $steps['shipping']['position'] = 60;
	    return $steps;
add_filter( 'wpmc_modify_steps', 'wmsc_shipping_step_last' ); 

The default step ids and positions

The steps are sorted in ascended order by their “position” parameter.
The Login step, if needed to be shown, will always be on the first position and cannot be removed with the “wpmc_modify_steps” filter. It can be removed only from the WP Admin -> WooCommerce -> Settings -> Accounts & Privacy page.

Custom validation rule in the “step-by-step validation”

If you remove or add the “required” rule to any field with the help of a plugin that modifies the checkout fields, then the WP Multi-Step Checkout Pro plugin will automatically pick up the validation rule modification.

If you want to add a custom validation rule to the checkout fields, then you can register the new validation rule with the “wmsc_custom_validation” hook. For example, the following PHP code snippet will show an error if there are numbers present within the first or the last name in the Billing step:

if ( ! function_exists( 'wmsc_validate_fname_lname' ) ) { 
    function wmsc_validate_fname_lname( $errors, $fields ) { 
        if ( preg_match( '/\\d/', $fields[ 'billing_first_name'] ) ) { 
            $errors[ 'billing_first_name' ] = __( '<b>Billing First name</b> field does not allow numbers.' );
        if ( preg_match( '/\\d/', $fields[ 'billing_last_name'] ) ) { 
            $errors[ 'billing_last_name' ] = __( '<b>Billing Last name</b> field does not allow numbers.' );
        return $errors;
add_action( 'wmsc_custom_validation', 'wmsc_validate_fname_lname', 10, 2 );

Customization examples

Adding a “Cross-Sales” step

Cross-sells are complementary products the buyer might be interested in, which are related to the products he is already buying. See this article on how to set up the cross-sells for your products. For adding a custom step with cross-sells, you’ll need to add the following PHP snippets to your website.

Add the step after Shipping:

if ( ! function_exists( 'wpmc_add_cross_sales_step' ) ) {
    function wpmc_add_cross_sales_step( $steps ) {
        $steps['cross_sales'] = array(
          'title'     => __( 'Cross-Sales' ),
          'position'  => 25,
          'class'     => 'wpmc-step-cross-sales',
          'sections'  => array( 'cross_sales' ),
        return $steps;
add_filter( 'wpmc_modify_steps', 'wpmc_add_cross_sales_step' );
Add the “Cross-Sales” content. Feel free to modify the $orderby, $order, $limit or $columns variables, if needed.

if ( ! function_exists( 'wmsc_step_content_cross_sales' ) ) {
    function wmsc_step_content_cross_sales() {
        $orderby = 'rand';
        $order = 'desc';
        $limit = 2;
        $columns = 2;

        // Get visible cross sells then sort them at random.
        $cross_sells = array_filter( array_map( 'wc_get_product', WC()->cart->get_cross_sells() ), 'wc_products_array_filter_visible' );

        wc_set_loop_prop( 'name', 'cross-sells' );
        wc_set_loop_prop( 'columns', apply_filters( 'woocommerce_cross_sells_columns', $columns ) );
        // Handle orderby and limit results.
        $orderby     = apply_filters( 'woocommerce_cross_sells_orderby', $orderby );
        $order       = apply_filters( 'woocommerce_cross_sells_order', $order );
        $cross_sells = wc_products_array_orderby( $cross_sells, $orderby, $order );
        $limit       = apply_filters( 'woocommerce_cross_sells_total', $limit );
        $cross_sells = $limit > 0 ? array_slice( $cross_sells, 0, $limit ) : $cross_sells;

                'cross_sells'    => $cross_sells,

                // Not used now, but used in previous version of up-sells.php.
                'posts_per_page' => $limit,
                'orderby'        => $orderby,
                'columns'        => $columns,
add_action( 'wmsc_step_content_cross_sales', 'wmsc_step_content_cross_sales' );

Questions & Answers

After registering is the customer redirected to the account page or the next step?
A: To the next step. Normally the “Billing” is the next step after Login/Registration, so in that case the customer will be redirected to the “Billing” step.
Can I edit the “Your personal data will be used to …” text after the Registration form?
A: Yes, you can edit it on the WP Admin -> WooCommerce -> Settings -> Accounts & Privacy page within the “Registration privacy policy” option.
How can I link a certain step?
A: You can link a certain step on the checkout page by adding “#step-0”, “#step-1”, … “#step-4” to the checkout address. For example the http://example.com/checkout/#step-0 URL will link to the first step. The http://example.com/checkout/#step-1 URL will link to the second step, and so on.
How do I remove the “Back” button from the last step?
A: You can do that by adding the following JavaScript code to your website:

    $( '.woocommerce-checkout' ).on( 'wpmc_after_switching_tab', function() {
       if ( $( '.wpmc-tabs-wrapper li.wpmc-tab-item:last-child' ).hasClass( 'current' ) ) {
          $( '#wpmc-prev' ).hide().removeClass( 'current' );
       } else {
          $( '#wpmc-prev' ).show();
Does the plugin collect the email address in the first step to use it for cart abandonment recovery?
A: No, the WP Multi-Step Checkout Pro plugin doesn’t collect the email address. Any cart recovery plugin (like WooCommerce Cart Abandonment Recovery or Abandoned Cart Lite for WooCommerce) will collect it at the moment the “Email Address” field is filled and use it later for sending emails to the possible customer.