Magento Product Attribute to Disable a Payment Method

In this short tutorial I’m going to show you how to create a new attribute called “card only” that will remove a specific “free” payment method whenever a customer holds this particular product and attribute in their cart.

This may seem a little strange but let me give you an example. Your company accepts cheque/money order payments for all of it’s products – except a certain few. This could possibly be because your company needs to pay upfront for these types of products – therefore you don’t really want to be left out-of-pocket while a cheque is delivered via snail-mail and possible ‘bounced’.

The ideal scenario for this is to check each product in our basket to check to see if it’s card-only attribute is activated (set to ‘yes’). If it is then we’re going to disable our “free” payment method in the checkout.

Creating our “Card-Only” attribute

First of all we need to create our simple attribute. In the Magento admin simply navigate to Catalog > Attributes > Manage Attributes. Add a new one and call make it’s attribute codecard_only‘ with the Catalog Input Type for Store Owner set as Yes/No – keeping the Default Value as No. Also make sure that you select Visible on Product View Page on Front-end as Yes. Make sure you add it into your appropriate attribute set so that you can set it for your products!

Now go into each of the products that you want to be purchased “Card Only” and set this attribute to “Yes”.

Creating our Module

That’s the easy stuff done, next we need to create a module that will disable our “free” method whenever someone has a “Card Only” product in their basket.

If you’ve never created your own Magento extension before – don’t worry – this one is really easy! There’s only 3 files!

First of all we need to create our folder structure so create the following folders:

app > code > local > Creare > CardOnly > etc
app > code > local > Creare > CardOnly > Model

Next we need to create our files – the first one will be our Observer.php. Create the file Observer.php inside the “Model” folder and paste in the following code.

<?php

class Creare_CardOnly_Model_Observer
{
	public function cardOnly(Varien_Event_Observer $observer)
	{
	   $event           = $observer->getEvent();
           $method          = $event->getMethodInstance();
           $result          = $event->getResult();
	   $cardonly	    = false;

		foreach (Mage::getSingleton('checkout/cart')->getQuote()->getAllVisibleItems() as $item)
		{
			if($item->getProduct()->getCardOnly()){
				$cardonly = true;
			}
		}

		if($method->getCode() == "checkmo" && $cardonly){
			$result->isAvailable = false;
		}

	}
}

That code is what helps us identify our “Card Only” products and disable our “Free” payment method (in this case – “checkmo” – check/money order).

The next file we need to create is the config.xml – this is so that Magento know’s where to look for our Observer.php and also where we can set up our Observer to initiate the function cardOnly.

Within our “etc” folder create a file called config.xml and paste in the following code:

<?xml version="1.0"?>
<config>
	<modules>
		<Creare_CardOnly>
			<version>0.1.0</version>
		</Creare_CardOnly>
	</modules>
	<global>
		<events>
			<payment_method_is_active>
				<observers>
					<card_only>
						<type>singleton</type>
						<class>cardonly/observer</class>
						<method>cardOnly</method>
					</card_only>
				</observers>
			</payment_method_is_active>
		</events> 
		<models>
			<cardonly>
				<class>Creare_CardOnly_Model</class>
				<resourceModel>cardonly_mysql4</resourceModel>
			</cardonly>
		</models>
		<sales>
            <quote>
                <item>
                    <product_attributes>
                        <card_only/>
                    </product_attributes>
                </item>
            </quote>
        </sales>
	</global>
</config>

Within this code all we are doing is telling Magento where to find our ‘Models’ and also telling Magento to perform a function when a certain event is triggered – in this case the event we want Magento to call our function on is “payment_method_is_active”.

Thanks to beeplogic for a couple of tips within this code – we’re also telling Magento to send across our “card_only” attribute to our quote object – so we can load it from our Observer.php. This way we do not need to load the product model again to get at the attribute – saving resources.

The last file we need is the Module Configuration file – basically the file that tells Magento to load our module. You need to create the following file in this location:

app > etc > modules > Creare_CardOnly.xml

Then paste in the following code:

<config>
    <modules>
        <Creare_CardOnly>
            <active>true</active>
            <codePool>local</codePool>
        </Creare_CardOnly>
    </modules>
</config>

There you go – such a simple Magento Module! Just make sure that you clear your cache for the module to take effect.

Testing

Now that our module has been created we should test it to make sure it works. I’m using a brand new version of Magento 1.8 CE (because it has just been released today!).

The first really simply thing to check is to make sure our Module has loaded correctly – visit System > Configuration > Advanced and you should see our new module in the list.

Our module is active
Our module is active.

Great – we know it’s loaded – now let’s test the module.

As this is a brand new installation with sample data installed – I’m going to be using the Cellphones attribute set to try my new “Card Only” attribute on. In particular I’m going to make sure that my HTC Touch phone has Card Only set to YES – any other product will either not contain this attribute or will have it set to default (being NO).

The other thing to note is that my “Free” payment gateway is Check/Money Order – this is the one I want to disable if there is a “Card Only” product in my cart.

Test WITHOUT a “Card Only” product

A default test now – I’m going to add the ever-popular “Ottomon sqaure thing” to my cart and make sure that both of my payment options are available.

Without a Card Only product in the cart
Without a Card Only product in the cart.

And within my checkout I can see both payment options.

Both our payment options are available
Both our payment options are available.

Test WITH a “Card Only” product

Now that the default test has been done let’s test it with a product that should remove my “Free” payment method. Let’s add my HTC Touch now and see what happens.

Our Card Only product is now in our cart
Our Card Only product is now in our cart

And in our checkout I can see that my “Free” payment method has been removed! How about that!

Our Free payment option has been disabled
Our Free payment option has been disabled

Conclusion

So, we’ve learned how to create a module for a particular purpose and really easily perform quite a (on the face of it) complicated task with ease. That’s Magento events & Modules in a nutshell.

You can obviously perform some PHP in the Observer.php to disable as many or as few payment methods as you wish (as long as you know the identifiers for them – trick is to check the radio-button fields on the checkout using Firebug or similar) – as well as anything else that takes your fancy.

You can find all the files featured in this tutorial on github.