Jump to content

Hook to modify allowed payment gateways?


bendrop

Recommended Posts

Is there a hook I can use to edit the list of allowed payment gateways on the checkout page?

I have a product that is free, so I don't want people to enter any credit card information.

The work around given here is great and does just that, but has one major flaw - if the customer is ordering JUST a domain then this gateway will also be allowed! Woohoo! Free domains for everyone!

At preset I am doing a conditional in the checkout template file ({if !($gateway.sysname eq 'mailin' && $total->toNumeric() > 0)}) but I would like to get this is hook code instead of needing to edit templates (it's also not foolproof)

Any ideas? :)

Link to comment
Share on other sites

Forgot to add - the reason it's not ideal is if someone is buying a product that does require a credit card, but uses a 100% discount voucher, this gateway will also be available to them, then on the next (non-discounted) iteration, they will still be on that gateway.

 

Thinking about it - am I just missing an option somewhere to set allowed payment gateways for domains?

Link to comment
Share on other sites

13 hours ago, bendrop said:

Is there a hook I can use to edit the list of allowed payment gateways on the checkout page?

clientareapagecart would be the one that springs to mind - basically, you're just manipulating the $gateways array and removing specific gateway(s) is certain conditions are met (or not met - depending on how you're doing it)

13 hours ago, bendrop said:

The work around given here is great and does just that, but has one major flaw - if the customer is ordering JUST a domain then this gateway will also be allowed! Woohoo! Free domains for everyone!

they'd only be free is auto-registration was enabled in domain pricing - but I get your point. :idea:

15 hours ago, bendrop said:

At preset I am doing a conditional in the checkout template file ({if !($gateway.sysname eq 'mailin' && $total->toNumeric() > 0)}) but I would like to get this is hook code instead of needing to edit templates (it's also not foolproof)

Any ideas?

the hook should be along the lines of below...

<?php

/**
* Detect if cart total zero - if so, remove other gateways
* @author brian!
*/
 
function cart_gateway_removal_for_free_products($vars)
{
	if ($vars['templatefile']=='viewcart'){
		$gateways = $vars['gateways'];
		$total = $vars['total']->toNumeric();
		$allowed = ['mailin','paypal'];
		foreach ($gateways as $k => $item) {
			if (!in_array($item['sysname'],$allowed) and $total == '0') {
				unset($gateways[$k]);
			}
		} 
		return array("gateways" => $gateways);
	}
}
add_hook("ClientAreaPageCart", 1, "cart_gateway_removal_for_free_products");

so if the cart total is zero, only those gateways listed in the $allowed array will be shown at checkout - in the above hook, it's mailin & paypal, but in your case it sounds as though you should change that to just mailin.

$allowed = ['mailin'];
15 hours ago, bendrop said:

Thinking about it - am I just missing an option somewhere to set allowed payment gateways for domains?

WHMCS is the one missing that option, not you!:)

I always thought it very strange that you could assign gateways for products, but not domains.... as a rule, all payment gateways are available for domains.

though you could easily tweak the above hook to specify which gateways are shown when the cart only contains domains if you wanted to. :idea:

 

Link to comment
Share on other sites

Hey Brian!

Thank you so much for that - my issue was I thought those "ClientArea" hooks were only for logged in clients - I was looking through the "Shopping Cart" hooks and hadn't found anything.

I also found a variable "$domainsinorder" which will be true if any domains are in the cart, so can utilise this.

So in summary - by only setting allowed gateways in each product group, that covers that bit - then to stop certain gateways being used for domains (which seem to be the only other items affected) you can use the following hook (edit the $disallowed array to add other gateways to exclude)

 

<?php

function cart_remove_freeproducts_gateway($vars)
{
	if ($vars['templatefile']=='viewcart' && $vars['domainsinorder']){

		// List of gateways to remove
		$disallowed = array('freeproducts');

		$gateways = $vars['gateways'];
		
		foreach ($gateways as $k => $item) {
			if (in_array($item['sysname'],$disallowed)) {
				unset($gateways[$k]);
			}
		} 
		return array("gateways" => $gateways);
	}
}
add_hook("ClientAreaPageCart", 1, "cart_remove_freeproducts_gateway");

 

Link to comment
Share on other sites

18 hours ago, bendrop said:

Thank you so much for that - my issue was I thought those "ClientArea" hooks were only for logged in clients - I was looking through the "Shopping Cart" hooks and hadn't found anything.

yeah having them called client area hooks can be confusing - but basically just think of them as applying to any page that the client (logged in or general visitor) can see on your whmcs site.

19 hours ago, bendrop said:

I also found a variable "$domainsinorder" which will be true if any domains are in the cart, so can utilise this.

I think that's a recent addition, e.g v7... before then, and still, you could just count the domains array.

Link to comment
Share on other sites

  • 3 weeks later...

Can't edit my original post (maybe a mod can help) - but just found an issue using the $domainsinorder variable - it only equals true if there is a new registration, not a renewal.

