Limiting payment methods to specific carriers in PrestaShop

If you want to hide or display certain payment methods for specific carriers you have, here is a little trick on how to do it quickly.

Upgrade-safe procedure

Whenever you want to limit a payment method by carrier, you will necessarily need to edit the module’s hookPayment method. This means you will need to do it for every single payment method your shop has. However, if you amend the core file, changes will be lost on the next update of the module itself. If you are running a version newer than PrestaShop 1.6.0.11, you can Override Modules Files and make your life easier. This is actually what we are going to do in the tutorial.

Notice: if you use an older PrestaShop version, you can simply modify the core file

Additionally, there is an important thing we need to be aware of, whenever dealing with carriers. Carrier IDs will change anytime you update a carrier’s information, so we cannot use the ID as our static factor to check against to.

Overriding the Bankwire Module

In this example, we will use the Bankwire module and limit it to a single carrier. The first thing we want to do is override it, so let’s create a new folder in override/modules and name it bankwire. Inside it, create a new file named bankwire.php, adding the following code inside php tags:

if (!defined('_CAN_LOAD_FILES_'))
    exit;
 
class BankwireOverride extends Bankwire
{
 
 
}

Then reach your cache folder, and erase class_index.php. This will make sure our new override is loaded.
Next, we want to extend the hookPayment method, which I will simply copy/paste from the original file

if (!defined('_CAN_LOAD_FILES_'))
    exit;
 
class BankwireOverride extends Bankwire
{
 
 	public function hookPayment($params)
	{
		if (!$this->active)
			return;
		if (!$this->checkCurrency($params['cart']))
			return;

		$this->smarty->assign(array(
			'this_path' => $this->_path,
			'this_path_bw' => $this->_path,
			'this_path_ssl' => Tools::getShopDomainSsl(true, true).__PS_BASE_URI__.'modules/'.$this->name.'/'
		));
		return $this->display(__FILE__, 'payment.tpl');
	}
}

At this point, we need our condition. First, I need to know which carrier I want to disable or enable the module for. I have a FedEx carrier that currently has ID 3, so I can temporarily use this information to get the real one I need.
Reach your front office, with a product in the cart, and make sure the 5-steps checkout is enabled. Continue until the payment page, making sure you select the carrier you want to target beforehand.
In our override, at the very beginning of the hookPayment method, let’s print out some debug code:

...
 	public function hookPayment($params)
	{

		d($params['cart']->id_carrier);
		if (!$this->active)
			return;
		if (!$this->checkCurrency($params['cart']))
			return;
...

Refresh the payments list, and it will result in a blank page only reading an ID, followed by “END”
That’s the ID of the carrier we selected. As mentioned at the beginning of the article, we cannot use it as static parameter, so we need to find the static id of this carrier.
let’s play with the carrier object a bit:

...
 	public function hookPayment($params)
	{

		$id_carrier = $params['cart']->id_carrier;
		$carrier = new Carrier($id_carrier);
		d($carrier);
		if (!$this->active)
			return;
		if (!$this->checkCurrency($params['cart']))
			return;
...

You will see a bunch of information as soon as you refresh. What we are interested in is the id_reference field of the carrier. This reference will never change, unlike the id_carrier, that will instead increase each time we save carrier information in the back office. Therefore, we can use this reference as our static field to check the payment method’s availability.

I want to disable bankwire for this carrier, so I will simply add:

...
 	public function hookPayment($params)
	{

		$id_carrier = $params['cart']->id_carrier;
		$carrier = new Carrier($id_carrier);
		if($carrier->id_reference == 3) // my fedex, make sure your matches the carrier you use
			return false;
		if (!$this->active)
			return;
		if (!$this->checkCurrency($params['cart']))
			return;
...

As simple as that! On the other hand, if I want to enable bankwire for this carrier only, I can reverse the condition

...
 	public function hookPayment($params)
	{

		$id_carrier = $params['cart']->id_carrier;
		$carrier = new Carrier($id_carrier);
		if($carrier->id_reference != 3) // my fedex, make sure your matches the carrier you use
			return false;
		if (!$this->active)
			return;
		if (!$this->checkCurrency($params['cart']))
			return;
...

You like the tuts and want to say "thank you"? Well, you can always feel free to donate:

  • Cylicom web

    Can you tell me where to create a new folder in override/modules please? In theme ? What’s gonna be the path?

  • CLICKME CLICKME

    Thanx! work fine, but delay as five six seconds on carrier change, any idea?

You like the tuts and want to say "thank you"? Well, you can always feel free to donate: