Your browser (Internet Explorer 6) is out of date. It has known security flaws and may not display all features of this and other websites. Learn how to update your browser.
X

Making Payment Module Available for Virtual Products - Prestashop Cart

I ran into a funny bug by a client. He bought my QuickTeller module for Prestashop and he kept complaining the module is not showing up on checkout. I was so confused because I have never gotten a complaint like this before, ever.

After so any days of looking for what really went wrong, checking the carriers and every single preference I can find, I couldn't just understand what was going on. Something felt very wrong about this whole issue because everything seems alright. I decided to check the product configuarion and I saw that the products are virtual products so carriers are not available for them. I decided to look into my plugin to see how to fix this and decided to document it.

The simplest way to restrict our payment methods is to modify the method named hookPayment, used by every single Prestashop Payment module. It’s the function responsible of displaying payment methods during the checkout, so hiding them here will prevent people from continuing the purchase with them.

If your code looks like this, your module won't support virtual products


	public function hookPayment($params)
	{
		if (!$this->active)
			return;
		
		if (!$this->checkCurrency($params['cart']))
			return;

		// Check if cart has product download
		foreach ($params['cart']->getProducts() as $product)
		{
			$pd = ProductDownload::getIdFromIdProduct((int)$product['id_product']);
			if ($pd && Validate::isUnsignedInt($pd))
				return false;
		}

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

This part of your code

		foreach ($params['cart']->getProducts() as $product)
		{
			$pd = ProductDownload::getIdFromIdProduct((int)$product['id_product']);
			if ($pd && Validate::isUnsignedInt($pd))
				return false;
		}

Implies you are looping through the products and checking if any of the products is virtual, don't show the payment method. If you remove that line, the module will be available for all types of product.

If you want to return true when all the products are virtual you can have something similar to below code

		
if($products)
{
    $virtuals = 0;
    foreach ($products as $product) {
        if ($product['is_virtual'])
        {
            $virtuals++;
        }      
    }
    if($virtuals == count($products))
        return false;
}


Hope this saves someone from nightmare.

 


comments powered by Disqus