<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>ModulesGarden Blog &#187; tutorial</title>
	<atom:link href="https://www.blog.modulesgarden.com/tag/tutorial/feed" rel="self" type="application/rss+xml" />
	<link>https://www.blog.modulesgarden.com</link>
	<description>Where Creativity Meets Technology</description>
	<lastBuildDate>Thu, 16 Apr 2026 11:45:52 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.4.2</generator>
		<item>
		<title>Automatic Currency, Language And Template Setup For WHMCS &#8211; Updated</title>
		<link>https://www.blog.modulesgarden.com/automatic-currency-language-template-setup-whmcs</link>
		<comments>https://www.blog.modulesgarden.com/automatic-currency-language-template-setup-whmcs#comments</comments>
		<pubDate>Wed, 16 Jan 2019 15:30:02 +0000</pubDate>
		<dc:creator>Piotr Dołęga</dc:creator>
				<category><![CDATA[Main]]></category>
		<category><![CDATA[customization]]></category>
		<category><![CDATA[free]]></category>
		<category><![CDATA[geolocation]]></category>
		<category><![CDATA[MaxMind]]></category>
		<category><![CDATA[products]]></category>
		<category><![CDATA[templates]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[WHMCS]]></category>

		<guid isPermaLink="false">https://www.blog.modulesgarden.com/?p=230</guid>
		<description><![CDATA[The recognition of our Geolocation Hook For WHMCS has been continuously growing among the global community of WHMCS users. Having this exhilarating trend in mind, we felt extremely tempted to breathe new life into the original Blog post dated March &#8230; <a href="https://www.blog.modulesgarden.com/automatic-currency-language-template-setup-whmcs">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">The recognition of our <a href="https://www.modulesgarden.com/products/whmcs/geolocation-hook"><strong style="color: #5e90b1;">Geolocation Hook For WHMCS</strong></a> has been continuously growing among the global community of WHMCS users. Having this exhilarating trend in mind, we felt extremely tempted to breathe new life into the original Blog post dated March 2013, and show the current potential lying within this simple, yet undoubtedly powerful tool.<strong><span id="more-230"></span></strong></p>
<p style="text-align: justify;">One of the most interesting novelties as compared to the then hook&#8217;s advantages is the addition of support for <a href="https://www.modulesgarden.com/products/whmcs/polish-language-translation"><strong style="color: #cb7d34;">Polish Language Translation For WHMCS</strong></a>. With it, all Polish clients will enjoy a detailed localization of your entire system into their very own mother tongue.</p>
<p style="text-align: justify;">What we present below is the catalog of most essential maneuvers you may carry out thanks to our hook. To help you find your way through the particular features more easily, the article has been supplemented with the exact code lines and clear guidelines on how to adjust them.</p>
<ol>
<li><strong>Configure the rules of currency, language and template changes</strong></li>
<p>
<p style="text-align: justify;">Adjustment of the client area pages depending on your clients location has been simplified to the maximum possible level. Edit the code with the provided in the commented areas tips to achieve any configuration of currency, language and templates.</p>
<p></p><pre class="crayon-plain-tag">/**
* Define relations between countries and currencies.
* Enter the currency code for each country (codes used), use the below pattern, edit it or add new entries below:
*/
$countryToCurrency = array(
'default' =&gt; 'USD',
'US' =&gt; 'USD',
'GB' =&gt; 'GBP',
// NOTE: You can add more below
);</pre><p></p><pre class="crayon-plain-tag">/**
* Define language rules by assigning a language to a single country.
* Use the below pattern (language name for country code) edit it and/or add new entries below:
*/
$countryToLanguage = array(
'default' =&gt; 'english',
'US' =&gt; 'english',
'DE' =&gt; 'german',
'NO' =&gt; 'norwegian',
// NOTE: You can add more below
);</pre><p></p><pre class="crayon-plain-tag">/**
* Configure additional settings:
* Firstly assign a WHMCS template to each country used.
* Use the below pattern (template name for country code) edit it and/or add new entries below:
*/
$countryToTemplate = array(
'US' =&gt; 'six',
'default' =&gt; 'six',
// NOTE: You can add more below
);</pre><p></p><pre class="crayon-plain-tag">/**
* Now, define the language for each WHMCS template used.
* Please note that a template available in WHMCS V7 is: 'six'.
* It is important to use a template that exists within your WHMCS system.
* Not Logged In Users
*/
$templateToLanguage = array(
'english' =&gt; 'six',
'german' =&gt; 'six',
'default' =&gt; 'six',
// NOTE: You can add more below
);</pre><p></p>
<li style="padding-top: 10px;"><strong>Select a template depending on a mobile device or a domain used</strong></li>
<p>
<p style="text-align: justify;">You may point a template that shall be called, following the device type used, a tablet or a mobile. In the very same way, point the domain names that your visitors are redirected from, to turn on a specific template for them. Uncomment the lines and provide required templates names.</p>
<p></p><pre class="crayon-plain-tag">/**
* You may define a mobile template per a mobile device: mobile and tablet types.
* Use the below pattern (template name for mobile device) and edit the entries.
* Comment out to disable the option.
*/
$mobileToTemplate = [
// 'mobile' =&gt; 'mobile_template',
// 'tablet' =&gt; 'tablet_template',
];</pre><p></p><pre class="crayon-plain-tag">/**
* You may define templates per domain name. Enter a domain name and assign a template to each one of them.
* Uncomment the below examples to turn on.
*/
$domainToTemplate = [
//'www.example.mobi' =&gt; 'mobile_template',
//'www.example.com' =&gt; 'six',
];</pre><p></p>
<li style="padding-top: 10px;"><strong>Select adjustable pages of your client area</strong></li>
<p>
<p style="text-align: justify;">The hook offers huge flexibility when it comes to personalizing a whole or just a specific part of your client area. You are free to select the exact pages where the alterations should be performed.</p>
<p></p><pre class="crayon-plain-tag">/**
* Enter pages in your WHMCS which the hook will be active for.
* Add more pages at the bottom of the list, comment out single pages to disable the hook for them:
*/
$allowedScripts = array(
'p1.php',
'index.php',
'clientarea.php',
'cart.php',
'knowledgebase.php',
'announcements.php',
'serverstatus.php',
'affiliates.php',
'contact.php',
// NOTE: You can add more below
);</pre><p></p>
<li style="padding-top: 10px;"><strong>Disable the hook with ease</strong></li>
<p>
<p style="text-align: justify;">There might be cases when you do not wish the hook to alter the client area. You are given a wide range of possibilities to turn off the hook for specific IP addresses, IP pools or certain user agents &#8211; all is up to you!</p>
<p></p><pre class="crayon-plain-tag">/**
* Point single IP addresses. The hook will be turned off for these addresses.
* Uncomment the below list and edit the exemplary addresses, add more at the bottom of the list:
*/
$disabledForIPs = array(
// '91.192.166.22',
// '192.168.0.39',
// NOTE: You can uncomment or add more below
);</pre><p></p><pre class="crayon-plain-tag">/**
* Point full IP pools. The hook will be turned off for the addresses in these pools.
* Uncomment the below list and edit the exemplary addresses, add more at the bottom of the list:
*/
$disabledForCidrIPs = array(
// '192.168.56.0/24',
// '192.168.0.39/24',
// NOTE: You can uncomment or add more below
);</pre><p></p><pre class="crayon-plain-tag">/**
* Point user agents. The hook will be turned off for the enumerated here devices/browsers.
* Enter a short or a full user agent name like in the examples below.
* Uncomment the below list and edit the exemplary entries, add more at the bottom of the list:
*/
$disabledForBrowsers = array(
// 'Chrome',
// 'Firefox',
// 'Google-Site-Verification',
// 'Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html )',
// 'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 7.1; Trident/5.0)',
// NOTE: You can uncomment or add more below
);</pre><p></p>
<li style="padding-top: 10px;"><strong>Get the country with MaxMind GeoIP2</strong></li>
<p>
<p style="text-align: justify;">In order to track your clients’ locations, either use the included in the package submodule, or add your own submodule.</p>
<p></p><pre class="crayon-plain-tag">/**
* Get the country using an external service, e.g. MaxMind GeoLite
* http://dev.maxmind.com/geoip/geolite
* NOTE: You can also create your own submodule, edit the below line in such case as only one submodule can work at a time.
*/
$submodule = 'GeoIP2';</pre><p></ol>
<p style="text-align: justify; padding-top: 10px;">If the article does not cover the configuration scheme you look for, it most likely can be found <strong style="text-decoration: underline; color: #5e90b1;"><a href="https://www.docs.modulesgarden.com/Geolocation_Hook_For_WHMCS">in our Wiki article</a></strong>. Apart from detailed instructions on how to upload and configure the tool, you will find there several visualizations of how the client area may be adapted with this neat, completely free of charge hook.</p>
<p style="text-align: justify;"><span style="display: block; text-align: center;"><a style="text-decoration: none; display: inline-block; margin: 28px 0px 28px 0px;" href="https://www.modulesgarden.com/products/whmcs/geolocation-hook"><span style="-webkit-border-radius: 3px; -moz-border-radius: 3px; border-radius: 3px; background: #5e90b1; color: #ffffff; padding: 15px 20px; text-decoration: none;"><strong>Get the Hook!</strong></span></a></span></p>
]]></content:encoded>
			<wfw:commentRss>https://www.blog.modulesgarden.com/automatic-currency-language-template-setup-whmcs/feed</wfw:commentRss>
		<slash:comments>213</slash:comments>
		</item>
		<item>
		<title>Grand Your Data The Gift Of Full Protection!</title>
		<link>https://www.blog.modulesgarden.com/world-backup-day</link>
		<comments>https://www.blog.modulesgarden.com/world-backup-day#comments</comments>
		<pubDate>Thu, 31 Mar 2016 14:45:14 +0000</pubDate>
		<dc:creator>Joanna Byjoś</dc:creator>
				<category><![CDATA[Main]]></category>
		<category><![CDATA[backup]]></category>
		<category><![CDATA[protection]]></category>
		<category><![CDATA[security]]></category>
		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">https://www.blog.modulesgarden.com/?p=2769</guid>
		<description><![CDATA[Whether it is intentional or by accident – the merest click can become a real culprit behind a digital fiasco. A fleeting moment of inattention that turned into a drink spilled on your laptop might also be a potential headache &#8230; <a href="https://www.blog.modulesgarden.com/world-backup-day">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">Whether it is intentional or by accident – the merest click can become a real culprit behind a digital fiasco. A fleeting moment of inattention that turned into a drink spilled on your laptop might also be a potential headache of your data being gone beyond retrieval. These, alongside the other types of risks are counted in thousands in today&#8217;s electronic-based reality, but they all can be averted successfully by following one good practice – <strong>a solid strategy of making regular data backups.<span id="more-2769"></span></strong></p>
<p style="text-align: justify;">In honor of World Backup Day that falls on March 31st, we wish to share with you our winning formula for maintaining foolproof data protection.</p>
<p style="text-align: center;"><img class=" wp-image-2781 aligncenter" style="padding: 0px; border: 0px none;" src="https://www.blog.modulesgarden.com/wp-content/uploads/2016/03/ModulesGarden-World-Backup-Day-2016.jpg" alt="ModulesGarden World Backup Day 2016" width="580" height="580" /></p>
<p style="text-align: justify;">What you should do in the first place is realize that it is not just computers that serve as a data repository anymore. These are also smartphones, tablets and plenty of different devices in everyday use that store huge amounts of information, the loss of which might turn out severely damaging to either your personal or business sphere (or both!). It is therefore of utmost importance to think ahead and ensure the perfect safety of documents, photos, videos, emails and absolutely anything of digital kind that you value.</p>
<p style="text-align: justify;">So how exactly can you prepare for the unexpected? A whole myriad of options exists for you to protect your files against any loss. The more of these methods you introduce to your usual routine, the smaller the risk of ever suffering the trauma of data disappearance will be.</p>
<p style="text-align: justify;">Simply put, a backup is an exact copy of your intangible valuables. Instead of keeping them all in a single place, you store a separate copy of each file somewhere safe. Conventional wisdom has it that your digital content can be utterly secured upon the adoption of <strong>the backup rule of three</strong>, also known as the 3-2-1 rule:</p>
<ol>
<li>Have at least 3 copies of your data (i.e. two backup files in addition to the original content).</li>
<li>Store the backups on 2 different media types (such as USB drives, optical media, SD-cards, external and internal hard drives, etc.).</li>
<li>Keep 1 backup off-site (ensure that the copies are saved on physically separated devices – the farther the better!).</li>
</ol>
<p style="text-align: justify;">Take some time to cruise through different backup mechanisms and alternative solutions like <span style="text-decoration: underline;"><a href="http://www.modulesgarden.com/products/whmcs/r1soft_backups/features" target="_blank"><span style="color: #3366ff; text-decoration: underline;">this one</span></a></span>, to decide which approach suits you and your clients the most. Regardless of your choice, keep in mind: it is not just about backups, it is about your personal well-being and business continuity!</p>
]]></content:encoded>
			<wfw:commentRss>https://www.blog.modulesgarden.com/world-backup-day/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Practical Tips To Defend Against DDoS Attacks</title>
		<link>https://www.blog.modulesgarden.com/practical-tips-to-defend-against-ddos-attacks</link>
		<comments>https://www.blog.modulesgarden.com/practical-tips-to-defend-against-ddos-attacks#comments</comments>
		<pubDate>Wed, 29 Apr 2015 14:03:27 +0000</pubDate>
		<dc:creator>Joanna Byjoś</dc:creator>
				<category><![CDATA[Main]]></category>
		<category><![CDATA[backup]]></category>
		<category><![CDATA[DDoS]]></category>
		<category><![CDATA[DNS]]></category>
		<category><![CDATA[protection]]></category>
		<category><![CDATA[scanner]]></category>
		<category><![CDATA[security]]></category>
		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">https://www.blog.modulesgarden.com/?p=1834</guid>
		<description><![CDATA[Imagine your average day at work. Managing orders, monitoring transactions, providing services, just as usual&#8230; but then, out of nowhere, your website has just disappeared and all orders and services have gone down. If something like this happens to you, &#8230; <a href="https://www.blog.modulesgarden.com/practical-tips-to-defend-against-ddos-attacks">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">Imagine your average day at work. Managing orders, monitoring transactions, providing services, just as usual&#8230; but then, out of nowhere, your website has just disappeared and all orders and services have gone down. If something like this happens to you, then there is a strong possibility that you have become yet another victim of  Distributed Denial of Service (DDoS) attack.<strong><span id="more-1834"></span></strong></p>
<p style="text-align: justify;">DDoS attacks have become one of the most common disastrous attacks on the Internet. The number of attacks along with their size and intensity has increased substantially: in the space of just last year 57% rise in total DDoS attacks have been reported. That is why we want to share with you some of practical tips to defend against DDoS attacks and actions worth taking while experiencing the attack to minimize losses:</p>
<p style="text-align: justify;"><strong>1.</strong> One of the well-known approaches to handling DDoS attacks is over-provisioning. In order to scotch the attack and reduce its impact on your clients you need to provision for far more traffic than you usually expect to receive. How much should be enough? Estimate the largest amount of traffic that you have ever had, multiply it by ten and adapt your hardware infrastructure to cope with this level of traffic. It will make much more difficult for an attacker to generate enough traffic to bring down your company&#8217;s network.</p>
<p style="text-align: center;"><img class="size-full wp-image-1835 aligncenter" src="https://www.blog.modulesgarden.com/wp-content/uploads/2015/03/DDoS-Attacks-In-Q4-2014-Per-Country.png" alt="DDoS Attacks In Q4 2014 Per Country" width="534" height="480" /></p>
<p style="text-align: justify;"><strong>2.</strong> If you are experiencing DDoS attack you need to consider disconnect<span style="font-size: medium;">ing</span><span style="font-size: medium;"> from a network. It will result in </span><span style="font-size: medium;">taking your business off-line and </span><span style="font-size: medium;">cutting off access to all your products and services but at the same time it will prevent from further utilizing network resources.</span></p>
<p style="text-align: justify;"><strong>3.</strong> Additionally, you can perform DNS redirection by changing an &#8220;A&#8221; record which provides servers with the IP address of your domain. Keep in mind that you have to notify your clients about it so they can enter new IP address in order to keep using services of current network provider. This method is as effective as quickly DNS propagation is proceeded. It may take even a few hours and often requires a direct contact with a hosting service provider.</p>
<p style="text-align: justify;"><strong>4.</strong> IP addresses are cached by servers around the world for a specific period of time (measured in seconds) which is known as &#8220;Time to live&#8221; (TTL). Usually, default TTL value is 86400 seconds (24 hours), which may be far too long if you are under DDoS attack. You can reduce losses by controlling TTL value: the shorter TTL value, the quicker you will be able to redirect all web site requests to a new IP address. You need to, however, bear in mind that shorter TTL value means more frequent requests which, in turn, increases the load on your DNS host.</p>
<p style="text-align: justify;"><strong>5.</strong> Changing DNS or even migrating to another server may be not sufficient to completely resolve the problem. If an attacker finds out what your intentions are, the attack will be redirected to a new target and everything may start all over again. Therefore, it is also worth giving some thought to cloud-based traffic scrubbing services which are able to quickly filter out malicious software from data stream. Data cleansing service providers are the first line of defence against high-volume DDoS attacks &#8211; they have sufficient bandwidth and proper tools to filter network traffic which stems DDoS packets within the cloud and pass normal traffic to the company network.</p>
<p style="text-align: center;"><img class=" wp-image-1836 aligncenter" title="DDoS Attacks In Q4 2014 Per Industry" src="https://www.blog.modulesgarden.com/wp-content/uploads/2015/03/DDoS-Attacks-In-Q4-2014-Per-Industry.png" alt="" width="533" height="532" /></p>
<p style="text-align: justify;"><strong>6.</strong> You may also take into consideration some additional services, such as CloudFlare. They monitor network traffic and collect data that are used as a basis to assess the risk of possible attacks. Thanks to this, each attack attempt is thwarted before it does any damage. What is more, in case of a serious attack, they are able to restore a webpage and revert back any negative changes using previously made backup files. This way, users may not even notice the malfunction.</p>
<p style="text-align: justify;">Destructive power of DDoS attacks cannot be disregarded. <span style="font-size: medium;">Every company needs to ensure its</span> sustained operation <span style="font-size: medium;">and resource availability by remaining vigilant and taking all possible measures </span><span style="font-size: medium;">to mitigate the risk of </span><span style="font-size: medium;">being hit before it happens.</span></p>
]]></content:encoded>
			<wfw:commentRss>https://www.blog.modulesgarden.com/practical-tips-to-defend-against-ddos-attacks/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Preventing Problems With Software Implementation</title>
		<link>https://www.blog.modulesgarden.com/preventing-problems-with-software-implementation</link>
		<comments>https://www.blog.modulesgarden.com/preventing-problems-with-software-implementation#comments</comments>
		<pubDate>Thu, 11 Dec 2014 12:21:36 +0000</pubDate>
		<dc:creator>Joanna Byjoś</dc:creator>
				<category><![CDATA[Main]]></category>
		<category><![CDATA[backup]]></category>
		<category><![CDATA[custom software]]></category>
		<category><![CDATA[security]]></category>
		<category><![CDATA[software]]></category>
		<category><![CDATA[software development]]></category>
		<category><![CDATA[software implementation]]></category>
		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">https://www.blog.modulesgarden.com/?p=1687</guid>
		<description><![CDATA[In the early 16th century Dutch philosopher Desiderius Erasmus famously said: &#8220;Prevention is better than cure&#8221; but we bet he had no idea how much this sentence&#8217;s significance will expand through the next 500 years. Nowadays, in the world dominated &#8230; <a href="https://www.blog.modulesgarden.com/preventing-problems-with-software-implementation">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">In the early 16th century Dutch philosopher Desiderius Erasmus famously said: &#8220;Prevention is better than cure&#8221; but we bet he had no idea how much this sentence&#8217;s significance will expand through the next 500 years.<strong><span id="more-1687"></span></strong></p>
<p style="text-align: justify;">Nowadays, in the world dominated by information technology, Erasmus&#8217;s words of wisdom can be interpreted in a completely new way. Their meaning may be successfully transfered into various fields not necessarily related to medicine.</p>
<p style="text-align: justify;">Nobody needs to be told that it is better and easier to prevent health problems than cure them. In this article we want to show you that the exact same idea applies to any sort of software problems. If you own or plan to purchase modules, or introduce custom software solutions to your business, the following tips will be the best guide to ensure the safety of yours and your clients&#8217; systems.</p>
<p style="text-align: justify;"><strong>1. Prepare Test Environment</strong><br />
The first thing to do before going live, especially if you own a custom made module, is testing it in the development environment. You should check the features and try out all functions of the product to make sure that it will integrate well with your system and avoid any problems after implementation. If something goes wrong in the testing phase, we are always at your disposal to find a solution.</p>
<p style="text-align: justify;">If you do not know how or have no time to organise test environment, keep in mind that we can do it for you!</p>
<p style="text-align: justify;"><strong>2. Make A Backup</strong><br />
Data protection should be a priority for every business owner. Loss of information may cause severe damage to companies of all sizes. That is why we highly recommend you to make a backup before introducing any changes to your system. This way you will be able to quickly restore the data in case of any unexpected deletion. In other words, keeping backup files will allow you to easily revert back the changes if something does not go the way it should.</p>
<p style="text-align: justify;">To convince yourself how important data protection is, take a look at the following table showing the cost of re-creating merely 20 MB of data:</p>
<p style="text-align: justify;"><img class="alignnone size-full wp-image-1709" src="https://www.blog.modulesgarden.com/wp-content/uploads/2014/12/Table-Of-Data-Re-creating-Costs.jpg" alt="Table Of Data Re-creating Costs" width="585" height="136" /></p>
<p style="text-align: justify;"><strong>3. Installation Service</strong><br />
Not certain how to handle the process of installation? You can have it done capably by our specialist within 48 hours from purchasing the product. Simply tick &#8216;Installation Service&#8217; field while ordering.</p>
<p style="text-align: justify;"><strong>4. Use The Help Of Professional</strong><br />
The configuration of the environment is a complex process. Doing all the required steps properly is extremely important because your system&#8217;s efficiency depends on that. You can manage it on your own with the help of tutorials available on our Wiki but if you are not sure how to proceed, call on professionals. In particular, if you order a custom made product, turn to our support team for necessary help with its configuration.</p>
<p style="text-align: justify;"><strong>5. Choose The Right Moment</strong><br />
When you want to implement a module or other software solution, especially if it is custom made, make sure that you are able to devote enough time for it and nothing will distract you. Avoid times when you are overloaded with work. Also, keep in mind that our support may be limited during weekends so it may be better to proceed with implementation on working days.</p>
<p style="text-align: justify;"><strong>6. Test The Software</strong><br />
Even if you tried out a module in the test environment do not forget to do it once again after going live. Check if all functions work as expected and if not, use previously made backup files to undo changes.</p>
<p style="text-align: justify;">Remember that we do our best to provide you with high quality custom software development but we cannot predict everything. Make sure to go through all of above-mentioned steps to minimise the risk of any adverse effects. And in case something goes wrong, do not hesitate to contact ModulesGarden!</p>
]]></content:encoded>
			<wfw:commentRss>https://www.blog.modulesgarden.com/preventing-problems-with-software-implementation/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Recurring Payments In Magento</title>
		<link>https://www.blog.modulesgarden.com/recurring-payments-in-magento</link>
		<comments>https://www.blog.modulesgarden.com/recurring-payments-in-magento#comments</comments>
		<pubDate>Mon, 30 Jun 2014 12:20:29 +0000</pubDate>
		<dc:creator>Piotr Dołęga</dc:creator>
				<category><![CDATA[Main]]></category>
		<category><![CDATA[eCommerce]]></category>
		<category><![CDATA[extensions]]></category>
		<category><![CDATA[Magento]]></category>
		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">https://www.blog.modulesgarden.com/?p=1052</guid>
		<description><![CDATA[We would like to discuss one of the most interesting payment functionalities of Magento &#8211; recurring payments. It is not an easy task to find a complete guide showing how to set up a recurring profile step-by-step therefore we decided &#8230; <a href="https://www.blog.modulesgarden.com/recurring-payments-in-magento">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;"><strong></strong>We would like to discuss one of the most interesting payment functionalities of Magento &#8211; recurring payments. It is not an easy task to find a complete guide showing how to set up a recurring profile step-by-step therefore we decided to create one.<strong><span id="more-1052"></span></strong></p>
<p style="text-align: justify;">Magento&#8217;s payment gateway sample for recurring profiles includes all the functionalities (but trials) that recurring profiles for products have: different billing period units, frequency, initial fee etc. A necessary functionality, autocharging, had to be created by us and it is contained in our sample which we will describe in details below. In Magento CE, there is only one recurring gateway installed &#8211; PayPal. However, there is no barrier to create another one, and that is why we are posting our sample.</p>
<p style="text-align: justify;"><strong>1. Why you should care</strong><br />
As a WHMCS experts we know that recurring payments are often used in the hosting industry. Why do not use it in your Magento store to increase your sales? We are very surprised that this part is still a niche in the Magento market. For more info about recurring profiles, see <span style="text-decoration: underline;"><span style="color: #3366ff;"><a title="Magento KnowledeBase - Recurring Profiles" href="http://www.magentocommerce.com/knowledge-base/entry/working-with-recurring-profiles" target="_blank"><span style="color: #3366ff; text-decoration: underline;">official Magento knowledgebase</span></a></span></span>.</p>
<p style="text-align: justify;"><strong>2. Download the sample</strong><br />
You can test it in your development Magento installation. Do not install it on production Magento as this is just a demo of recurring profiles. Installation is very simple: Download zip package, upload it to your Magento, clear cache and new section should appear at System &gt; Configuration &gt; Payment Methods &gt; Recurring Payments Sample. We tested it on Magento CE versions 1.8.1.0 and 1.9.0.0. Download link can be found in further part of the article.</p>
<p style="text-align: center;"><img class="aligncenter  wp-image-1109" src="https://www.blog.modulesgarden.com/wp-content/uploads/2014/06/ModulesGarden-Magento-Ordering.png" alt="ModulesGarden Magento - Ordering" width="864" height="565" /><strong></strong></p>
<p style="text-align: justify;"><strong>3. How it works (step-by-step)</strong><br />
After installing the extension, administrator should go to the gateway configuration (System &gt; Configuration &gt; Payment Methods &gt; Recurring Payments Sample) and enable it. API ID and API Key are just fake fields and there is no need to fill them (more about it in programming description below). After that, you should create product that will have a recurring profile enabled. When client buys this product there are two API calls which are sent to the real gateway (of course not in sample case): first for recurring initialization with initial fee, and second one for the first payment. That part could be different for other gateways. Extension adds cron job for sending request to the remote API when profile should be charged. Magento does not do that and we have to use very long SQL query for checking all of recurring profiles. On next profile&#8217;s time period our gateway is trying to charge it. After successful attempt, new order is created with transaction assigned.</p>
<p style="text-align: center;"><img class="aligncenter  wp-image-1107" src="https://www.blog.modulesgarden.com/wp-content/uploads/2014/06/ModulesGarden-Magento-Backend-Profile.png" alt="ModulesGarden Magento - Backend Profile" width="1109" height="603" /><strong></strong></p>
<p style="text-align: justify;"><strong>4. Programming description</strong><br />
In this part we assume that you have a basic knowledge how to build Magento Extension. We will put attention to the gateway part and skip basic explanations.</p>
<p style="text-align: justify;"><strong>4.1 Configuration</strong><br />
The first thing what we would like to do is to create configuration for our gateway. In extension&#8217;s <em>etc/system.xml</em> we will use:</p>
<p></p><pre class="crayon-plain-tag">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;config&gt;
    &lt;sections&gt;
        &lt;payment&gt;
            &lt;groups&gt;
                &lt;recurringpaymentssample translate="label comment" module="recurringpaymentssample"&gt;
                    &lt;label&gt;Recurring Payments Sample&lt;/label&gt;
                    &lt;frontend_type&gt;text&lt;/frontend_type&gt;
                    &lt;sort_order&gt;10&lt;/sort_order&gt;
                    &lt;show_in_default&gt;1&lt;/show_in_default&gt;
                    &lt;show_in_website&gt;1&lt;/show_in_website&gt;
                    &lt;show_in_store&gt;1&lt;/show_in_store&gt;
                    &lt;fields&gt;
                        &lt;active translate="label"&gt;
                            &lt;label&gt;Enabled&lt;/label&gt;
                            &lt;frontend_type&gt;select&lt;/frontend_type&gt;
                            &lt;source_model&gt;adminhtml/system_config_source_yesno&lt;/source_model&gt;
                            &lt;sort_order&gt;10&lt;/sort_order&gt;
                            &lt;show_in_default&gt;1&lt;/show_in_default&gt;
                            &lt;show_in_website&gt;1&lt;/show_in_website&gt;
                            &lt;show_in_store&gt;0&lt;/show_in_store&gt;
                        &lt;/active&gt;
                        &lt;title translate="label"&gt;
                            &lt;label&gt;Title&lt;/label&gt;
                            &lt;frontend_type&gt;text&lt;/frontend_type&gt;
                            &lt;sort_order&gt;20&lt;/sort_order&gt;
                            &lt;show_in_default&gt;1&lt;/show_in_default&gt;
                            &lt;show_in_website&gt;1&lt;/show_in_website&gt;
                            &lt;show_in_store&gt;0&lt;/show_in_store&gt;
                        &lt;/title&gt;
                        &lt;api_id&gt;
                            &lt;label&gt;API ID&lt;/label&gt;
                            &lt;frontend_type&gt;obscure&lt;/frontend_type&gt;
                            &lt;backend_model&gt;adminhtml/system_config_backend_encrypted&lt;/backend_model&gt;
                            &lt;sort_order&gt;60&lt;/sort_order&gt;
                            &lt;show_in_default&gt;1&lt;/show_in_default&gt;
                            &lt;show_in_website&gt;1&lt;/show_in_website&gt;
                            &lt;show_in_store&gt;0&lt;/show_in_store&gt;
                        &lt;/api_id&gt;
                        &lt;api_key&gt;
                            &lt;label&gt;API Key&lt;/label&gt;
                            &lt;frontend_type&gt;obscure&lt;/frontend_type&gt;
                            &lt;backend_model&gt;adminhtml/system_config_backend_encrypted&lt;/backend_model&gt;
                            &lt;sort_order&gt;62&lt;/sort_order&gt;
                            &lt;show_in_default&gt;1&lt;/show_in_default&gt;
                            &lt;show_in_website&gt;1&lt;/show_in_website&gt;
                            &lt;show_in_store&gt;0&lt;/show_in_store&gt;
                        &lt;/api_key&gt;
                        &lt;cctypes translate="label"&gt;
                            &lt;label&gt;Credit Card Types&lt;/label&gt;
                            &lt;frontend_type&gt;multiselect&lt;/frontend_type&gt;
                            &lt;source_model&gt;paygate/authorizenet_source_cctype&lt;/source_model&gt;
                            &lt;sort_order&gt;64&lt;/sort_order&gt;
                            &lt;show_in_default&gt;1&lt;/show_in_default&gt;
                            &lt;show_in_website&gt;1&lt;/show_in_website&gt;
                            &lt;show_in_store&gt;0&lt;/show_in_store&gt;
                        &lt;/cctypes&gt;
                        &lt;allowspecific translate="label"&gt;
                            &lt;label&gt;Payment Applicable From&lt;/label&gt;
                            &lt;frontend_type&gt;select&lt;/frontend_type&gt;
                            &lt;sort_order&gt;65&lt;/sort_order&gt;
                            &lt;source_model&gt;adminhtml/system_config_source_payment_allspecificcountries&lt;/source_model&gt;
                            &lt;show_in_default&gt;1&lt;/show_in_default&gt;
                            &lt;show_in_website&gt;1&lt;/show_in_website&gt;
                            &lt;show_in_store&gt;0&lt;/show_in_store&gt;
                        &lt;/allowspecific&gt;
                        &lt;specificcountry translate="label"&gt;
                            &lt;label&gt;Countries Payment Applicable From&lt;/label&gt;
                            &lt;frontend_type&gt;multiselect&lt;/frontend_type&gt;
                            &lt;sort_order&gt;66&lt;/sort_order&gt;
                            &lt;source_model&gt;adminhtml/system_config_source_country&lt;/source_model&gt;
                            &lt;depends&gt;
                                &lt;allowspecific&gt;1&lt;/allowspecific&gt;
                            &lt;/depends&gt;
                            &lt;show_in_default&gt;1&lt;/show_in_default&gt;
                            &lt;show_in_website&gt;1&lt;/show_in_website&gt;
                            &lt;show_in_store&gt;0&lt;/show_in_store&gt;
                        &lt;/specificcountry&gt;
                        &lt;sort_order translate="label"&gt;
                            &lt;label&gt;Sort Order&lt;/label&gt;
                            &lt;frontend_type&gt;text&lt;/frontend_type&gt;
                            &lt;sort_order&gt;70&lt;/sort_order&gt;
                            &lt;show_in_default&gt;1&lt;/show_in_default&gt;
                            &lt;show_in_website&gt;1&lt;/show_in_website&gt;
                            &lt;show_in_store&gt;0&lt;/show_in_store&gt;
                        &lt;/sort_order&gt;
                    &lt;/fields&gt;
                &lt;/recurringpaymentssample&gt;
            &lt;/groups&gt;
        &lt;/payment&gt;
    &lt;/sections&gt;
&lt;/config&gt;</pre><p></p>
<p style="text-align: justify;">This file is mostly self-explanatory. You can create as many fields as gateway requires. We added fake fields api_id and api_key. In real gateway they could be used. Fields <em>&#8216;active&#8217;</em>, <em>&#8216;title&#8217;</em>, <em>&#8216;cctypes&#8217;</em>, <em>&#8216;allowspecific&#8217;</em>, <em>&#8216;specificcountry&#8217;</em>,<em> &#8216;sort_order&#8217;</em> are used by default Magento mechanisms and should be used in all of gateways.</p>
<p style="text-align: center;"><img class="aligncenter  wp-image-1108" src="https://www.blog.modulesgarden.com/wp-content/uploads/2014/06/ModulesGarden-Magento-Configuration.png" alt="ModulesGarden Magento - Configuration" width="891" height="690" /><strong></strong></p>
<p style="text-align: justify;"><strong>4.2 Gateway</strong><br />
Magento should &#8220;know&#8221; that we would like to add payment gateway and we should define it in <em>etc/config.xml</em> file:</p>
<p></p><pre class="crayon-plain-tag">&lt;config&gt;
    ...
    &lt;default&gt;
        &lt;payment&gt;
            &lt;recurringpaymentssample&gt;
                &lt;model&gt;recurringpaymentssample/payment&lt;/model&gt;
                &lt;title&gt;Recurring Payments Sample&lt;/title&gt;
                &lt;enabled&gt;1&lt;/enabled&gt;
                &lt;sort_order&gt;0&lt;/sort_order&gt;
            &lt;/recurringpaymentssample&gt;
        &lt;/payment&gt;
    &lt;/default&gt;
    ...
&lt;/config&gt;</pre><p>This part describes that main payment PHP class will be located in extensions&#8217;s <em>Model/Payment.php</em> and named <em>Modulesgarden_Recurringpaymentssample_Model_Payment</em>. The important fact is that class must extend <em>Mage_Payment_Model_Method_Abstract</em> and implement <em>Mage_Payment_Model_Recurring_Profile_MethodInterface</em>. Now Magento &#8220;knows&#8221; exactly what we want to do. Our class must implement these methods:</p>
<ul style="text-align: justify;">
<li>validateRecurringProfile</li>
<li>submitRecurringProfile (this is the most important method &#8211; it will send our profile to the gateway after order of recurring product)</li>
<li>getRecurringProfileDetails</li>
<li>canGetRecurringProfileDetails</li>
<li>updateRecurringProfile</li>
<li>updateRecurringProfileStatus</li>
</ul>
<p style="text-align: justify;">All of methods are logged in Magento log files in <em>var/log/recurringpaymentssample.log</em> file (enable logging in Magento configuration), so you can monitor what and when is called. Check out the screenshot of logs after placing an order.</p>
<p style="text-align: center;"><img class="aligncenter  wp-image-1106" src="https://www.blog.modulesgarden.com/wp-content/uploads/2014/06/ModulesGarden-Magento-After-Ordering.png" alt="ModulesGarden Magento - After Ordering" width="1259" height="293" /></p>
<p style="text-align: justify;">Source code for <em>submitRecurringProfile</em> method:</p>
<p></p><pre class="crayon-plain-tag">public function submitRecurringProfile(Mage_Payment_Model_Recurring_Profile $profile, Mage_Payment_Model_Info $payment){

        Mage::log(__METHOD__.'; Profile #'.$profile-&gt;getId(), null, 'recurringpaymentssample.log');

        $response = $this-&gt;_sendRequest('chargeInitAmount', array(
            'amount' =&gt; $profile-&gt;getInitAmount()
        ));

        if ($response['result'] == 'SUCCESS'){
            $profile-&gt;setReferenceId( $response['token'] );
            $payment-&gt;setSkipTransactionCreation(true);

            // add order assigned to the recurring profile with initial fee
            if ((float)$profile-&gt;getInitAmount()){
                $productItemInfo = new Varien_Object;
                $productItemInfo-&gt;setPaymentType(Mage_Sales_Model_Recurring_Profile::PAYMENT_TYPE_INITIAL);
                $productItemInfo-&gt;setPrice($profile-&gt;getInitAmount());

                $order = $profile-&gt;createOrder($productItemInfo);
                $trans_id = 'trans-' . uniqid();

                $payment = $order-&gt;getPayment();
                $payment-&gt;setTransactionId($trans_id)-&gt;setIsTransactionClosed(1);
                $order-&gt;save();
                $profile-&gt;addOrderRelation($order-&gt;getId());
                $order-&gt;save();
                $payment-&gt;save();

                $transaction= Mage::getModel('sales/order_payment_transaction');
                $transaction-&gt;setTxnId($trans_id);
                $transaction-&gt;setTxnType(Mage_Sales_Model_Order_Payment_Transaction::TYPE_CAPTURE);
                $transaction-&gt;setPaymentId($payment-&gt;getId());
                $transaction-&gt;setOrderId($order-&gt;getId());
                $transaction-&gt;setOrderPaymentObject($payment);
                $transaction-&gt;setIsClosed( 1 );
                $transaction-&gt;save();
            }

            // send fake request to charge
            $this-&gt;chargeRecurringProfile($profile);

            return $this;

        } else {

            if (!$profile-&gt;getInitMayFail()){
                $profile-&gt;setState(Mage_Sales_Model_Recurring_Profile::STATE_SUSPENDED);
                $profile-&gt;save();
            }

            Mage::throwException( $response['msg'] );

        }
    }</pre><p></p>
<p style="text-align: justify;">The problem with this gateway is that it will be shown while ordering of all products (non-recurring). To hide it from regular payments we have to create another method (overwrite from parent):</p>
<p></p><pre class="crayon-plain-tag">public function canUseCheckout(){
        $cart = Mage::getModel('checkout/cart')-&gt;getQuote();
        foreach ($cart-&gt;getAllItems() as $item) {
            if (!$item-&gt;getProduct()-&gt;getIsRecurring())
                return false;
        }
        return true;
    }</pre><p></p>
<p style="text-align: justify;">Methods checks whether the cart contains &#8220;regular&#8221; products. If so, then just disables it.</p>
<p style="text-align: justify;"><strong>4.3 Cron</strong><br />
The first question is: where is the method for cyclical payments? There is no such method! PayPal (the only recurring gateway in Magento) does the job on its side and does not require it. We have to implement it by ourselves. In <em>config.xml</em> file we have to add cron job:</p>
<p></p><pre class="crayon-plain-tag">&lt;config&gt;
    ...
    &lt;crontab&gt;
        &lt;jobs&gt;
            &lt;recurringpaymentssample_charge&gt;
                &lt;schedule&gt;
                    &lt;cron_expr&gt;* * * * *&lt;/cron_expr&gt;
                &lt;/schedule&gt;
                &lt;run&gt;
                    &lt;model&gt;recurringpaymentssample/observer::chargeRecurringProfiles&lt;/model&gt;
                &lt;/run&gt;
            &lt;/recurringpaymentssample_charge&gt;
        &lt;/jobs&gt;
    &lt;/crontab&gt;
    ...
&lt;/config&gt;</pre><p>It will call<em> Modulesgarden_Recurringpaymentssample_Model_Observer::chargeRecurringProfiles</em> every minute (just for example). This method runs log SQL query for profiles that needs top be charged:</p><pre class="crayon-plain-tag">class Modulesgarden_Recurringpaymentssample_Model_Observer {

    /**
     * Cron job method to charge recurring profiles
     *
     * @param Mage_Cron_Model_Schedule $schedule
     */
    public function chargeRecurringProfiles(Mage_Cron_Model_Schedule $schedule){
        Mage::log('Cron run, '.__METHOD__, null, 'recurringpaymentssample.log');

        $_resource = Mage::getSingleton('core/resource');
        $sql = '
            SELECT
                CASE srp.period_unit
                    WHEN "day"             THEN FLOOR(DATEDIFF(NOW(), srp.updated_at) / srp.period_frequency)
                    WHEN "week"         THEN FLOOR(FLOOR(DATEDIFF(NOW(), srp.updated_at) / 7) / srp.period_frequency)
                    WHEN "semi_month"     THEN FLOOR(FLOOR(DATEDIFF(NOW(), srp.updated_at) / 14) / srp.period_frequency)
                    WHEN "month"         THEN FLOOR(PERIOD_DIFF(DATE_FORMAT(NOW(), "%Y%m"), DATE_FORMAT(srp.updated_at, "%Y%m")) - (DATE_FORMAT(NOW(), "%d") &lt; DATE_FORMAT(srp.updated_at, "%d")) / srp.period_frequency)
                    WHEN "year"         THEN FLOOR(YEAR(NOW()) - YEAR(srp.updated_at) - (DATE_FORMAT(NOW(), "%m%d") &lt; DATE_FORMAT(srp.updated_at, "%m%d")) / srp.period_frequency)
                END
                AS billing_count,
                srp.*
            FROM '.$_resource-&gt;getTableName('sales_recurring_profile').' AS srp
            WHERE
                srp.method_code = "recurringpaymentssample" AND
                srp.state = "active" AND
                srp.updated_at &lt;= NOW() AND
                srp.start_datetime &lt;= NOW() AND
                NOW() &gt;= CASE srp.period_unit
                    WHEN "day"             THEN DATE_ADD(srp.updated_at, INTERVAL srp.period_frequency DAY)
                    WHEN "week"         THEN DATE_ADD(srp.updated_at, INTERVAL srp.period_frequency WEEK)
                    WHEN "semi_month"     THEN DATE_ADD(srp.updated_at, INTERVAL (srp.period_frequency * 2) WEEK)
                    WHEN "month"         THEN DATE_ADD(srp.updated_at, INTERVAL srp.period_frequency MONTH)
                    WHEN "year"         THEN DATE_ADD(srp.updated_at, INTERVAL srp.period_frequency YEAR)
                END
        ';

        $connection = $_resource-&gt;getConnection('core_read');
        $recurring = Mage::getModel('recurringpaymentssample/payment');

        foreach ($connection-&gt;fetchAll($sql) as $profileArr) {

            $profile = Mage::getModel('sales/recurring_profile')-&gt;addData($profileArr);
            $orders = $profile-&gt;getResource()-&gt;getChildOrderIds($profile);
            $countBillingCycling = count($orders);
            if ($profile-&gt;getInitAmount())
                $countBillingCycling--;

            if ($profile-&gt;getBillFailedLater()){ // Auto Bill on Next Cycle
                // multi charges
                for ($i = 0; $i &lt; $profile-&gt;getBillingCount(); $i++){
                    if ($recurring-&gt;chargeRecurringProfile($profile)){
                        $countBillingCycling++;
                    } else {
                        break;
                    }

                    if ($countBillingCycling &gt;= $profile-&gt;getPeriodMaxCycles()){
                        $profile-&gt;setState(Mage_Sales_Model_Recurring_Profile::STATE_SUSPENDED);
                        break;
                    }
                }

            } else {
                // single charge
                if ($recurring-&gt;chargeRecurringProfile($profile))
                    $countBillingCycling++;

                if ($countBillingCycling &gt;= $profile-&gt;getPeriodMaxCycles())
                    $profile-&gt;setState(Mage_Sales_Model_Recurring_Profile::STATE_SUSPENDED);
            }
        }
    }

}</pre><p></p>
<p style="text-align: justify;">Finally, the method for charging a profile:</p>
<p></p><pre class="crayon-plain-tag">public function chargeRecurringProfile(Mage_Payment_Model_Recurring_Profile $profile){
        Mage::log(__METHOD__.'; Profile #'.$profile-&gt;getId(), null, 'recurringpaymentssample.log');

        // send fake request to charge
        $responseRecurring = $this-&gt;_sendRequest('chargeRecurringAmount', array(
            'amount' =&gt; $profile-&gt;getTaxAmount() + $profile-&gt;getBillingAmount() + $profile-&gt;getShippingAmount(),
            'token' =&gt; $profile-&gt;getReferenceId()
        ));

        if ($responseRecurring['result'] == 'SUCCESS'){
            $productItemInfo = new Varien_Object;
            $productItemInfo-&gt;setPaymentType(Mage_Sales_Model_Recurring_Profile::PAYMENT_TYPE_REGULAR);
            $productItemInfo-&gt;setPrice( $profile-&gt;getTaxAmount() + $profile-&gt;getBillingAmount() + $profile-&gt;getShippingAmount() );

            $order = $profile-&gt;createOrder($productItemInfo);
            $order-&gt;setState(Mage_Sales_Model_Order::STATE_NEW);
            $trans_id = 'trans-' . uniqid();

            $payment = $order-&gt;getPayment();
            $payment-&gt;setTransactionId($trans_id)-&gt;setIsTransactionClosed(1);
            $order-&gt;save();
            $profile-&gt;addOrderRelation($order-&gt;getId());
            $payment-&gt;save();

            $transaction= Mage::getModel('sales/order_payment_transaction');
            $transaction-&gt;setTxnId($trans_id);
            $transaction-&gt;setTxnType(Mage_Sales_Model_Order_Payment_Transaction::TYPE_CAPTURE);
            $transaction-&gt;setPaymentId($payment-&gt;getId());
            $transaction-&gt;setOrderId($order-&gt;getId());
            $transaction-&gt;setOrderPaymentObject($payment);
            $transaction-&gt;setIsClosed( 1 );
            $transaction-&gt;save();

            $profile-&gt;setState(Mage_Sales_Model_Recurring_Profile::STATE_ACTIVE);

            // change updated_at to one cycle ahead
            $this-&gt;_setUpdateDateToNextPeriod($profile-&gt;getId());

            return true;

        }

        return false;
    }</pre><p></p>
<p style="text-align: justify;">To get the full source code, just download the sample gateway from the link below.</p>
<p style="text-align: justify;"><a title="Download ModulesGarden Recurring Profiles Sample For Magento" href="https://www.modulesgarden.com/client-area/dl.php?type=d&#038;id=226"><strong><span style="text-decoration: underline; font-color: green; background: #ffffcc; font-size: 17px;">Download ModulesGarden Recurring Profiles Sample For Magento</span></strong></a></p>
<p style="text-align: justify;"><strong>5. Amazing extension &#8211; GPN DATA For Magento</strong></p>
<p style="text-align: justify;">GPN DATA payment gateway offers reliable and secure online payment solutions for IT business all over the world. A big piece of cake of that business are online stores, such as Magento.</p>
<p style="text-align: justify;">We have created a payment gateway for recurring profiles. It is named GPN DATA For Magento. It is using a similar logic as in this sample extension showed above but it is a little bit more complex. The real gateway is called in that case. The communication exists in both directions: magento-gateway and gateway-magento. These are GPN DATA requirements. Owing to GPN DATA For Magento module you will be able implement proven GPN DATA services directly to your sales platform.</p>
<p style="text-align: justify;">For more information visit our <span style="text-decoration: underline;"><strong><span style="color: #3366ff;"><a title="GPN DATA For Magento" href="http://www.modulesgarden.com/products/magento/gpn_data/features" target="_blank"><span style="color: #3366ff; text-decoration: underline;">website</span></a></span></strong></span>.</p>
<p style="text-align: justify;"><strong>6. Summary</strong><br />
This is a great opportunity for your online store to earn more money. We could also create such a gateway for you &#8211; just ask us for a custom software development <span style="text-decoration: underline;"><strong><span style="color: #3366ff; text-decoration: underline;"><a title="Magento Custom Software Development" href="https://www.modulesgarden.com/order/request" target="_blank"><span style="color: #3366ff; text-decoration: underline;">here</span></a></span></strong></span>.</p>
]]></content:encoded>
			<wfw:commentRss>https://www.blog.modulesgarden.com/recurring-payments-in-magento/feed</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
		<item>
		<title>Amazing Report Generator For WHMCS</title>
		<link>https://www.blog.modulesgarden.com/amazing-report-generator-for-whmcs</link>
		<comments>https://www.blog.modulesgarden.com/amazing-report-generator-for-whmcs#comments</comments>
		<pubDate>Fri, 30 May 2014 07:57:58 +0000</pubDate>
		<dc:creator>Piotr Dołęga</dc:creator>
				<category><![CDATA[Main]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[WHMCS]]></category>
		<category><![CDATA[WHMCS modules]]></category>

		<guid isPermaLink="false">https://www.blog.modulesgarden.com/?p=998</guid>
		<description><![CDATA[Neatly prepared reports can significantly facilitate the understanding of your business. If you had access to detailed information about the performance and efficiency of your company presented in an accessible way, wouldn&#8217;t you a make good use of it? Such &#8230; <a href="https://www.blog.modulesgarden.com/amazing-report-generator-for-whmcs">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">Neatly prepared reports can significantly facilitate the understanding of your business. If you had access to detailed information about the performance and efficiency of your company presented in an accessible way, wouldn&#8217;t you a make good use of it? Such reports would help you to make the right decisions as well as increase your sales and income. However, most of us are focused only on the basic income and sales reports. Is it good for you and your business?<strong><span id="more-998"></span></strong></p>
<p style="text-align: justify;">Definitely not. Understanding of all possible aspects of your business is a key factor for your success. Having broad knowledge about your products, services, sales, tickets, income, customers, staff members, invoices and many others will allow you to make wise decisions backed by reliable information and lead your company to the victory.</p>
<p style="text-align: justify;">Perhaps you are asking how to achieve that? The answer is quite simple &#8211; <strong>Report Generator For WHMCS</strong>. Among many other functionalities, the module will allow you to easily generate and manage  dynamic reports from any kind of WHMCS data. Module contains inbuilt drag &amp; drop WYSIWYG builder allowing to prepare reports in a quick and painless way. We will show how to prepare such an exemplary report.</p>
<p style="text-align: justify;">To start work with dynamic report builder you should at first choose a default section template to use. We would like to see the column chart which will represent the number of tickets submitted in the specified hours. To begin, we choose <em>&#8216;Tickets&#8217;</em> model as our base table and select the <em>&#8216;Column Chart&#8217;</em> as the section type.</p>
<p style="text-align: center;"><img class="aligncenter  wp-image-1043" src="https://www.blog.modulesgarden.com/wp-content/uploads/2014/05/ModulesGarden-Report-Generator-For-WHMCS-1.png" alt="ModulesGarden Report Generator For WHMCS 1" width="1024" height="793" /></p>
<p style="text-align: justify;">Afterwards you will see an information encouraging you to specify a <em>&#8216;Group By&#8217;</em> column in order to generate a section with a chart type. So let&#8217;s switch to the <em>&#8216;Group &amp; Limits&#8217;</em> tab. We would like to know in which hour the number of sent tickets is the greatest so we have to group the results by the<em> &#8216;date&#8217;</em> column  from the tickets table, which is representing the original ticket creation date. After setting up this field you will get the result looking similar to the one shown on the following screenshot.</p>
<p style="text-align: center;"><img class="aligncenter  wp-image-1026" src="https://www.blog.modulesgarden.com/wp-content/uploads/2014/05/ModulesGarden-Report-Generator-For-WHMCS-2.png" alt="ModulesGarden Report Generator For WHMCS 2" width="997" height="800" /></p>
<p style="text-align: justify;">Though as you can see, this is not exactly what we want to achieve. To make the group by work properly, just one more simple step is necessary. As you can see on the left side next to the <em>&#8216;Group By&#8217;</em> field, there is a grey box with <em>&#8216;No Expression&#8217;</em> text inside. We should change this so it will show only an hour of tickets creation.</p>
<p style="text-align: justify;">To achieve this, let&#8217;s click on the <em>&#8216;No Expression&#8217;</em> link. Next, a new select box with a few options available to choose should show up. These are predefined MySQL functions which are modifying our final result and are configurable from the module settings page. To continue, just choose the <em>&#8216;Hour&#8217;</em> expression from the list. After this operation, our chart should be re-rendered and now it should look almost perfectly.</p>
<p style="text-align: center;"><img class="aligncenter  wp-image-1047" src="https://www.blog.modulesgarden.com/wp-content/uploads/2014/05/ModulesGarden-Report-Generator-For-WHMCS-3.png" alt="ModulesGarden Report Generator For WHMCS 3" width="996" height="679" /></p>
<p style="text-align: justify;">The last thing to do is setting the correct ordering. There are many possibilities here but let&#8217;s say that we would like to present the results according to the hour in the ascending order. To do so, let&#8217;s just copy the information from the <em>&#8216;Group This Section&#8217;</em> into the <em>&#8216;Order This Section By&#8217;</em> (including the expression) and choose the <em>&#8216;Ascending&#8217;</em> from the <em>&#8216;Order Direction&#8217;</em> select box. As you can see on the screen below, our report is now looking just fine.</p>
<p style="text-align: center;"><img class="aligncenter  wp-image-1048" src="https://www.blog.modulesgarden.com/wp-content/uploads/2014/05/ModulesGarden-Report-Generator-For-WHMCS-4.png" alt="ModulesGarden Report Generator For WHMCS 4" width="998" height="685" /></p>
<p style="text-align: justify;">Additionally you can check the <em>&#8216;I want to filter results by date&#8217;</em> field in the <em>&#8216;Conditions&#8217;</em> section of the builder and select a date field from the list. Afterwards you will be able to filter the results only by the specified time range, as in the builder, as also in the report view page.</p>
<p style="text-align: center;"><img class="aligncenter  wp-image-1044" src="https://www.blog.modulesgarden.com/wp-content/uploads/2014/05/ModulesGarden-Report-Generator-For-WHMCS-5.png" alt="ModulesGarden Report Generator For WHMCS 5" width="1026" height="596" /></p>
<p style="text-align: justify;">It is just as simple as that. You can now export the data for this report to some popular formats like XML or CSV. You can also print it or export to PDF including any filters provided. That gives you a flexibility to present data in any format you need. You are also able to change report name, descriptions and tables name in &#8216;Advanced Builder Settings&#8217;.</p>
<p style="text-align: justify;">As you can see, creating and managing reports with Report Generator For WHMCS is very easy and convenient. Presented example is just a pinch of the module&#8217;s possibilities which are nearly endless and limited only by your imagination and needs.</p>
<p style="text-align: justify;"><strong>Next step belongs to you. What kind of report will you create?</strong></p>
<p style="text-align: justify;">Article has been created in cooperation with <strong>Dominik Gacek</strong> &#8211; ModulesGarden Lead Product Developer.</p>
]]></content:encoded>
			<wfw:commentRss>https://www.blog.modulesgarden.com/amazing-report-generator-for-whmcs/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Become ModulesGarden Affiliate And Earn Attractive Commission!</title>
		<link>https://www.blog.modulesgarden.com/become-modulesgarden-affiliate-and-earn-attractive-commission</link>
		<comments>https://www.blog.modulesgarden.com/become-modulesgarden-affiliate-and-earn-attractive-commission#comments</comments>
		<pubDate>Tue, 29 Apr 2014 07:23:06 +0000</pubDate>
		<dc:creator>Piotr Dołęga</dc:creator>
				<category><![CDATA[Main]]></category>
		<category><![CDATA[affiliate]]></category>
		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">https://www.blog.modulesgarden.com/?p=954</guid>
		<description><![CDATA[Since some time we receive a number of requests regarding reselling our products or Affiliate program. In order to meet with your expectations we decided to take the first step in that direction and introduce an Affiliate program to our &#8230; <a href="https://www.blog.modulesgarden.com/become-modulesgarden-affiliate-and-earn-attractive-commission">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">Since some time we receive a number of requests regarding reselling our products or Affiliate program. In order to meet with your expectations we decided to take the first step in that direction and introduce an Affiliate program to our offer. See, how you can benefit from it!<strong><span id="more-954"></span></strong></p>
<p style="text-align: justify;">ModulesGarden Affiliate program is a really nice way to earn good money with a minimum of effort.</p>
<p style="text-align: justify;">Its assumptions are very simple:</p>
<ol style="text-align: justify;">
<li>Firstly you need to apply to our Affiliate program.</li>
<li>Then we are reviewing and accepting your application. Afterwards we are activating your affiliate account and you can start making money immediately.</li>
<li>You are placing one or more buttons leading to our website on your own website. Ready button codes can be found at your affiliate page in our client area.</li>
<li>For each product that will be purchased by the customer redirected from your website you will receive a commission &#8211; a certain percentage of sold module&#8217;s price. The greater your sales are, the greater commissions we will offer you. Simple and effective!</li>
</ol>
<p style="text-align: justify;">Are you interested in becoming our affiliate and increasing your profits?</p>
<p style="text-align: center;"><strong><a title="Apply For ModulesGarden Affiliate Program" href="https://www.modulesgarden.com/company/affiliates"><span style="text-decoration: underline; background: #ffffcc; font-size: 20px;">Apply Today!</span></a></strong></p>
]]></content:encoded>
			<wfw:commentRss>https://www.blog.modulesgarden.com/become-modulesgarden-affiliate-and-earn-attractive-commission/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Do You Need A Documentation Or Knowledgebase?</title>
		<link>https://www.blog.modulesgarden.com/do-you-need-a-documentation-or-knowledgebase</link>
		<comments>https://www.blog.modulesgarden.com/do-you-need-a-documentation-or-knowledgebase#comments</comments>
		<pubDate>Mon, 19 Aug 2013 14:01:22 +0000</pubDate>
		<dc:creator>Piotr Dołęga</dc:creator>
				<category><![CDATA[Main]]></category>
		<category><![CDATA[documentation]]></category>
		<category><![CDATA[FAQ]]></category>
		<category><![CDATA[knowledgebase]]></category>
		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">https://www.blog.modulesgarden.com/?p=460</guid>
		<description><![CDATA[At present many of IT related companies offer their customers more or less extensive documentations, knowledge bases or FAQs. However, not all companies do that. Why do you think? Is it really worth to spend your time and money to &#8230; <a href="https://www.blog.modulesgarden.com/do-you-need-a-documentation-or-knowledgebase">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">At present many of IT related companies offer their customers more or less extensive documentations, knowledge bases or FAQs. However, not all companies do that. Why do you think? Is it really worth to spend your time and money to prepare tutorials for your clients and visitors?<strong><span id="more-460"></span></strong></p>
<p style="text-align: justify;">In my opinion it is. I have several reasons for this:</p>
<p style="text-align: justify;"><strong>1.</strong> Through reading your documentations, both visitors and your customers can learn more about your products and services. Many of them are looking for much more detailed information that those which can be found on your website. By creating documentation, you allow people to obtain this information, which may also have a positive impact on your sales.</p>
<p style="text-align: justify;"><strong>2.</strong> It is a fantastic way to provide support for your customers. Each time your client needs help, he have to create a ticket, join a chat or call you. This is often associated with a longer or shorter waiting time, sometimes up to several hours. Customers usually do not want to wait that long. They want to solve the problem immediately. Good knowledgebase or FAQ may contain solutions to many of such problems. More importantly, off the shelf.</p>
<p style="text-align: justify;"><strong>3.</strong> In a documentation you can place important and valuable information, which are problematic for various reasons, to provide by conventional support. Clarifying some of the issues may take your support team too much time or it may turn to be too difficult for customer. In many cases a practical documentation with screenshots and videos will be more understandable solution.</p>
<p style="text-align: justify;"><strong>4.</strong> It is truth that creation, updating and maintenance of documentation, knowledgebase, FAQ or tutorial can be expensive and time consuming. However, this investment pays off through reduction the number of tickets, reduction the number of calls and/or reduction the amount of time required to provide support. Not to mention the increase in customer satisfaction!</p>
<p style="text-align: justify;">In ModulesGarden, after creating a Wiki with documentation concerning our products, number of tickets decreased by <strong>45%</strong>!</p>
<p style="text-align: justify;">Conclusions belong to you.</p>
]]></content:encoded>
			<wfw:commentRss>https://www.blog.modulesgarden.com/do-you-need-a-documentation-or-knowledgebase/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How To Cooperate With Software Developer Of Your Project</title>
		<link>https://www.blog.modulesgarden.com/how-to-cooperate-with-software-developer-of-your-project</link>
		<comments>https://www.blog.modulesgarden.com/how-to-cooperate-with-software-developer-of-your-project#comments</comments>
		<pubDate>Fri, 08 Mar 2013 10:55:43 +0000</pubDate>
		<dc:creator>Piotr Dołęga</dc:creator>
				<category><![CDATA[Main]]></category>
		<category><![CDATA[custom software]]></category>
		<category><![CDATA[software]]></category>
		<category><![CDATA[software developer]]></category>
		<category><![CDATA[software project]]></category>
		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">https://www.blog.modulesgarden.com/?p=173</guid>
		<description><![CDATA[From personal experience, you know perfectly that your cooperation between the software developer or software development company not always meet your expectations. I will show you what to do, to pay less for the project, to receive it faster and &#8230; <a href="https://www.blog.modulesgarden.com/how-to-cooperate-with-software-developer-of-your-project">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<div style="text-align: justify;">
<p>From personal experience, you know perfectly that your cooperation between the software developer or software development company not always meet your expectations. I will show you what to do, to pay less for the project, to receive it faster and to be 100% satisfied with the results.<strong><span id="more-173"></span></strong></p>
<p>I will present you some best practices that are worth using to make life easier for both you and the developers.</p>
<p><strong>1. Prepare Detailed Development Request.</strong></p>
<p>This part is the most important. The more information you provide to developer, the better he will understand your intentions. This is a key factor in the creation of custom software as most of the problems are caused by misunderstandings. Take an appropriate amount of time to prepare all the details regarding your project. In this way you will:</p>
<ol>
<li><strong>Save your valuable time</strong> &#8211; you will not have to explain three times what you really had in mind and why the final product differs from what you expected.</li>
<li><strong>Save your money</strong> &#8211; you will simply avoid the situations in which you will have to pay for improving the finished project that does not meet your expectations.</li>
<li><strong>Avoid stress</strong> &#8211; you will have the confidence that the software will be made according to your needs and most importantly, on time.</li>
</ol>
<p>Here&#8217;s what you can prepare:</p>
<ul>
<li>detailed description of assumptions and actions of your project</li>
<li>API documentation</li>
<li>description of your environment: system, used software etc.</li>
<li>access to your system environment or equivalent system</li>
<li>screenshots or movies with descriptions</li>
<li>your deadlines</li>
<li>any other documentation that will help developers to understand your intentions</li>
</ul>
<p><strong>2. Get To Know The Payment Terms.</strong></p>
<p>When the objectives of the project are clear to both sides, you should familiarize yourself with payment terms to avoid any surprises. Any form of payment is good, as long as both sides are satisfied.<br />
<strong></strong></p>
<p><strong>3. Verify And Accept SLA (Service Level Agreement).</strong></p>
<p>After you determine the project details, price and form of payment, you can accept an SLA. But before that happens, stop for a moment and check again whether all details of the project have been discussed. It is very important not to make any significant changes to the project during its implementation. If you have any doubts, it is time to dispel them.<br />
<strong></strong></p>
<p><strong>4. Thoroughly Check Beta Version Of The Project.</strong></p>
<p>After the agreed time, you will receive the beta version of the product. It&#8217;s crucial to carefully check this version. You or developer of the software should test all the functionalities of the product in order to clear all doubts and find as many bugs as possible. Also check if the product has everything you need. Collect all the information together, prepare just one document with all listed bugs, problems, inaccuracies etc. and send it to developer. Remember to do everything at one go as this greatly facilitates the work of developer.</p>
<p>Most of all you should avoid sending multiple emails with requests of changes. Try to double check the received product to put all your comments and observations into one message to creator of software. Even if it takes you longer, in the final effect you will save your time and money. It is always better, faster and above all cheaper for you, to make all the changes to the product at one go.</p>
<p><strong>5. Test And Accept The Final Version Of The Project.</strong></p>
<p>When the product will be fixed according to your instructions, you will receive it&#8217;s next version. Check the entire product, test the changed functionalities and report the last minor fixes to developer. Soon you will receive the final version of your product and the project can be considered complete.</p>
<p>Stick to these few simple rules, and your cooperation with software developer will definitely achieve the expected results.</p>
</div>
]]></content:encoded>
			<wfw:commentRss>https://www.blog.modulesgarden.com/how-to-cooperate-with-software-developer-of-your-project/feed</wfw:commentRss>
		<slash:comments>15</slash:comments>
		</item>
	</channel>
</rss>
