There are many tutorials out there which show parts of implementing a payment module. None completely build the module. They all stop short of showing how they implemented their nameless payment method. These holes made something which should have taken a day or so to work out take two weeks to complete. Most of that time was spent figuring out the "Magento way" to do things. Once that was established, the module itself is very small. 6 files and 300 lines of code.
The previous post created a fake payment gateway. Part 2 will cover the structure of your magento module and part 3 will discribe how magento and the api interact.
The completed module can be downloaded from github.
Magento module file structure
Magento's file structure is based on the PEAR/Zend Framework autoloader where class xx_yyy_zz relates directly to a physical file of ./xx/yyy/zz.php.
Our module will use the namespace/folder structure of My_Mockpay_*
Example folder structure:
[My] [Mockpay] [controllers] [etc] [Model] [Helper] [Block]
Controllers are related to Zend_Action_Controllers.
In this example, we'll have one controller action for each possible response of the api: Success, Cancel and Failure.
Model is for your model code and business logic.
We'll extend Mage_Payment_Model_Method_Abstract, create a custom observer to hook into events which are fired during checkout, and create a custom class which will talk to our mockpay soap API.
Helper is for custom Mage_Payment_Helper_* classes. Only one helper is required and it need not be customized.
We'll extend Mage_Payment_Helper_Data.
Block is for custom code which alters the display of our payment method.
In this example, we're going to use the default block so this folder will be empty.
Etc contains the config files which glue the module together.
System.xml is for configuring the back-end of your module.
The args defined here will have a UI for editing them in the System->config->Payment Methods screen automatically.
Config.xml lets Magento know what the module is supposed to do and which files to load.
Lets take a look at Config.xml
the root element is
<modules? <My_Mockpay> <version>0.1.0</version> </My_Mockpay> </modules>
You set the module version here. It's important later when the next version of your module is released.
(Which is outside the scope of this tutorial. We don't need a custom database table so upgrading is irrelevant.)
Then start the
<models> <mockpay> <class>My_Mockpay_Model</class> </mockpay> </models>
This registers a route to your model files in Magento.
<helpers> <mockpay> <class>My_Mockpay_Helper</class> </mockpay> </helpers>
Ditto for the helpers.
<payment> <groups> <mockpay>Mockpay</mockpay> </groups> </payment>
This lets mageto know this is a payment module.
<events> <checkout_type_onepage_save_order_after> <observers> <my_mockpay_observer> <class>My_Mockpay_Model_Observer</class> <method>saveOrderQuoteToSession</method> </my_mockpay_observer> </observers> </checkout_type_onepage_save_order_after> </events>
Events are triggered at specific points in the code and allow you to attach custom code to an event without overriding it. In the example, the "checkout_type_onepage_save_order_after" event is a part of one-page checkout and is fired right after the order is created, but before the redirect to the payment form.
That's the end of the global section of the config.xml
The default section establishes the default values for the fields defined in system.xml file.
<default> <payment> <mockpay> <model>mockpay/standard</model> <group>mockpay</group> <active>1</active> <title>Credit Card (MockPay - Fake Payment Gateway) </title> <payment_action>sale</payment_action> <allowspecific>0</allowspecific> </mockpay> </payment> <mockpay> <settings> <activationstatus>0</activationstatus> </settings> </mockpay> </default>
The last section of my file is the front-end
<frontend> <secure_url> <mockpay_processing>/mockpay/standard</mockpay_processing> </secure_url> <routers> <mockpay> <use>standard</use> <args> <module>My_Mockpay</module> <frontName>mockpay</frontName> </args> </mockpay> </routers> </frontend>
Here we're registering a route to the controller for magento to use.
When the module is installed its actions will be accessible from:
This defines where the files will go an what we need to do.
Lets take a look at the system.xml
Each child node of
is a field of data which will be save into the "core_config" table in the magento database.
The configuration option for your module should go here. You'll be able to edit these values from the magento configuration panel in thte back-end
and retrieve these values in your module. The sample file includes the options you'd see most often when configuring a new module.
Take note of the "merchantkey" element:
<merchantkey translate="label"> <label>Merchant Key</label> <comment><![CDATA[Data entered into this field is stored encrypted in the db.]]></comment> <frontend_type>text</frontend_type> <backend_model>adminhtml/system_config_backend_encrypted</backend_model> <sort_order>51</sort_order> <show_in_default>1</show_in_default> <show_in_website>1</show_in_website> <show_in_store>0</show_in_store> </merchantkey>
The name of the element is arbitrary. You get to pick.
Each field has a label, optional comment, type, model, order and visibility options.
This data is stored in the core_config table in the database.
If your saving passwords or sensitive information here, use the "system_config_backend_encrypted" back-end. (aka Mage_Adminhtml_Model_System_Config_Backend_Encrypted)
This stores your data in the core_config table encrypted and prevents prying eyes from discovering sensitive information like api username or keys.
You can see the other back-ends by browsing the "/Mage/Adminhtml/Model/System/Config/Backend" folder.
The final config file is the module config file, called "My_Mockpay.xml". This file is normally stored in the "magento/app/ete/module" folder and enables the module withinMmagento. If you need to remove the module, delete this file and clear the Magento cache.
We'll dive into the controller and event modules in part 3.