There are also variables for addons and upgrades in there too, so I added them for good measure (not sure if required as they should inherit payment types from the actual products, but hey, just in case!)

So updating the code comes out as the following:

 

<?php

/* Remove freeproducts gateway if domain in cart */

function cart_remove_freeproducts_gateway($vars)
{

	if ($vars['templatefile']=='viewcart' && (count($vars['addons']) > 0 || count($vars['domains']) > 0 || count($vars['renewals']) > 0 || count($vars['upgrades']) > 0)){

		// List of gateways to remove
		$disallowed = array('freeproducts');

		$gateways = $vars['gateways'];
		
		foreach ($gateways as $k => $item) {
			if (in_array($item['sysname'],$disallowed)) {
				unset($gateways[$k]);
			}
		} 
		return array("gateways" => $gateways);
	}
	
}
add_hook("ClientAreaPageCart", 1, "cart_remove_freeproducts_gateway");

 

Oh and for people wondering what the 'freeproducts' gateway is - it's just a blank one I created (I am using the mailin and banktransfer gateways for their real purpose!)

Just create a file called "freeproducts.php" and put it in the /includes/gateways folder with the following code:

<?php
/**
 * WHMCS Sample Payment Gateway Module
 *
 * Payment Gateway modules allow you to integrate payment solutions with the
 * WHMCS platform.
 *
 * This sample file demonstrates how a payment gateway module for WHMCS should
 * be structured and all supported functionality it can contain.
 *
 * Within the module itself, all functions must be prefixed with the module
 * filename, followed by an underscore, and then the function name. For this
 * example file, the filename is "gatewaymodule" and therefore all functions
 * begin "gatewaymodule_".
 *
 * If your module or third party API does not support a given function, you
 * should not define that function within your module. Only the _config
 * function is required.
 *
 * For more information, please refer to the online documentation.
 *
 * @see https://developers.whmcs.com/payment-gateways/
 *
 * @copyright Copyright (c) WHMCS Limited 2017
 * @license http://www.whmcs.com/license/ WHMCS Eula
 */

if (!defined("WHMCS")) {
    die("This file cannot be accessed directly");
}

/**
 * Define module related meta data.
 *
 * Values returned here are used to determine module related capabilities and
 * settings.
 *
 * @see https://developers.whmcs.com/payment-gateways/meta-data-params/
 *
 * @return array
 */
function freeproducts_MetaData()
{
    return array(
        'DisplayName' => 'Free Products',
        'APIVersion' => '1.1', // Use API Version 1.1
        'DisableLocalCredtCardInput' => true,
        'TokenisedStorage' => false,
    );
}

/**
 * Define gateway configuration options.
 *
 * The fields you define here determine the configuration options that are
 * presented to administrator users when activating and configuring your
 * payment gateway module for use.
 *
 * Supported field types include:
 * * text
 * * password
 * * yesno
 * * dropdown
 * * radio
 * * textarea
 *
 * Examples of each field type and their possible configuration parameters are
 * provided in the sample function below.
 *
 * @return array
 */
function freeproducts_config()
{
    return array(
        // the friendly display name for a payment gateway should be
        // defined here for backwards compatibility
        'FriendlyName' => array(
            'Type' => 'System',
            'Value' => 'Free Products',
        ),
    );
}

 

Link to comment
Share on other sites

  • 3 years later...
On 6/26/2018 at 9:19 PM, brian! said:

clientareapagecart would be the one that springs to mind - basically, you're just manipulating the $gateways array and removing specific gateway(s) is certain conditions are met (or not met - depending on how you're doing it)

they'd only be free is auto-registration was enabled in domain pricing - but I get your point. :idea:

the hook should be along the lines of below...


<?php

/**
* Detect if cart total zero - if so, remove other gateways
* @author brian!
*/
 
function cart_gateway_removal_for_free_products($vars)
{
	if ($vars['templatefile']=='viewcart'){
		$gateways = $vars['gateways'];
		$total = $vars['total']->toNumeric();
		$allowed = ['mailin','paypal'];
		foreach ($gateways as $k => $item) {
			if (!in_array($item['sysname'],$allowed) and $total == '0') {
				unset($gateways[$k]);
			}
		} 
		return array("gateways" => $gateways);
	}
}
add_hook("ClientAreaPageCart", 1, "cart_gateway_removal_for_free_products");

so if the cart total is zero, only those gateways listed in the $allowed array will be shown at checkout - in the above hook, it's mailin & paypal, but in your case it sounds as though you should change that to just mailin.


$allowed = ['mailin'];

WHMCS is the one missing that option, not you!:)

I always thought it very strange that you could assign gateways for products, but not domains.... as a rule, all payment gateways are available for domains.

though you could easily tweak the above hook to specify which gateways are shown when the cart only contains domains if you wanted to. :idea:

 

where i must to put that code?

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • 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