Jump to content

a specific payment method for a specific item


Recommended Posts

It is not possible. It could be possible if you limited your cart to that one item, but say a person has that item and another item and tries to check out. You could custom write a solution, that is totally possible but it would be a pain.

Link to comment
Share on other sites

you would have to customize the payment module so that the payment option is only available if the cart has the target product/products.

it would not be all that complex if you are familiar with coding and prestashop modules.

 

if you know exactly what you want done, send me a PM and I can provide you an estimate to do this work for you.

Link to comment
Share on other sites

  • 3 years later...

Hi bellini13  :)

 

I saw your post in this thread but you can't reply there anymore.

 

How can you do the same thing, except for categories and subcategories? I would like user to pay in advance (only bank wire or paypal), because i do handmade products.

 

Thanks and regards,

Housy

 

you would have to customize the payment module so that the payment option is only available if the cart has the target product/products.
it would not be all that complex if you are familiar with coding and prestashop modules.

if you know exactly what you want done, send me a PM and I can provide you an estimate to do this work for you.

Link to comment
Share on other sites

the logic is similar.  instead of looping through the products, you would have to loop through the products in the cart, then loop through those products categories and match them up against a pre-defined list of category ID's.

 

what you need to consider is if the customer has added a product in one of the pre-defined categories, in addition to a product that is not in one of those categories. 

Link to comment
Share on other sites

I'm a designer and this is a bit too hard for me to do ... so i guess there is no easy "few steps" way? Is it possible to buy that from you, do you have a module or something?

 

 

the logic is similar.  instead of looping through the products, you would have to loop through the products in the cart, then loop through those products categories and match them up against a pre-defined list of category ID's.

 

what you need to consider is if the customer has added a product in one of the pre-defined categories, in addition to a product that is not in one of those categories. 

Link to comment
Share on other sites

unfortunately I do not believe a module could be used here, as Prestashop did not design for this.  You would need to edit or override each payment module, or override the PaymentModule class.

 

If you are looking to hire someone to create this customization for you, you can post the job request in the job offers forum, or you can send me a PM or contact me on my website for an estimate.

 

You may want to take a stab at documenting your specific requirements, as any decent developer is going to ask you for them in order to provide an estimate

Link to comment
Share on other sites

I would only like to disable "cash on delivery". Is that possible to do with one IF statement? Which file should i modify, the cash on delivery module?

 

 

unfortunately I do not believe a module could be used here, as Prestashop did not design for this.  You would need to edit or override each payment module, or override the PaymentModule class.

 

If you are looking to hire someone to create this customization for you, you can post the job request in the job offers forum, or you can send me a PM or contact me on my website for an estimate.

 

You may want to take a stab at documenting your specific requirements, as any decent developer is going to ask you for them in order to provide an estimate

Link to comment
Share on other sites

bellini13, you are truly the best  :)

 

I actually know some basic stuff and i did it thanks to your code from the other thread.

 

Here is the final code but this works only for product ID's, so you have to put them manually in your "modules/cashondelivery/cashondelivery.php" file. Just replace old hookPayment function with one below and you're good to go  ;)

public function hookPayment($params) {
		
	if (!$this->active)
		return ;

	global $smarty;
	global $cart;

	// Check if cart has product download
	if ($this->hasProductDownload($params['cart']))
		return false;

	$smarty->assign(array(
		'this_path' => $this->_path, //keep for retro compat
		'this_path_cod' => $this->_path,
		'this_path_ssl' => Tools::getShopDomainSsl(true, true).__PS_BASE_URI__.'modules/'.$this->name.'/'
	));
	
	// list of all products, which can't be bought by cash on delivery method
	$disable_cod = array(7, 20, 22);

	// get all cart products
	$products = $cart->getProducts();

	// default value - show module
	$show = true;
	
	// loop through all products and check if
	foreach ($products as $product) {
		
		if (in_array($product['id_product'], $disable_cod))
			$show = false; // cash on delivery is not allowed, hide it
		
	}
	
	// hide module, if cart contains any product from $disable_cod array above
	if (!$show)
		return ;
	else
		return $this->display(__FILE__, 'payment.tpl');
	
}

Thanks and regards,

Housy

 

 

there should be a function called hookpayment in the module.  you would need to add your logic to this function

Edited by Housy (see edit history)
Link to comment
Share on other sites

yup, code looks good

 

I'm not sure what your hasProductDownload function does exactly, but there is a function in the Cart class you could use named "isVirtualCart".

    // Check if cart has product download
    if ($this->hasProductDownload($params['cart']))
        return false;

So instead of the above code and custom function, you could use

        if ($params['cart']->isVirtualCart())
            return false;

 

Link to comment
Share on other sites

I guess this is the same thing. Both codes are for virtual products aren't they? That was already within that function, by default, i didn't change anything.

 

 

yup, code looks good

 

I'm not sure what your hasProductDownload function does exactly, but there is a function in the Cart class you could use named "isVirtualCart".

    // Check if cart has product download
    if ($this->hasProductDownload($params['cart']))
        return false;

So instead of the above code and custom function, you could use

        if ($params['cart']->isVirtualCart())
            return false;
Link to comment
Share on other sites

You didn't supply the code for hasProductDownload, so I have no idea if they are the same

 

hasProductDownload function is written before. Check the code below.

public function hasProductDownload($cart) {

	foreach ($cart->getProducts() AS $product) {

		$pd = ProductDownload::getIdFromIdProduct((int)($product['id_product']));
		if ($pd AND Validate::isUnsignedInt($pd))
			return true;

	}

	return false;

}
Link to comment
Share on other sites

  • 2 weeks later...

Bellini13, could you please be so kind and tell me, what am i doing wrong, because i'm getting fatal error all the time, when i'm trying to override the whole "cashondelivery.php" class. I copied default "cashondelivery.php" file into "override/modules/cashondelivery/cashondelivery.php" and made those changes within "hookPayment" function.

 

What am i doing wrong? What is the proper way to override a specific class function?

 

Thank you and best regards,

Housy

 

 

Fatal error: Cannot redeclare class CashOnDelivery in /home/myusername/public_html/TESTSHOP1714/override/modules/cashondelivery/cashondelivery.php on line 147

Link to comment
Share on other sites

If i rename class like this "class CashOnDeliveryOverride extends PaymentModule" then i don't get this error anymore but the other problem is, that i just can't get this thing working. If i make changes directly from modules directory, it is ok. After i added "cashondelivery.php" file into override directory, i have also deleted "class_index.php" from "cache" directory.

 

What am i still doing wrong? How should i override class name, is that even correct?

 

Sorry, but i'm not good in php.

 

Regards,

Housy

 

Bellini13, could you please be so kind and tell me, what am i doing wrong, because i'm getting fatal error all the time, when i'm trying to override the whole "cashondelivery.php" class. I copied default "cashondelivery.php" file into "override/modules/cashondelivery/cashondelivery.php" and made those changes within "hookPayment" function.

 

What am i doing wrong? What is the proper way to override a specific class function?

 

Thank you and best regards,

Housy

Edited by Housy (see edit history)
Link to comment
Share on other sites

Here is also the current class override PHP code.

if (!defined('_PS_VERSION_'))
	exit;

class CashOnDeliveryOverride extends PaymentModule
{

	public function hookPayment($params) {
		
		if (!$this->active)
			return ;

		global $smarty;
		global $cart;
		
		$is_disabled = false;

		// Check if cart has product download
		if ($this->hasProductDownload($params['cart']))
			return false;
		
		// list of all products, which can't be bought by cash on delivery method
		$disable_cod = array(1, 3);

		// get all cart products
		$products = $cart->getProducts();

		// default value - show module
		$show = true;
		
		// loop through all products and check if
		foreach ($products as $product) {
			
			if (in_array($product['id_product'], $disable_cod))
				$show = false; // cash on delivery is not allowed, disable it
			
		}
		
		// hide module, if cart contains any product from $disable_cod array above
		if (!$show)
			$is_disabled = true;
		
		$smarty->assign(array(
			'this_path' => $this->_path, //keep for retro compat
			'this_path_cod' => $this->_path,
			'this_path_ssl' => Tools::getShopDomainSsl(true, true).__PS_BASE_URI__.'modules/'.$this->name.'/',
			'disabled_link' => $is_disabled
		));
			
		return $this->display(__FILE__, 'payment.tpl');
		
	}
	
}

And here is the payment.tpl file inside "templates/mytheme/modules/cashondelivery/views/templates/hook/payment.tpl".

