bendrop Posted June 25, 2018 Share Posted June 25, 2018 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? 0 Quote Link to comment Share on other sites More sharing options...
bendrop Posted June 25, 2018 Author Share Posted June 25, 2018 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? 0 Quote Link to comment Share on other sites More sharing options...
brian! Posted June 26, 2018 Share Posted June 26, 2018 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. 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. 0 Quote Link to comment Share on other sites More sharing options...
bendrop Posted June 26, 2018 Author Share Posted June 26, 2018 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"); 0 Quote Link to comment Share on other sites More sharing options...
brian! Posted June 27, 2018 Share Posted June 27, 2018 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. 0 Quote Link to comment Share on other sites More sharing options...
bendrop Posted July 16, 2018 Author Share Posted July 16, 2018 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', ), ); } 0 Quote Link to comment Share on other sites More sharing options...
andy t Posted January 25, 2022 Share Posted January 25, 2022 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. 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. where i must to put that code? 0 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.