Jump to content

Second terms agreement checkbox on checkout page hook


Recommended Posts

  • WHMCS Support Manager

WHMCS can be configured to require clients to agree to a Terms of Service document before placing an order. There may be occasions or regulations which necessitate clients agree with a second separate agreement before they are permitted to place the order (for example a privacy policy).

In this post we are using an action hook which uses three hook points to display the checkbox on the order form checkout page, validate it has been ticked, and optionally perform complete any post-order processing. All in one small file.

Quick Start

You can download this hook in directly by clicking on the following link: additionalAgreement.php

Customise the message and link to be displayed on the checkout page:

I can confirm I have read and agree to the
            <a href="https://www.example.com/" target="_blank">Demo Agreement</a>

Customise the error to be returned if the client does not tick the checkbox:

You must confirm you agree to the Demo Agreement

Save and upload it to the "includes/hooks" directory on your server.

 

Detailed Explanation

Alternatively, you can create a new .php file, preferably named something that let you know what the file does at a glance, in the "includes/hooks" directory on your server. Then you can copy the code below, paste it into your new .php file, and save it.

<?php
/**
 * Example hook to provide an additional agreement requirement in checkout.
 *
 * @copyright Copyright (c) WHMCS Limited 2018
 * @license https://www.whmcs.com/eula/ WHMCS Eula
 */

use App;

add_hook('ClientAreaFooterOutput', 1, function ($vars)
{
    if (!defined('CLIENTAREA')) {
        return false;
    }

    if ($vars['filename'] != 'cart') {
        return false;
    }

    $a = App::getFromRequest('a');
    if (!in_array($a, array('view', 'checkout'))) {
        return false;
    }

    $additionalAgreement = App::getFromRequest('additional_agreement');

    $output = '<div class="text-center">
        <label class="checkbox-inline">
            <input type="checkbox" name="additional_agreement" value="1"' . ($additionalAgreement ? ' checked':'') . ' />
            &nbsp;
            I can confirm I have read and agree to the
            <a href="https://www.example.com/" target="_blank">Demo Agreement</a>
        </label>
    </div>
    <br />';

    return '<script>
    jQuery("#btnCompleteOrder").before("' . preg_replace( "/\r|\n/", "", str_replace('"', '\"', $output)) . '");
</script>';
});

add_hook('ShoppingCartValidateCheckout', 1, function ($vars) {

    $additionalAgreement = App::getFromRequest('additional_agreement');

    if (!$additionalAgreement) {
        return 'You must confirm you agree to the Demo Agreement';
    }
});

add_hook('AfterShoppingCartCheckout', 1, function ($vars) {

    $orderId = $vars['OrderID'];
    $additionalAgreement = App::getFromRequest('additional_agreement');

    if ($additionalAgreement) {
        // Run any additional code post checkout here
        // For example logging of the agreement, time, IP, etc...
    }
});

This hook uses the ClientAreaFooterOutput hook point to first check the current page.

If we are on the checkout page, then it proceeds to define the HTML to display the additional checkbox. This text and link can be be customised to reflect the nature of the agreement in use, and point to the document on your server.

Finally it makes use of JQuery to insert the checkbox above the Complete Order button.

 

Next the hook uses the ShoppingCartValidateCheckout hook point to confirm that the checkbox has been ticked and return an error message alongside the regular validation form errors. This is preferable to purely javascript-based validation which would return the error in a browser prompt and could potentially be bypassed.

 

The last element of this hook file is the AfterShoppingCartCheckout hook point. Whilst not used in this example, this provides a place where you might execute any additional code based upon the particular requirements. For example you may wish to add a record to a custom database table to record the time and date of the order.

 

2018-03-28_11-36-38.png

This hook was tested with the current versions of WHMCS that fall under Active Support as listed at https://docs.whmcs.com/Long_Term_Support#Active_Development and is not guaranteed to work with prior or subsequent versions of WHMCS.

If you have any feedback, comments, or questions concerning this hook then please let me know!

Link to comment
Share on other sites

14 minutes ago, WHMCS John said:

If you have any feedback, comments, or questions concerning this hook then please let me know!

if I was being picky, it would be better if it used language strings rather than hardcoded in English, but I can completely understand why you didn't do that initially - as it would take longer to explain... i've been there myself!

in practice, that's probably best left to the end-user to write any required language strings for themselves relevant to their situation. :idea:

Link to comment
Share on other sites

  • 1 month later...
  • 2 weeks later...
  • WHMCS Support Manager

Hi @cenourinha,

There isn't a similar hook point to ShoppingCartValidateCheckout for the client registration only process. So I don't foresee a quick way this could be validated by the system so as to determine that it becomes a required field.

I'm happy to be proven otherwise, but in the meantime you might need to consider disabling client registration without an order via Setup > General Settings > Other tab.

 

Link to comment
Share on other sites

11 hours ago, MDavid said:

Very good solution!

I just ask a question:

How can I store that user agree with it? I need to store it somewhere in database. 

Hey @MDavid

Thanks for your question! I've included the below extract from @WHMCS John's post where you can use the AfterShoppingCartCheckout hook point to create a customisation and add a custom database record.

On 29/03/2018 at 1:49 AM, WHMCS John said:

The last element of this hook file is the AfterShoppingCartCheckout hook point. Whilst not used in this example, this provides a place where you might execute any additional code based upon the particular requirements. For example you may wish to add a record to a custom database table to record the time and date of the order.

1

 

Link to comment
Share on other sites

Guest
This topic is now closed to further replies.
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use & Guidelines and understand your posts will initially be pre-moderated