<div class="row" {if $disabled_link}style="opacity: 0.4; pointer-events: none; cursor: default"{/if}>
	<div class="col-xs-12">
        <p class="payment_module">
            <a class="cash" {if $disabled_link}onclick="return false;"{/if} href="{$link->getModuleLink('cashondelivery', 'validation', [], true)|escape:'html'}" title="{l s='Pay with cash on delivery (COD)' mod='cashondelivery'}" rel="nofollow">
            	<img src="{$modules_dir}/cashondelivery/cashondelivery.png" width="200" height="108" alt="{l s='Pay with cash on delivery (COD)' mod='cashondelivery'}" style="float:left;" />
				{if $disabled_link}
					<span>{l s='There are products in your cart, which can\'t be bought by cash on delivery payment method' mod='cashondelivery'}</span>
				{else}
					{l s='Pay with cash on delivery (COD)' mod='cashondelivery'}<br>
					<span>({l s='You pay for the merchandise upon delivery' mod='cashondelivery'})</span>
				{/if}
            </a>
        </p>
    </div>
</div>

I have assigned another variable, because i don't want to hide payment option, i only want to disable it  :)

 

I just don't know, what else should i do.

 

Regards,

Housy

Link to comment
Share on other sites

Thanks for the link, it helped, i am now one step closer  :) You have to name your class whatever you want, except you must extend it with "Cashondelivery", like below ...

class CashOnDeliveryOverride extends CashOnDelivery

But it is still not fully working, because it still shows default TPL design, even if i modify the file within "templates/mytheme/modules/cashondelivery/views/templates/hook/payment.tpl". What am i doing wrong?

 

Override class is working, because i did a test with var_dump function and it's printed at the top of my store.

 

Regards,

Housy

 

Link to comment
Share on other sites

It is finally working after hours of thinking  :)

I was very sloppy, because the PHP logic wasn't written right.

 

The final PHP code for override cashondelivery.php file

<?php

if (!defined('_CAN_LOAD_FILES_'))
    exit;

class CashOnDeliveryOverride extends CashOnDelivery
{

	public function hasProductDownload($cart) {
		
		foreach ($cart->getProducts() AS $product) {
			
			$pd = ProductDownload::getIdFromIdProduct((int)($product['id_product']));
			if ($pd AND Validate::isUnsignedInt($pd))
				return true;
		
		}
		
		return false;
		
	}

	public function hookPayment($params) {
		
		if (!$this->active)
			return ;

		global $smarty;
		global $cart;
		
		// default variable values
		$is_disabled = false;
		$show = false;

		// Check if cart has product download
		if ($this->hasProductDownload($params['cart']))
			return false;
		
		// list of all products, which can't be bought by cash on delivery method
		$disable_cod = array(111, 112, 113);

		// get all cart products
		$products = $cart->getProducts();
		
		// loop through all products and check if
		foreach ($products as $product) {
			
			if (in_array($product['id_product'], $disable_cod))
				$show = true; // cash on delivery is not allowed, disable it
			
		}
		
		// hide module, if cart contains any product from $disable_cod array above
		if ($show)
			$is_disabled = true;
		
		$smarty->assign(array(
			'this_path' => $this->_path, //keep for retro compat
			'this_path_cod' => $this->_path,
			'this_path_ssl' => Tools::getShopDomainSsl(true, true).__PS_BASE_URI__.'modules/'.$this->name.'/',
			'disabled_link' => $is_disabled
		));
		
		return $this->display(__FILE__, 'payment.tpl');
		
	}
	
}

Bellini13, thank you so much for helping me out, you are the man!  B)

 

Regards,

Housy

Edited by Housy (see edit history)
Link to comment
Share on other sites

Bellini13, one more question and then i won't bother you anymore, i promise  :P

 

If i don't include hasProductDownload function in override class, it won't work in hookPayment, i get error.

Is there maybe a better way? I mean how can you call $this->hasProductDownload($params['cart'])? 

Or should i ask, how can you call a function from parent class in override class? Hope i asked this properly, sorry i'm not good with PHP classes at all.

 

Thanks and regards,

Housy

Edited by Housy (see edit history)
Link to comment
Share on other sites

Already tried that bellini13 but it's not working. I get error below  :wacko:

 

 

Fatal error: Call to undefined method CashOnDelivery::hasProductDownload() in /home/username/public_html/override/modules/cashondelivery/cashondelivery.php on line 36

 

What else could be wrong?

 

Regards,

Housy

 

you might need to use $self or $parent instead of $this

 

$this->hasProductDownload($params['cart'])

 

try this instead

parent::hasProductDownload($params['cart'])

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...