<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
		<id>http://3.19.219.109/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Nicolas</id>
		<title>WHMCS Documentation - User contributions [en]</title>
		<link rel="self" type="application/atom+xml" href="http://3.19.219.109/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Nicolas"/>
		<link rel="alternate" type="text/html" href="http://3.19.219.109/Special:Contributions/Nicolas"/>
		<updated>2026-04-03T21:19:30Z</updated>
		<subtitle>User contributions</subtitle>
		<generator>MediaWiki 1.29.1</generator>

	<entry>
		<id>http://3.19.219.109/index.php?title=Client_Area_Template_Files&amp;diff=19778</id>
		<title>Client Area Template Files</title>
		<link rel="alternate" type="text/html" href="http://3.19.219.109/index.php?title=Client_Area_Template_Files&amp;diff=19778"/>
				<updated>2016-08-09T14:12:32Z</updated>
		
		<summary type="html">&lt;p&gt;Nicolas: /* Using GitHub */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Intro=&lt;br /&gt;
WHMCS always endeavours to make the system as customisable as possible so that users can always tailor it to their exact needs. With that in mind, all pages of the WHMCS client area use templates. This allows a user to add/remove and change the look and feel of everything.  In WHMCS, use of the powerful [[Template Syntax|Smarty template system]] allows you to:&lt;br /&gt;
&lt;br /&gt;
*Customise the layout and content of the client area fully.&lt;br /&gt;
*Make use of file includes for common elements shared between pages.&lt;br /&gt;
*Make use of many other powerful features Smarty has to offer.&lt;br /&gt;
&lt;br /&gt;
Most pages use three templates that combine to make up the output. These combine in this order:&lt;br /&gt;
&lt;br /&gt;
#'''Header Template (header.tpl)'''&lt;br /&gt;
#'''Main Content Template (homepage.tpl, clientareahome.tpl, etc...)'''&lt;br /&gt;
#'''Footer Template (footer.tpl)'''&lt;br /&gt;
&lt;br /&gt;
The header and footer are common to every page displayed as a wrapper around the content. Within the template folders you will see many other template files. These take the place of 'The Page Template' above. These templates define the output on each page. The templates are also named so that you can identify which relates to which page. For example, the template that defines the WHMCS homepage at (yoursite.com/whmcs/) is homepage.tpl. The main client area page is clientareahome.tpl and so on.&lt;br /&gt;
&lt;br /&gt;
'''Before starting''', please refer to the '''[[Template Syntax]]''' section of the docs. This provides information on how to work with the templates in WHMCS.&lt;br /&gt;
&lt;br /&gt;
==Creating a Custom Template==&lt;br /&gt;
 &lt;br /&gt;
When customising any WHMCS templates, the first step is to create another template folder. The default templates should never be edited directly. To do this, perform the following steps:&lt;br /&gt;
 &lt;br /&gt;
#Duplicate one of the standard folders in the templates folder (six, five) and rename it to a custom name.&lt;br /&gt;
#The directory name should be all one word and consist of just lowercase letters and numbers.&lt;br /&gt;
#Now make your customisations and changes as desired. See section below for more details on this.&lt;br /&gt;
#Once complete, upload the new templates folder to the templates directory of WHMCS.&lt;br /&gt;
#Preview the new template by specifying it using an URL &amp;quot;on the fly&amp;quot;. For example, www.yourdomain.com/whmcs/?systpl=xxxxx where xxxxx is the name of the new template. See [[Linking to WHMCS]] for more information.&lt;br /&gt;
#Once happy with it, set it live by going to '''Setup &amp;gt; General Settings'''. On the first tab, choose the new custom template name from the Template's dropdown menu.&lt;br /&gt;
 &lt;br /&gt;
The template selected here will be referred to throughout the documentation as the active template folder. Likewise, the order form template selected in Setup &amp;gt; General Settings &amp;gt; Ordering.&lt;br /&gt;
&lt;br /&gt;
==Customising to Match Your Website==&lt;br /&gt;
&lt;br /&gt;
What most people want to do with customisation is integrate WHMCS to match the rest of their website. This can be a daunting task but it is fairly straightforward. Following on from the above, begin by copying the HTML which controls the top of your website design. Paste this into the header.tpl file of your custom template folder.  Make sure to preserve the &amp;lt;head&amp;gt; section of code in the default WHMCS template. This contains the necessary CSS, Javascript Code &amp;amp; File Includes for WHMCS to function. Then copy and paste the footer code from your website design into footer.tpl.&lt;br /&gt;
&lt;br /&gt;
[[File:Videotutorial.png‎|center|link=https://www.youtube.com/watch?v=9VkbPoVTHYg&amp;amp;hd=1|Watch Video Tutorial]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Customising how payment gateways are displayed===&lt;br /&gt;
There may be occasion where it's desirable to customise the way payment gateways display. For example, you may wish to add formatting, display images such as card logos, or any other code of your own.&lt;br /&gt;
&lt;br /&gt;
Due to security considerations, it isn't possible to enter HTML into the display name or payment instruction fields. Instead, you can customise the relevant template to display your desired code.&lt;br /&gt;
&lt;br /&gt;
For example, to display credit card logos when the PayPal is the payment method on the printable invoice, use the following code. This will be in /templates/*your active template*/'''viewinvoice.tpl''':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
{if $paymentmodule eq 'paypal'}&lt;br /&gt;
&amp;lt;img src=&amp;quot;/images/creditcardlogos.png&amp;quot;&amp;gt;&lt;br /&gt;
{/if}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The image tag could be replaced with any code you wanted to display there. Replace 'paypal' with the name of your payment module. The exact value can be obtained from the tblpaymentgateways table.&lt;br /&gt;
&lt;br /&gt;
==Customising the Six theme==&lt;br /&gt;
 &lt;br /&gt;
Six is the name of the default client area template that ships with WHMCS 6.0 and later. With this template we have introduced a number of new resources that you can use to further customise your WHMCS installation. Two of these new features are briefly addressed below and detailed information on how to customise the Six theme can be found in the [[Customising the Six Theme]] documentation.&lt;br /&gt;
 &lt;br /&gt;
===Navigation and Sidebar Customisation===&lt;br /&gt;
 &lt;br /&gt;
In the Six theme the look and feel of the navigation bar and sidebar elements can customised via the header.tpl and sidebar.tpl (located in /includes/) template files.&lt;br /&gt;
 &lt;br /&gt;
To make changes to the layout of the menus (i.e. adding, removing, and modifying items) please refer to the [[Editing Client Area Menus|Editing Client Area Menus]] documentation.&lt;br /&gt;
&lt;br /&gt;
===Using GitHub===&lt;br /&gt;
 &lt;br /&gt;
The Six theme is made available via GitHub and provides version-by-version changes of the “Six” template as published in WHMCS. The WHMCS &amp;quot;Six&amp;quot; template repository can be found at [[https://github.com/WHMCS/templates-six]].&lt;/div&gt;</summary>
		<author><name>Nicolas</name></author>	</entry>

	<entry>
		<id>http://3.19.219.109/index.php?title=Interacting_With_The_Database&amp;diff=19322</id>
		<title>Interacting With The Database</title>
		<link rel="alternate" type="text/html" href="http://3.19.219.109/index.php?title=Interacting_With_The_Database&amp;diff=19322"/>
				<updated>2016-07-11T18:07:15Z</updated>
		
		<summary type="html">&lt;p&gt;Nicolas: /* External Links */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Database connectivity changes in WHMCS 6.0=&lt;br /&gt;
&lt;br /&gt;
The mysql PHP extension was deprecated when PHP 5.5 was released in June 2013&amp;lt;ref&amp;gt;http://php.net/ChangeLog-5.php#5.5.0&amp;lt;/ref&amp;gt; and is scheduled to be removed in PHP 7&amp;lt;ref&amp;gt;https://wiki.php.net/rfc/remove_deprecated_functionality_in_php7&amp;lt;/ref&amp;gt;. WHMCS 6.0 introduces a new database connection and library to ensure compatibility with modern PHP environments and best practices.&lt;br /&gt;
&lt;br /&gt;
==New functionality==&lt;br /&gt;
&lt;br /&gt;
WHMCS 6.0 incorporates the Laravel framework 4.1's database component (''WHMCS 7.0 incorporates 5.2''). This library includes a Database Abstraction Layer (DBAL) called &amp;quot;Capsule&amp;quot; and an Object Relational Mapping (ORM) library called &amp;quot;Eloquent&amp;quot;. The new DBAL is based on the PHP Data Objects (PDO MySQL) extension and uses WHMCS's existing &amp;lt;tt&amp;gt;configuration.php&amp;lt;/tt&amp;gt; file. No configuration file changes are required to use the new database connection.&lt;br /&gt;
&lt;br /&gt;
The Capsule DBAL component introduces two libraries to WHMCS, a query manager for running database queries and a schema manager for an abstracted API to table management. Capsule's underlying PDO connection is also available for advanced database usage. Capsule has three static methods to get to these components:&lt;br /&gt;
&lt;br /&gt;
* '''Capsule::table(string $tableName)''': Access the query manager for the given table.&lt;br /&gt;
* '''Capsule::schema()''': Access the schema manager for the WHMCS database. &lt;br /&gt;
* '''Capsule::connection()''': Access the connection manager to interact with the underlying database connection.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' WHMCS 6.0 makes two connections to the database. One connection is made through the legacy mysql extension to handle existing hooks, modules, and other customizations. The other connection is made by PDO to drive new DBAL and model based functionality in the program. &lt;br /&gt;
&lt;br /&gt;
==Deprecated functionality==&lt;br /&gt;
&lt;br /&gt;
The current [[SQL Helper Functions]] are present in WHMCS 6.0 and above, but are now deprecated and may be removed in a later version of the product:&lt;br /&gt;
* '''select_query()'''&lt;br /&gt;
* '''update_query()'''&lt;br /&gt;
* '''insert_query()'''&lt;br /&gt;
* '''full_query()'''&lt;br /&gt;
&lt;br /&gt;
The mysql extension driven database connection is now deprecated and may be discontinued in a later version of the product. WHMCS encourages all third party developers to use the Capsule DBAL and PDO connection for all new database interaction.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' WHMCS 7.0 incorporates the Laravel framework's 5.2 database component, which deprecates as well as removes many features present in 4.1  Please see the upgrade guide for more information:&lt;br /&gt;
* [https://laravel.com/docs/5.2/upgrade- Laravel 5.2 Upgrade Guide]&lt;br /&gt;
&lt;br /&gt;
=Using Capsule=&lt;br /&gt;
&lt;br /&gt;
Declare an alias to Laravel's database manager in your project file's &amp;lt;tt&amp;gt;use&amp;lt;/tt&amp;gt; block to access Capsule:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
use Illuminate\Database\Capsule\Manager as Capsule;&lt;br /&gt;
&lt;br /&gt;
// Run queries or modify tables as you like.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==The Query Manager==&lt;br /&gt;
&lt;br /&gt;
: ''Please see [https://laravel.com/docs/5.2/queries Laravel's query documentation] for more information.''&lt;br /&gt;
&lt;br /&gt;
The '''Capsule::table(string $tableName)''' method provides access to the query manager. Declare it with the name of the table you wish to query as it's first parameter to interact with that table. The query manager has a wide range of functionality to perform advanced select, join, insert, update, and delete statements. Capsule's select calls return rows as ''stdClass'' objects.&lt;br /&gt;
&lt;br /&gt;
Capsule escapes all input, so it is not necessary to add escaping slashes to variables passed to these methods.&lt;br /&gt;
&lt;br /&gt;
All of Capsule's methods throw an exception on failure. Please place Capusle calls in &amp;lt;tt&amp;gt;try&amp;lt;/tt&amp;gt;/&amp;lt;tt&amp;gt;catch&amp;lt;/tt&amp;gt; blocks for graceful error handling and to avoid potential fatal errors in your hook, module, or other customization.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
use Illuminate\Database\Capsule\Manager as Capsule;&lt;br /&gt;
&lt;br /&gt;
// Print all client first names using a simple select.&lt;br /&gt;
&lt;br /&gt;
/** @var stdClass $client */&lt;br /&gt;
foreach (Capsule::table('tblclients')-&amp;gt;get() as $client) {&lt;br /&gt;
    echo $client-&amp;gt;firstname . PHP_EOL;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Rename all clients named &amp;quot;John Deo&amp;quot; to &amp;quot;John Doe&amp;quot; using an update statement. &lt;br /&gt;
try {&lt;br /&gt;
    $updatedUserCount = Capsule::table('tblclients')&lt;br /&gt;
        -&amp;gt;where('firstname', 'John')&lt;br /&gt;
        -&amp;gt;where('lastname', 'Deo')&lt;br /&gt;
        -&amp;gt;update(&lt;br /&gt;
            [&lt;br /&gt;
                'lastname' =&amp;gt; 'Doe',&lt;br /&gt;
            ]&lt;br /&gt;
        );&lt;br /&gt;
&lt;br /&gt;
    echo &amp;quot;Fixed {$updatedUserCount} misspelled last names.&amp;quot;;&lt;br /&gt;
} catch (\Exception $e) {&lt;br /&gt;
    echo &amp;quot;I couldn't update client names. {$e-&amp;gt;getMessage()}&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==The Schema Manager==&lt;br /&gt;
&lt;br /&gt;
Use the '''Capsule::schema()''' method to access the schema manager to modify table schema if necessary. The schema manager has support for creating, dropping and truncating tables and for modifying columns, indexes, and keys. &lt;br /&gt;
&lt;br /&gt;
'''Note''': WHMCS does not recommend changing default table schema as that can affect product functionality.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
use Illuminate\Database\Capsule\Manager as Capsule;&lt;br /&gt;
&lt;br /&gt;
// Create a new table.&lt;br /&gt;
try {&lt;br /&gt;
    Capsule::schema()-&amp;gt;create(&lt;br /&gt;
        'my_table',&lt;br /&gt;
        function ($table) {&lt;br /&gt;
            /** @var \Illuminate\Database\Schema\Blueprint $table */&lt;br /&gt;
            $table-&amp;gt;increments('id');&lt;br /&gt;
            $table-&amp;gt;string('name');&lt;br /&gt;
            $table-&amp;gt;integer('serial_number');&lt;br /&gt;
            $table-&amp;gt;boolean('is_required');&lt;br /&gt;
            $table-&amp;gt;timestamps();&lt;br /&gt;
        }&lt;br /&gt;
    );&lt;br /&gt;
} catch (\Exception $e) {&lt;br /&gt;
    echo &amp;quot;Unable to create my_table: {$e-&amp;gt;getMessage()}&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==The Connection Manager==&lt;br /&gt;
&lt;br /&gt;
The '''Capsule::connection()''' method provides low-level access to the database connection itself. Use it to initiate transactions with automatic commit and rollback or to access the underlying PDO connection to perform manual database queries outside the DBAL. The connection manager also has methods to retrieve query and schema managers.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
use Illuminate\Database\Capsule\Manager as Capsule;&lt;br /&gt;
&lt;br /&gt;
// Perform potentially risky queries in a transaction for easy rollback.&lt;br /&gt;
try {&lt;br /&gt;
    Capsule::connection()-&amp;gt;transaction(&lt;br /&gt;
        function ($connectionManager)&lt;br /&gt;
        {&lt;br /&gt;
            /** @var \Illuminate\Database\Connection $connectionManager */&lt;br /&gt;
            $connectionManager-&amp;gt;table('my_table')-&amp;gt;insert(&lt;br /&gt;
                [&lt;br /&gt;
                    'name' =&amp;gt; $_POST['name'],&lt;br /&gt;
                    'serial_number' =&amp;gt; $_POST['serialNumber'],&lt;br /&gt;
                    'is_required' =&amp;gt; (int)(bool) $_POST['isRequired'],&lt;br /&gt;
                ]&lt;br /&gt;
            );&lt;br /&gt;
        }&lt;br /&gt;
    );&lt;br /&gt;
} catch (\Exception $e) {&lt;br /&gt;
    echo &amp;quot;Uh oh! Inserting didn't work, but I was able to rollback. {$e-&amp;gt;getMessage()}&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Getting to PDO===&lt;br /&gt;
&lt;br /&gt;
Use the connection manager's '''getPdo()''' method to retrieve the underlying PDO connection instance. Use the PDO connection to perform manual queries and advanced database usage.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
use Illuminate\Database\Capsule\Manager as Capsule;&lt;br /&gt;
&lt;br /&gt;
// Perform potentially risky queries in a transaction for easy rollback.    &lt;br /&gt;
$pdo = Capsule::connection()-&amp;gt;getPdo();&lt;br /&gt;
$pdo-&amp;gt;beginTransaction();&lt;br /&gt;
&lt;br /&gt;
try {&lt;br /&gt;
    $statement = $pdo-&amp;gt;prepare(&lt;br /&gt;
        'insert into my_table (name, serial_number, is_required) values (:name, :serialNumber, :isRequired)'&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    $statement-&amp;gt;execute(&lt;br /&gt;
        [&lt;br /&gt;
            ':name' =&amp;gt; $_POST['name'],&lt;br /&gt;
            ':serialNumber' =&amp;gt; $_POST['serialNumber'],&lt;br /&gt;
            ':isRequired' =&amp;gt; (bool) $_POST['isRequired'],&lt;br /&gt;
        ]&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    $pdo-&amp;gt;commit();&lt;br /&gt;
} catch (\Exception $e) {&lt;br /&gt;
    echo &amp;quot;Uh oh! {$e-&amp;gt;getMessage()}&amp;quot;;&lt;br /&gt;
    $pdo-&amp;gt;rollBack();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Troubleshooting=&lt;br /&gt;
&lt;br /&gt;
==Exceptions==&lt;br /&gt;
&lt;br /&gt;
All Capsule methods throw an exception on failure. Catch these exceptions and analyze their messages and stack traces to help determine the nature of the failure. WHMCS recommends placing all database interactivity in &amp;lt;tt&amp;gt;try&amp;lt;/tt&amp;gt;/&amp;lt;tt&amp;gt;catch&amp;lt;/tt&amp;gt; blocks for graceful error handling.&lt;br /&gt;
&lt;br /&gt;
==The Capsule Query Log==&lt;br /&gt;
&lt;br /&gt;
The connection manager's '''getQueryLog()''' method returns an array of all queries made during the life of the page request. Queries are stored in the log as an array containing the query run, the parameter bindings passed to the query, and the time it took for the query to execute, measured in milliseconds.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
use Illuminate\Database\Capsule\Manager as Capsule;&lt;br /&gt;
&lt;br /&gt;
// Loop through each Capsule query made during the page request.&lt;br /&gt;
foreach (Capsule::connection()-&amp;gt;getQueryLog() as $query) {&lt;br /&gt;
    echo &amp;quot;Query: {$query['query']}&amp;quot; . PHP_EOL;&lt;br /&gt;
    echo &amp;quot;Execution Time: {$query['time']}ms&amp;quot; . PHP_EOL;&lt;br /&gt;
    echo &amp;quot;Parameters: &amp;quot; . PHP_EOL;&lt;br /&gt;
&lt;br /&gt;
    foreach ($query['bindings'] as $key =&amp;gt; $value) {&lt;br /&gt;
        echo &amp;quot;{$key} =&amp;gt; {$value}&amp;quot; . PHP_EOL;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==The WHMCS Activity Log==&lt;br /&gt;
&lt;br /&gt;
All uncaught PDO-based query failures, including those made by Capsule and manual PDO queries, are written to to the WHMCS activity log. View the system activity log to view the details of these failed queries.&lt;br /&gt;
&lt;br /&gt;
=See Also=&lt;br /&gt;
* [[SQL Helper Functions]] (functional, but deprecated in WHMCS 6.0)&lt;br /&gt;
&lt;br /&gt;
=External Links=&lt;br /&gt;
* [http://laravel.com/docs/4.2/queries Query Builder - Laravel 4.2]&lt;br /&gt;
* [http://laravel.com/docs/5.2/queries Query Builder - Laravel 5.2]&lt;br /&gt;
* [http://laravel.com/docs/4.2/schema Schema Builder - Laravel 4.2]&lt;br /&gt;
* [https://laravel.com/docs/5.0/schema Schema Builder - Laravel 5.0]&lt;br /&gt;
* [http://php.net/manual/en/book.pdo.php PHP: PDO]&lt;br /&gt;
&lt;br /&gt;
=References=&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Nicolas</name></author>	</entry>

	<entry>
		<id>http://3.19.219.109/index.php?title=Interacting_With_The_Database&amp;diff=19318</id>
		<title>Interacting With The Database</title>
		<link rel="alternate" type="text/html" href="http://3.19.219.109/index.php?title=Interacting_With_The_Database&amp;diff=19318"/>
				<updated>2016-07-11T18:06:54Z</updated>
		
		<summary type="html">&lt;p&gt;Nicolas: /* External Links */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Database connectivity changes in WHMCS 6.0=&lt;br /&gt;
&lt;br /&gt;
The mysql PHP extension was deprecated when PHP 5.5 was released in June 2013&amp;lt;ref&amp;gt;http://php.net/ChangeLog-5.php#5.5.0&amp;lt;/ref&amp;gt; and is scheduled to be removed in PHP 7&amp;lt;ref&amp;gt;https://wiki.php.net/rfc/remove_deprecated_functionality_in_php7&amp;lt;/ref&amp;gt;. WHMCS 6.0 introduces a new database connection and library to ensure compatibility with modern PHP environments and best practices.&lt;br /&gt;
&lt;br /&gt;
==New functionality==&lt;br /&gt;
&lt;br /&gt;
WHMCS 6.0 incorporates the Laravel framework 4.1's database component (''WHMCS 7.0 incorporates 5.2''). This library includes a Database Abstraction Layer (DBAL) called &amp;quot;Capsule&amp;quot; and an Object Relational Mapping (ORM) library called &amp;quot;Eloquent&amp;quot;. The new DBAL is based on the PHP Data Objects (PDO MySQL) extension and uses WHMCS's existing &amp;lt;tt&amp;gt;configuration.php&amp;lt;/tt&amp;gt; file. No configuration file changes are required to use the new database connection.&lt;br /&gt;
&lt;br /&gt;
The Capsule DBAL component introduces two libraries to WHMCS, a query manager for running database queries and a schema manager for an abstracted API to table management. Capsule's underlying PDO connection is also available for advanced database usage. Capsule has three static methods to get to these components:&lt;br /&gt;
&lt;br /&gt;
* '''Capsule::table(string $tableName)''': Access the query manager for the given table.&lt;br /&gt;
* '''Capsule::schema()''': Access the schema manager for the WHMCS database. &lt;br /&gt;
* '''Capsule::connection()''': Access the connection manager to interact with the underlying database connection.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' WHMCS 6.0 makes two connections to the database. One connection is made through the legacy mysql extension to handle existing hooks, modules, and other customizations. The other connection is made by PDO to drive new DBAL and model based functionality in the program. &lt;br /&gt;
&lt;br /&gt;
==Deprecated functionality==&lt;br /&gt;
&lt;br /&gt;
The current [[SQL Helper Functions]] are present in WHMCS 6.0 and above, but are now deprecated and may be removed in a later version of the product:&lt;br /&gt;
* '''select_query()'''&lt;br /&gt;
* '''update_query()'''&lt;br /&gt;
* '''insert_query()'''&lt;br /&gt;
* '''full_query()'''&lt;br /&gt;
&lt;br /&gt;
The mysql extension driven database connection is now deprecated and may be discontinued in a later version of the product. WHMCS encourages all third party developers to use the Capsule DBAL and PDO connection for all new database interaction.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' WHMCS 7.0 incorporates the Laravel framework's 5.2 database component, which deprecates as well as removes many features present in 4.1  Please see the upgrade guide for more information:&lt;br /&gt;
* [https://laravel.com/docs/5.2/upgrade- Laravel 5.2 Upgrade Guide]&lt;br /&gt;
&lt;br /&gt;
=Using Capsule=&lt;br /&gt;
&lt;br /&gt;
Declare an alias to Laravel's database manager in your project file's &amp;lt;tt&amp;gt;use&amp;lt;/tt&amp;gt; block to access Capsule:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
use Illuminate\Database\Capsule\Manager as Capsule;&lt;br /&gt;
&lt;br /&gt;
// Run queries or modify tables as you like.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==The Query Manager==&lt;br /&gt;
&lt;br /&gt;
: ''Please see [https://laravel.com/docs/5.2/queries Laravel's query documentation] for more information.''&lt;br /&gt;
&lt;br /&gt;
The '''Capsule::table(string $tableName)''' method provides access to the query manager. Declare it with the name of the table you wish to query as it's first parameter to interact with that table. The query manager has a wide range of functionality to perform advanced select, join, insert, update, and delete statements. Capsule's select calls return rows as ''stdClass'' objects.&lt;br /&gt;
&lt;br /&gt;
Capsule escapes all input, so it is not necessary to add escaping slashes to variables passed to these methods.&lt;br /&gt;
&lt;br /&gt;
All of Capsule's methods throw an exception on failure. Please place Capusle calls in &amp;lt;tt&amp;gt;try&amp;lt;/tt&amp;gt;/&amp;lt;tt&amp;gt;catch&amp;lt;/tt&amp;gt; blocks for graceful error handling and to avoid potential fatal errors in your hook, module, or other customization.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
use Illuminate\Database\Capsule\Manager as Capsule;&lt;br /&gt;
&lt;br /&gt;
// Print all client first names using a simple select.&lt;br /&gt;
&lt;br /&gt;
/** @var stdClass $client */&lt;br /&gt;
foreach (Capsule::table('tblclients')-&amp;gt;get() as $client) {&lt;br /&gt;
    echo $client-&amp;gt;firstname . PHP_EOL;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Rename all clients named &amp;quot;John Deo&amp;quot; to &amp;quot;John Doe&amp;quot; using an update statement. &lt;br /&gt;
try {&lt;br /&gt;
    $updatedUserCount = Capsule::table('tblclients')&lt;br /&gt;
        -&amp;gt;where('firstname', 'John')&lt;br /&gt;
        -&amp;gt;where('lastname', 'Deo')&lt;br /&gt;
        -&amp;gt;update(&lt;br /&gt;
            [&lt;br /&gt;
                'lastname' =&amp;gt; 'Doe',&lt;br /&gt;
            ]&lt;br /&gt;
        );&lt;br /&gt;
&lt;br /&gt;
    echo &amp;quot;Fixed {$updatedUserCount} misspelled last names.&amp;quot;;&lt;br /&gt;
} catch (\Exception $e) {&lt;br /&gt;
    echo &amp;quot;I couldn't update client names. {$e-&amp;gt;getMessage()}&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==The Schema Manager==&lt;br /&gt;
&lt;br /&gt;
Use the '''Capsule::schema()''' method to access the schema manager to modify table schema if necessary. The schema manager has support for creating, dropping and truncating tables and for modifying columns, indexes, and keys. &lt;br /&gt;
&lt;br /&gt;
'''Note''': WHMCS does not recommend changing default table schema as that can affect product functionality.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
use Illuminate\Database\Capsule\Manager as Capsule;&lt;br /&gt;
&lt;br /&gt;
// Create a new table.&lt;br /&gt;
try {&lt;br /&gt;
    Capsule::schema()-&amp;gt;create(&lt;br /&gt;
        'my_table',&lt;br /&gt;
        function ($table) {&lt;br /&gt;
            /** @var \Illuminate\Database\Schema\Blueprint $table */&lt;br /&gt;
            $table-&amp;gt;increments('id');&lt;br /&gt;
            $table-&amp;gt;string('name');&lt;br /&gt;
            $table-&amp;gt;integer('serial_number');&lt;br /&gt;
            $table-&amp;gt;boolean('is_required');&lt;br /&gt;
            $table-&amp;gt;timestamps();&lt;br /&gt;
        }&lt;br /&gt;
    );&lt;br /&gt;
} catch (\Exception $e) {&lt;br /&gt;
    echo &amp;quot;Unable to create my_table: {$e-&amp;gt;getMessage()}&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==The Connection Manager==&lt;br /&gt;
&lt;br /&gt;
The '''Capsule::connection()''' method provides low-level access to the database connection itself. Use it to initiate transactions with automatic commit and rollback or to access the underlying PDO connection to perform manual database queries outside the DBAL. The connection manager also has methods to retrieve query and schema managers.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
use Illuminate\Database\Capsule\Manager as Capsule;&lt;br /&gt;
&lt;br /&gt;
// Perform potentially risky queries in a transaction for easy rollback.&lt;br /&gt;
try {&lt;br /&gt;
    Capsule::connection()-&amp;gt;transaction(&lt;br /&gt;
        function ($connectionManager)&lt;br /&gt;
        {&lt;br /&gt;
            /** @var \Illuminate\Database\Connection $connectionManager */&lt;br /&gt;
            $connectionManager-&amp;gt;table('my_table')-&amp;gt;insert(&lt;br /&gt;
                [&lt;br /&gt;
                    'name' =&amp;gt; $_POST['name'],&lt;br /&gt;
                    'serial_number' =&amp;gt; $_POST['serialNumber'],&lt;br /&gt;
                    'is_required' =&amp;gt; (int)(bool) $_POST['isRequired'],&lt;br /&gt;
                ]&lt;br /&gt;
            );&lt;br /&gt;
        }&lt;br /&gt;
    );&lt;br /&gt;
} catch (\Exception $e) {&lt;br /&gt;
    echo &amp;quot;Uh oh! Inserting didn't work, but I was able to rollback. {$e-&amp;gt;getMessage()}&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Getting to PDO===&lt;br /&gt;
&lt;br /&gt;
Use the connection manager's '''getPdo()''' method to retrieve the underlying PDO connection instance. Use the PDO connection to perform manual queries and advanced database usage.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
use Illuminate\Database\Capsule\Manager as Capsule;&lt;br /&gt;
&lt;br /&gt;
// Perform potentially risky queries in a transaction for easy rollback.    &lt;br /&gt;
$pdo = Capsule::connection()-&amp;gt;getPdo();&lt;br /&gt;
$pdo-&amp;gt;beginTransaction();&lt;br /&gt;
&lt;br /&gt;
try {&lt;br /&gt;
    $statement = $pdo-&amp;gt;prepare(&lt;br /&gt;
        'insert into my_table (name, serial_number, is_required) values (:name, :serialNumber, :isRequired)'&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    $statement-&amp;gt;execute(&lt;br /&gt;
        [&lt;br /&gt;
            ':name' =&amp;gt; $_POST['name'],&lt;br /&gt;
            ':serialNumber' =&amp;gt; $_POST['serialNumber'],&lt;br /&gt;
            ':isRequired' =&amp;gt; (bool) $_POST['isRequired'],&lt;br /&gt;
        ]&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    $pdo-&amp;gt;commit();&lt;br /&gt;
} catch (\Exception $e) {&lt;br /&gt;
    echo &amp;quot;Uh oh! {$e-&amp;gt;getMessage()}&amp;quot;;&lt;br /&gt;
    $pdo-&amp;gt;rollBack();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Troubleshooting=&lt;br /&gt;
&lt;br /&gt;
==Exceptions==&lt;br /&gt;
&lt;br /&gt;
All Capsule methods throw an exception on failure. Catch these exceptions and analyze their messages and stack traces to help determine the nature of the failure. WHMCS recommends placing all database interactivity in &amp;lt;tt&amp;gt;try&amp;lt;/tt&amp;gt;/&amp;lt;tt&amp;gt;catch&amp;lt;/tt&amp;gt; blocks for graceful error handling.&lt;br /&gt;
&lt;br /&gt;
==The Capsule Query Log==&lt;br /&gt;
&lt;br /&gt;
The connection manager's '''getQueryLog()''' method returns an array of all queries made during the life of the page request. Queries are stored in the log as an array containing the query run, the parameter bindings passed to the query, and the time it took for the query to execute, measured in milliseconds.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
use Illuminate\Database\Capsule\Manager as Capsule;&lt;br /&gt;
&lt;br /&gt;
// Loop through each Capsule query made during the page request.&lt;br /&gt;
foreach (Capsule::connection()-&amp;gt;getQueryLog() as $query) {&lt;br /&gt;
    echo &amp;quot;Query: {$query['query']}&amp;quot; . PHP_EOL;&lt;br /&gt;
    echo &amp;quot;Execution Time: {$query['time']}ms&amp;quot; . PHP_EOL;&lt;br /&gt;
    echo &amp;quot;Parameters: &amp;quot; . PHP_EOL;&lt;br /&gt;
&lt;br /&gt;
    foreach ($query['bindings'] as $key =&amp;gt; $value) {&lt;br /&gt;
        echo &amp;quot;{$key} =&amp;gt; {$value}&amp;quot; . PHP_EOL;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==The WHMCS Activity Log==&lt;br /&gt;
&lt;br /&gt;
All uncaught PDO-based query failures, including those made by Capsule and manual PDO queries, are written to to the WHMCS activity log. View the system activity log to view the details of these failed queries.&lt;br /&gt;
&lt;br /&gt;
=See Also=&lt;br /&gt;
* [[SQL Helper Functions]] (functional, but deprecated in WHMCS 6.0)&lt;br /&gt;
&lt;br /&gt;
=External Links=&lt;br /&gt;
* [http://laravel.com/docs/4.2/queries Query Builder - Laravel 4.2]&lt;br /&gt;
* [http://laravel.com/docs/5.2/queries Query Builder - Laravel 5.2]&lt;br /&gt;
* [http://laravel.com/docs/4.2/schema Schema Builder - Laravel 4.2]&lt;br /&gt;
* [https://laravel.com/docs/5.0/schema Schema Builder Laravel 5.0]&lt;br /&gt;
* [http://php.net/manual/en/book.pdo.php PHP: PDO]&lt;br /&gt;
&lt;br /&gt;
=References=&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Nicolas</name></author>	</entry>

	<entry>
		<id>http://3.19.219.109/index.php?title=Interacting_With_The_Database&amp;diff=19314</id>
		<title>Interacting With The Database</title>
		<link rel="alternate" type="text/html" href="http://3.19.219.109/index.php?title=Interacting_With_The_Database&amp;diff=19314"/>
				<updated>2016-07-11T18:06:32Z</updated>
		
		<summary type="html">&lt;p&gt;Nicolas: /* External Links */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Database connectivity changes in WHMCS 6.0=&lt;br /&gt;
&lt;br /&gt;
The mysql PHP extension was deprecated when PHP 5.5 was released in June 2013&amp;lt;ref&amp;gt;http://php.net/ChangeLog-5.php#5.5.0&amp;lt;/ref&amp;gt; and is scheduled to be removed in PHP 7&amp;lt;ref&amp;gt;https://wiki.php.net/rfc/remove_deprecated_functionality_in_php7&amp;lt;/ref&amp;gt;. WHMCS 6.0 introduces a new database connection and library to ensure compatibility with modern PHP environments and best practices.&lt;br /&gt;
&lt;br /&gt;
==New functionality==&lt;br /&gt;
&lt;br /&gt;
WHMCS 6.0 incorporates the Laravel framework 4.1's database component (''WHMCS 7.0 incorporates 5.2''). This library includes a Database Abstraction Layer (DBAL) called &amp;quot;Capsule&amp;quot; and an Object Relational Mapping (ORM) library called &amp;quot;Eloquent&amp;quot;. The new DBAL is based on the PHP Data Objects (PDO MySQL) extension and uses WHMCS's existing &amp;lt;tt&amp;gt;configuration.php&amp;lt;/tt&amp;gt; file. No configuration file changes are required to use the new database connection.&lt;br /&gt;
&lt;br /&gt;
The Capsule DBAL component introduces two libraries to WHMCS, a query manager for running database queries and a schema manager for an abstracted API to table management. Capsule's underlying PDO connection is also available for advanced database usage. Capsule has three static methods to get to these components:&lt;br /&gt;
&lt;br /&gt;
* '''Capsule::table(string $tableName)''': Access the query manager for the given table.&lt;br /&gt;
* '''Capsule::schema()''': Access the schema manager for the WHMCS database. &lt;br /&gt;
* '''Capsule::connection()''': Access the connection manager to interact with the underlying database connection.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' WHMCS 6.0 makes two connections to the database. One connection is made through the legacy mysql extension to handle existing hooks, modules, and other customizations. The other connection is made by PDO to drive new DBAL and model based functionality in the program. &lt;br /&gt;
&lt;br /&gt;
==Deprecated functionality==&lt;br /&gt;
&lt;br /&gt;
The current [[SQL Helper Functions]] are present in WHMCS 6.0 and above, but are now deprecated and may be removed in a later version of the product:&lt;br /&gt;
* '''select_query()'''&lt;br /&gt;
* '''update_query()'''&lt;br /&gt;
* '''insert_query()'''&lt;br /&gt;
* '''full_query()'''&lt;br /&gt;
&lt;br /&gt;
The mysql extension driven database connection is now deprecated and may be discontinued in a later version of the product. WHMCS encourages all third party developers to use the Capsule DBAL and PDO connection for all new database interaction.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' WHMCS 7.0 incorporates the Laravel framework's 5.2 database component, which deprecates as well as removes many features present in 4.1  Please see the upgrade guide for more information:&lt;br /&gt;
* [https://laravel.com/docs/5.2/upgrade- Laravel 5.2 Upgrade Guide]&lt;br /&gt;
&lt;br /&gt;
=Using Capsule=&lt;br /&gt;
&lt;br /&gt;
Declare an alias to Laravel's database manager in your project file's &amp;lt;tt&amp;gt;use&amp;lt;/tt&amp;gt; block to access Capsule:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
use Illuminate\Database\Capsule\Manager as Capsule;&lt;br /&gt;
&lt;br /&gt;
// Run queries or modify tables as you like.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==The Query Manager==&lt;br /&gt;
&lt;br /&gt;
: ''Please see [https://laravel.com/docs/5.2/queries Laravel's query documentation] for more information.''&lt;br /&gt;
&lt;br /&gt;
The '''Capsule::table(string $tableName)''' method provides access to the query manager. Declare it with the name of the table you wish to query as it's first parameter to interact with that table. The query manager has a wide range of functionality to perform advanced select, join, insert, update, and delete statements. Capsule's select calls return rows as ''stdClass'' objects.&lt;br /&gt;
&lt;br /&gt;
Capsule escapes all input, so it is not necessary to add escaping slashes to variables passed to these methods.&lt;br /&gt;
&lt;br /&gt;
All of Capsule's methods throw an exception on failure. Please place Capusle calls in &amp;lt;tt&amp;gt;try&amp;lt;/tt&amp;gt;/&amp;lt;tt&amp;gt;catch&amp;lt;/tt&amp;gt; blocks for graceful error handling and to avoid potential fatal errors in your hook, module, or other customization.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
use Illuminate\Database\Capsule\Manager as Capsule;&lt;br /&gt;
&lt;br /&gt;
// Print all client first names using a simple select.&lt;br /&gt;
&lt;br /&gt;
/** @var stdClass $client */&lt;br /&gt;
foreach (Capsule::table('tblclients')-&amp;gt;get() as $client) {&lt;br /&gt;
    echo $client-&amp;gt;firstname . PHP_EOL;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Rename all clients named &amp;quot;John Deo&amp;quot; to &amp;quot;John Doe&amp;quot; using an update statement. &lt;br /&gt;
try {&lt;br /&gt;
    $updatedUserCount = Capsule::table('tblclients')&lt;br /&gt;
        -&amp;gt;where('firstname', 'John')&lt;br /&gt;
        -&amp;gt;where('lastname', 'Deo')&lt;br /&gt;
        -&amp;gt;update(&lt;br /&gt;
            [&lt;br /&gt;
                'lastname' =&amp;gt; 'Doe',&lt;br /&gt;
            ]&lt;br /&gt;
        );&lt;br /&gt;
&lt;br /&gt;
    echo &amp;quot;Fixed {$updatedUserCount} misspelled last names.&amp;quot;;&lt;br /&gt;
} catch (\Exception $e) {&lt;br /&gt;
    echo &amp;quot;I couldn't update client names. {$e-&amp;gt;getMessage()}&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==The Schema Manager==&lt;br /&gt;
&lt;br /&gt;
Use the '''Capsule::schema()''' method to access the schema manager to modify table schema if necessary. The schema manager has support for creating, dropping and truncating tables and for modifying columns, indexes, and keys. &lt;br /&gt;
&lt;br /&gt;
'''Note''': WHMCS does not recommend changing default table schema as that can affect product functionality.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
use Illuminate\Database\Capsule\Manager as Capsule;&lt;br /&gt;
&lt;br /&gt;
// Create a new table.&lt;br /&gt;
try {&lt;br /&gt;
    Capsule::schema()-&amp;gt;create(&lt;br /&gt;
        'my_table',&lt;br /&gt;
        function ($table) {&lt;br /&gt;
            /** @var \Illuminate\Database\Schema\Blueprint $table */&lt;br /&gt;
            $table-&amp;gt;increments('id');&lt;br /&gt;
            $table-&amp;gt;string('name');&lt;br /&gt;
            $table-&amp;gt;integer('serial_number');&lt;br /&gt;
            $table-&amp;gt;boolean('is_required');&lt;br /&gt;
            $table-&amp;gt;timestamps();&lt;br /&gt;
        }&lt;br /&gt;
    );&lt;br /&gt;
} catch (\Exception $e) {&lt;br /&gt;
    echo &amp;quot;Unable to create my_table: {$e-&amp;gt;getMessage()}&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==The Connection Manager==&lt;br /&gt;
&lt;br /&gt;
The '''Capsule::connection()''' method provides low-level access to the database connection itself. Use it to initiate transactions with automatic commit and rollback or to access the underlying PDO connection to perform manual database queries outside the DBAL. The connection manager also has methods to retrieve query and schema managers.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
use Illuminate\Database\Capsule\Manager as Capsule;&lt;br /&gt;
&lt;br /&gt;
// Perform potentially risky queries in a transaction for easy rollback.&lt;br /&gt;
try {&lt;br /&gt;
    Capsule::connection()-&amp;gt;transaction(&lt;br /&gt;
        function ($connectionManager)&lt;br /&gt;
        {&lt;br /&gt;
            /** @var \Illuminate\Database\Connection $connectionManager */&lt;br /&gt;
            $connectionManager-&amp;gt;table('my_table')-&amp;gt;insert(&lt;br /&gt;
                [&lt;br /&gt;
                    'name' =&amp;gt; $_POST['name'],&lt;br /&gt;
                    'serial_number' =&amp;gt; $_POST['serialNumber'],&lt;br /&gt;
                    'is_required' =&amp;gt; (int)(bool) $_POST['isRequired'],&lt;br /&gt;
                ]&lt;br /&gt;
            );&lt;br /&gt;
        }&lt;br /&gt;
    );&lt;br /&gt;
} catch (\Exception $e) {&lt;br /&gt;
    echo &amp;quot;Uh oh! Inserting didn't work, but I was able to rollback. {$e-&amp;gt;getMessage()}&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Getting to PDO===&lt;br /&gt;
&lt;br /&gt;
Use the connection manager's '''getPdo()''' method to retrieve the underlying PDO connection instance. Use the PDO connection to perform manual queries and advanced database usage.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
use Illuminate\Database\Capsule\Manager as Capsule;&lt;br /&gt;
&lt;br /&gt;
// Perform potentially risky queries in a transaction for easy rollback.    &lt;br /&gt;
$pdo = Capsule::connection()-&amp;gt;getPdo();&lt;br /&gt;
$pdo-&amp;gt;beginTransaction();&lt;br /&gt;
&lt;br /&gt;
try {&lt;br /&gt;
    $statement = $pdo-&amp;gt;prepare(&lt;br /&gt;
        'insert into my_table (name, serial_number, is_required) values (:name, :serialNumber, :isRequired)'&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    $statement-&amp;gt;execute(&lt;br /&gt;
        [&lt;br /&gt;
            ':name' =&amp;gt; $_POST['name'],&lt;br /&gt;
            ':serialNumber' =&amp;gt; $_POST['serialNumber'],&lt;br /&gt;
            ':isRequired' =&amp;gt; (bool) $_POST['isRequired'],&lt;br /&gt;
        ]&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    $pdo-&amp;gt;commit();&lt;br /&gt;
} catch (\Exception $e) {&lt;br /&gt;
    echo &amp;quot;Uh oh! {$e-&amp;gt;getMessage()}&amp;quot;;&lt;br /&gt;
    $pdo-&amp;gt;rollBack();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Troubleshooting=&lt;br /&gt;
&lt;br /&gt;
==Exceptions==&lt;br /&gt;
&lt;br /&gt;
All Capsule methods throw an exception on failure. Catch these exceptions and analyze their messages and stack traces to help determine the nature of the failure. WHMCS recommends placing all database interactivity in &amp;lt;tt&amp;gt;try&amp;lt;/tt&amp;gt;/&amp;lt;tt&amp;gt;catch&amp;lt;/tt&amp;gt; blocks for graceful error handling.&lt;br /&gt;
&lt;br /&gt;
==The Capsule Query Log==&lt;br /&gt;
&lt;br /&gt;
The connection manager's '''getQueryLog()''' method returns an array of all queries made during the life of the page request. Queries are stored in the log as an array containing the query run, the parameter bindings passed to the query, and the time it took for the query to execute, measured in milliseconds.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
use Illuminate\Database\Capsule\Manager as Capsule;&lt;br /&gt;
&lt;br /&gt;
// Loop through each Capsule query made during the page request.&lt;br /&gt;
foreach (Capsule::connection()-&amp;gt;getQueryLog() as $query) {&lt;br /&gt;
    echo &amp;quot;Query: {$query['query']}&amp;quot; . PHP_EOL;&lt;br /&gt;
    echo &amp;quot;Execution Time: {$query['time']}ms&amp;quot; . PHP_EOL;&lt;br /&gt;
    echo &amp;quot;Parameters: &amp;quot; . PHP_EOL;&lt;br /&gt;
&lt;br /&gt;
    foreach ($query['bindings'] as $key =&amp;gt; $value) {&lt;br /&gt;
        echo &amp;quot;{$key} =&amp;gt; {$value}&amp;quot; . PHP_EOL;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==The WHMCS Activity Log==&lt;br /&gt;
&lt;br /&gt;
All uncaught PDO-based query failures, including those made by Capsule and manual PDO queries, are written to to the WHMCS activity log. View the system activity log to view the details of these failed queries.&lt;br /&gt;
&lt;br /&gt;
=See Also=&lt;br /&gt;
* [[SQL Helper Functions]] (functional, but deprecated in WHMCS 6.0)&lt;br /&gt;
&lt;br /&gt;
=External Links=&lt;br /&gt;
* [http://laravel.com/docs/4.2/queries Query Builder - Laravel 4.2]&lt;br /&gt;
* [http://laravel.com/docs/5.2/queries Query Builder - Laravel 5.2]&lt;br /&gt;
* [http://laravel.com/docs/4.2/schema Schema Builder - Laravel 4.2]&lt;br /&gt;
* [https://laravel.com/docs/5.0/schema - Schema Builder 5.0]&lt;br /&gt;
* [http://php.net/manual/en/book.pdo.php PHP: PDO]&lt;br /&gt;
&lt;br /&gt;
=References=&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Nicolas</name></author>	</entry>

	<entry>
		<id>http://3.19.219.109/index.php?title=Interacting_With_The_Database&amp;diff=19310</id>
		<title>Interacting With The Database</title>
		<link rel="alternate" type="text/html" href="http://3.19.219.109/index.php?title=Interacting_With_The_Database&amp;diff=19310"/>
				<updated>2016-07-11T17:54:41Z</updated>
		
		<summary type="html">&lt;p&gt;Nicolas: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Database connectivity changes in WHMCS 6.0=&lt;br /&gt;
&lt;br /&gt;
The mysql PHP extension was deprecated when PHP 5.5 was released in June 2013&amp;lt;ref&amp;gt;http://php.net/ChangeLog-5.php#5.5.0&amp;lt;/ref&amp;gt; and is scheduled to be removed in PHP 7&amp;lt;ref&amp;gt;https://wiki.php.net/rfc/remove_deprecated_functionality_in_php7&amp;lt;/ref&amp;gt;. WHMCS 6.0 introduces a new database connection and library to ensure compatibility with modern PHP environments and best practices.&lt;br /&gt;
&lt;br /&gt;
==New functionality==&lt;br /&gt;
&lt;br /&gt;
WHMCS 6.0 incorporates the Laravel framework 4.1's database component (''WHMCS 7.0 incorporates 5.2''). This library includes a Database Abstraction Layer (DBAL) called &amp;quot;Capsule&amp;quot; and an Object Relational Mapping (ORM) library called &amp;quot;Eloquent&amp;quot;. The new DBAL is based on the PHP Data Objects (PDO MySQL) extension and uses WHMCS's existing &amp;lt;tt&amp;gt;configuration.php&amp;lt;/tt&amp;gt; file. No configuration file changes are required to use the new database connection.&lt;br /&gt;
&lt;br /&gt;
The Capsule DBAL component introduces two libraries to WHMCS, a query manager for running database queries and a schema manager for an abstracted API to table management. Capsule's underlying PDO connection is also available for advanced database usage. Capsule has three static methods to get to these components:&lt;br /&gt;
&lt;br /&gt;
* '''Capsule::table(string $tableName)''': Access the query manager for the given table.&lt;br /&gt;
* '''Capsule::schema()''': Access the schema manager for the WHMCS database. &lt;br /&gt;
* '''Capsule::connection()''': Access the connection manager to interact with the underlying database connection.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' WHMCS 6.0 makes two connections to the database. One connection is made through the legacy mysql extension to handle existing hooks, modules, and other customizations. The other connection is made by PDO to drive new DBAL and model based functionality in the program. &lt;br /&gt;
&lt;br /&gt;
==Deprecated functionality==&lt;br /&gt;
&lt;br /&gt;
The current [[SQL Helper Functions]] are present in WHMCS 6.0 and above, but are now deprecated and may be removed in a later version of the product:&lt;br /&gt;
* '''select_query()'''&lt;br /&gt;
* '''update_query()'''&lt;br /&gt;
* '''insert_query()'''&lt;br /&gt;
* '''full_query()'''&lt;br /&gt;
&lt;br /&gt;
The mysql extension driven database connection is now deprecated and may be discontinued in a later version of the product. WHMCS encourages all third party developers to use the Capsule DBAL and PDO connection for all new database interaction.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' WHMCS 7.0 incorporates the Laravel framework's 5.2 database component, which deprecates as well as removes many features present in 4.1  Please see the upgrade guide for more information:&lt;br /&gt;
* [https://laravel.com/docs/5.2/upgrade- Laravel 5.2 Upgrade Guide]&lt;br /&gt;
&lt;br /&gt;
=Using Capsule=&lt;br /&gt;
&lt;br /&gt;
Declare an alias to Laravel's database manager in your project file's &amp;lt;tt&amp;gt;use&amp;lt;/tt&amp;gt; block to access Capsule:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
use Illuminate\Database\Capsule\Manager as Capsule;&lt;br /&gt;
&lt;br /&gt;
// Run queries or modify tables as you like.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==The Query Manager==&lt;br /&gt;
&lt;br /&gt;
: ''Please see [https://laravel.com/docs/5.2/queries Laravel's query documentation] for more information.''&lt;br /&gt;
&lt;br /&gt;
The '''Capsule::table(string $tableName)''' method provides access to the query manager. Declare it with the name of the table you wish to query as it's first parameter to interact with that table. The query manager has a wide range of functionality to perform advanced select, join, insert, update, and delete statements. Capsule's select calls return rows as ''stdClass'' objects.&lt;br /&gt;
&lt;br /&gt;
Capsule escapes all input, so it is not necessary to add escaping slashes to variables passed to these methods.&lt;br /&gt;
&lt;br /&gt;
All of Capsule's methods throw an exception on failure. Please place Capusle calls in &amp;lt;tt&amp;gt;try&amp;lt;/tt&amp;gt;/&amp;lt;tt&amp;gt;catch&amp;lt;/tt&amp;gt; blocks for graceful error handling and to avoid potential fatal errors in your hook, module, or other customization.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
use Illuminate\Database\Capsule\Manager as Capsule;&lt;br /&gt;
&lt;br /&gt;
// Print all client first names using a simple select.&lt;br /&gt;
&lt;br /&gt;
/** @var stdClass $client */&lt;br /&gt;
foreach (Capsule::table('tblclients')-&amp;gt;get() as $client) {&lt;br /&gt;
    echo $client-&amp;gt;firstname . PHP_EOL;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Rename all clients named &amp;quot;John Deo&amp;quot; to &amp;quot;John Doe&amp;quot; using an update statement. &lt;br /&gt;
try {&lt;br /&gt;
    $updatedUserCount = Capsule::table('tblclients')&lt;br /&gt;
        -&amp;gt;where('firstname', 'John')&lt;br /&gt;
        -&amp;gt;where('lastname', 'Deo')&lt;br /&gt;
        -&amp;gt;update(&lt;br /&gt;
            [&lt;br /&gt;
                'lastname' =&amp;gt; 'Doe',&lt;br /&gt;
            ]&lt;br /&gt;
        );&lt;br /&gt;
&lt;br /&gt;
    echo &amp;quot;Fixed {$updatedUserCount} misspelled last names.&amp;quot;;&lt;br /&gt;
} catch (\Exception $e) {&lt;br /&gt;
    echo &amp;quot;I couldn't update client names. {$e-&amp;gt;getMessage()}&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==The Schema Manager==&lt;br /&gt;
&lt;br /&gt;
Use the '''Capsule::schema()''' method to access the schema manager to modify table schema if necessary. The schema manager has support for creating, dropping and truncating tables and for modifying columns, indexes, and keys. &lt;br /&gt;
&lt;br /&gt;
'''Note''': WHMCS does not recommend changing default table schema as that can affect product functionality.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
use Illuminate\Database\Capsule\Manager as Capsule;&lt;br /&gt;
&lt;br /&gt;
// Create a new table.&lt;br /&gt;
try {&lt;br /&gt;
    Capsule::schema()-&amp;gt;create(&lt;br /&gt;
        'my_table',&lt;br /&gt;
        function ($table) {&lt;br /&gt;
            /** @var \Illuminate\Database\Schema\Blueprint $table */&lt;br /&gt;
            $table-&amp;gt;increments('id');&lt;br /&gt;
            $table-&amp;gt;string('name');&lt;br /&gt;
            $table-&amp;gt;integer('serial_number');&lt;br /&gt;
            $table-&amp;gt;boolean('is_required');&lt;br /&gt;
            $table-&amp;gt;timestamps();&lt;br /&gt;
        }&lt;br /&gt;
    );&lt;br /&gt;
} catch (\Exception $e) {&lt;br /&gt;
    echo &amp;quot;Unable to create my_table: {$e-&amp;gt;getMessage()}&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==The Connection Manager==&lt;br /&gt;
&lt;br /&gt;
The '''Capsule::connection()''' method provides low-level access to the database connection itself. Use it to initiate transactions with automatic commit and rollback or to access the underlying PDO connection to perform manual database queries outside the DBAL. The connection manager also has methods to retrieve query and schema managers.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
use Illuminate\Database\Capsule\Manager as Capsule;&lt;br /&gt;
&lt;br /&gt;
// Perform potentially risky queries in a transaction for easy rollback.&lt;br /&gt;
try {&lt;br /&gt;
    Capsule::connection()-&amp;gt;transaction(&lt;br /&gt;
        function ($connectionManager)&lt;br /&gt;
        {&lt;br /&gt;
            /** @var \Illuminate\Database\Connection $connectionManager */&lt;br /&gt;
            $connectionManager-&amp;gt;table('my_table')-&amp;gt;insert(&lt;br /&gt;
                [&lt;br /&gt;
                    'name' =&amp;gt; $_POST['name'],&lt;br /&gt;
                    'serial_number' =&amp;gt; $_POST['serialNumber'],&lt;br /&gt;
                    'is_required' =&amp;gt; (int)(bool) $_POST['isRequired'],&lt;br /&gt;
                ]&lt;br /&gt;
            );&lt;br /&gt;
        }&lt;br /&gt;
    );&lt;br /&gt;
} catch (\Exception $e) {&lt;br /&gt;
    echo &amp;quot;Uh oh! Inserting didn't work, but I was able to rollback. {$e-&amp;gt;getMessage()}&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Getting to PDO===&lt;br /&gt;
&lt;br /&gt;
Use the connection manager's '''getPdo()''' method to retrieve the underlying PDO connection instance. Use the PDO connection to perform manual queries and advanced database usage.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
use Illuminate\Database\Capsule\Manager as Capsule;&lt;br /&gt;
&lt;br /&gt;
// Perform potentially risky queries in a transaction for easy rollback.    &lt;br /&gt;
$pdo = Capsule::connection()-&amp;gt;getPdo();&lt;br /&gt;
$pdo-&amp;gt;beginTransaction();&lt;br /&gt;
&lt;br /&gt;
try {&lt;br /&gt;
    $statement = $pdo-&amp;gt;prepare(&lt;br /&gt;
        'insert into my_table (name, serial_number, is_required) values (:name, :serialNumber, :isRequired)'&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    $statement-&amp;gt;execute(&lt;br /&gt;
        [&lt;br /&gt;
            ':name' =&amp;gt; $_POST['name'],&lt;br /&gt;
            ':serialNumber' =&amp;gt; $_POST['serialNumber'],&lt;br /&gt;
            ':isRequired' =&amp;gt; (bool) $_POST['isRequired'],&lt;br /&gt;
        ]&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    $pdo-&amp;gt;commit();&lt;br /&gt;
} catch (\Exception $e) {&lt;br /&gt;
    echo &amp;quot;Uh oh! {$e-&amp;gt;getMessage()}&amp;quot;;&lt;br /&gt;
    $pdo-&amp;gt;rollBack();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Troubleshooting=&lt;br /&gt;
&lt;br /&gt;
==Exceptions==&lt;br /&gt;
&lt;br /&gt;
All Capsule methods throw an exception on failure. Catch these exceptions and analyze their messages and stack traces to help determine the nature of the failure. WHMCS recommends placing all database interactivity in &amp;lt;tt&amp;gt;try&amp;lt;/tt&amp;gt;/&amp;lt;tt&amp;gt;catch&amp;lt;/tt&amp;gt; blocks for graceful error handling.&lt;br /&gt;
&lt;br /&gt;
==The Capsule Query Log==&lt;br /&gt;
&lt;br /&gt;
The connection manager's '''getQueryLog()''' method returns an array of all queries made during the life of the page request. Queries are stored in the log as an array containing the query run, the parameter bindings passed to the query, and the time it took for the query to execute, measured in milliseconds.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
use Illuminate\Database\Capsule\Manager as Capsule;&lt;br /&gt;
&lt;br /&gt;
// Loop through each Capsule query made during the page request.&lt;br /&gt;
foreach (Capsule::connection()-&amp;gt;getQueryLog() as $query) {&lt;br /&gt;
    echo &amp;quot;Query: {$query['query']}&amp;quot; . PHP_EOL;&lt;br /&gt;
    echo &amp;quot;Execution Time: {$query['time']}ms&amp;quot; . PHP_EOL;&lt;br /&gt;
    echo &amp;quot;Parameters: &amp;quot; . PHP_EOL;&lt;br /&gt;
&lt;br /&gt;
    foreach ($query['bindings'] as $key =&amp;gt; $value) {&lt;br /&gt;
        echo &amp;quot;{$key} =&amp;gt; {$value}&amp;quot; . PHP_EOL;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==The WHMCS Activity Log==&lt;br /&gt;
&lt;br /&gt;
All uncaught PDO-based query failures, including those made by Capsule and manual PDO queries, are written to to the WHMCS activity log. View the system activity log to view the details of these failed queries.&lt;br /&gt;
&lt;br /&gt;
=See Also=&lt;br /&gt;
* [[SQL Helper Functions]] (functional, but deprecated in WHMCS 6.0)&lt;br /&gt;
&lt;br /&gt;
=External Links=&lt;br /&gt;
* [http://laravel.com/docs/4.2/queries Query Builder - Laravel 4.2]&lt;br /&gt;
* [http://laravel.com/docs/5.2/queries Query Builder - Laravel 5.2]&lt;br /&gt;
* [http://laravel.com/docs/4.2/schema Schema Builder - Laravel 4.2]&lt;br /&gt;
* [https://laravel.com/docs/5.0/schema - Laravel 5.0]&lt;br /&gt;
* [http://php.net/manual/en/book.pdo.php PHP: PDO]&lt;br /&gt;
&lt;br /&gt;
=References=&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Nicolas</name></author>	</entry>

	<entry>
		<id>http://3.19.219.109/index.php?title=Interacting_With_The_Database&amp;diff=19306</id>
		<title>Interacting With The Database</title>
		<link rel="alternate" type="text/html" href="http://3.19.219.109/index.php?title=Interacting_With_The_Database&amp;diff=19306"/>
				<updated>2016-07-11T17:35:36Z</updated>
		
		<summary type="html">&lt;p&gt;Nicolas: /* External Links */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Database connectivity changes in WHMCS 6.0=&lt;br /&gt;
&lt;br /&gt;
The mysql PHP extension was deprecated when PHP 5.5 was released in June 2013&amp;lt;ref&amp;gt;http://php.net/ChangeLog-5.php#5.5.0&amp;lt;/ref&amp;gt; and is scheduled to be removed in PHP 7&amp;lt;ref&amp;gt;https://wiki.php.net/rfc/remove_deprecated_functionality_in_php7&amp;lt;/ref&amp;gt;. WHMCS 6.0 introduces a new database connection and library to ensure compatibility with modern PHP environments and best practices.&lt;br /&gt;
&lt;br /&gt;
==New functionality==&lt;br /&gt;
&lt;br /&gt;
WHMCS 6.0 incorporates the Laravel framework 4.1's database component (''WHMCS 7.0 incorporates 5.2''). This library includes a Database Abstraction Layer (DBAL) called &amp;quot;Capsule&amp;quot; and an Object Relational Mapping (ORM) library called &amp;quot;Eloquent&amp;quot;. The new DBAL is based on the PHP Data Objects (PDO MySQL) extension and uses WHMCS's existing &amp;lt;tt&amp;gt;configuration.php&amp;lt;/tt&amp;gt; file. No configuration file changes are required to use the new database connection.&lt;br /&gt;
&lt;br /&gt;
The Capsule DBAL component introduces two libraries to WHMCS, a query manager for running database queries and a schema manager for an abstracted API to table management. Capsule's underlying PDO connection is also available for advanced database usage. Capsule has three static methods to get to these components:&lt;br /&gt;
&lt;br /&gt;
* '''Capsule::table(string $tableName)''': Access the query manager for the given table.&lt;br /&gt;
* '''Capsule::schema()''': Access the schema manager for the WHMCS database. &lt;br /&gt;
* '''Capsule::connection()''': Access the connection manager to interact with the underlying database connection.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' WHMCS 6.0 makes two connections to the database. One connection is made through the legacy mysql extension to handle existing hooks, modules, and other customizations. The other connection is made by PDO to drive new DBAL and model based functionality in the program. &lt;br /&gt;
&lt;br /&gt;
==Deprecated functionality==&lt;br /&gt;
&lt;br /&gt;
The current [[SQL Helper Functions]] are present in WHMCS 6.0 and above, but are now deprecated and may be removed in a later version of the product:&lt;br /&gt;
* '''select_query()'''&lt;br /&gt;
* '''update_query()'''&lt;br /&gt;
* '''insert_query()'''&lt;br /&gt;
* '''full_query()'''&lt;br /&gt;
&lt;br /&gt;
The mysql extension driven database connection is now deprecated and may be discontinued in a later version of the product. WHMCS encourages all third party developers to use the Capsule DBAL and PDO connection for all new database interaction.&lt;br /&gt;
&lt;br /&gt;
=Using Capsule=&lt;br /&gt;
&lt;br /&gt;
Declare an alias to Laravel's database manager in your project file's &amp;lt;tt&amp;gt;use&amp;lt;/tt&amp;gt; block to access Capsule:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
use Illuminate\Database\Capsule\Manager as Capsule;&lt;br /&gt;
&lt;br /&gt;
// Run queries or modify tables as you like.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==The Query Manager==&lt;br /&gt;
&lt;br /&gt;
: ''Please see [https://laravel.com/docs/5.2/queries Laravel's query documentation] for more information.''&lt;br /&gt;
&lt;br /&gt;
The '''Capsule::table(string $tableName)''' method provides access to the query manager. Declare it with the name of the table you wish to query as it's first parameter to interact with that table. The query manager has a wide range of functionality to perform advanced select, join, insert, update, and delete statements. Capsule's select calls return rows as ''stdClass'' objects.&lt;br /&gt;
&lt;br /&gt;
Capsule escapes all input, so it is not necessary to add escaping slashes to variables passed to these methods.&lt;br /&gt;
&lt;br /&gt;
All of Capsule's methods throw an exception on failure. Please place Capusle calls in &amp;lt;tt&amp;gt;try&amp;lt;/tt&amp;gt;/&amp;lt;tt&amp;gt;catch&amp;lt;/tt&amp;gt; blocks for graceful error handling and to avoid potential fatal errors in your hook, module, or other customization.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
use Illuminate\Database\Capsule\Manager as Capsule;&lt;br /&gt;
&lt;br /&gt;
// Print all client first names using a simple select.&lt;br /&gt;
&lt;br /&gt;
/** @var stdClass $client */&lt;br /&gt;
foreach (Capsule::table('tblclients')-&amp;gt;get() as $client) {&lt;br /&gt;
    echo $client-&amp;gt;firstname . PHP_EOL;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Rename all clients named &amp;quot;John Deo&amp;quot; to &amp;quot;John Doe&amp;quot; using an update statement. &lt;br /&gt;
try {&lt;br /&gt;
    $updatedUserCount = Capsule::table('tblclients')&lt;br /&gt;
        -&amp;gt;where('firstname', 'John')&lt;br /&gt;
        -&amp;gt;where('lastname', 'Deo')&lt;br /&gt;
        -&amp;gt;update(&lt;br /&gt;
            [&lt;br /&gt;
                'lastname' =&amp;gt; 'Doe',&lt;br /&gt;
            ]&lt;br /&gt;
        );&lt;br /&gt;
&lt;br /&gt;
    echo &amp;quot;Fixed {$updatedUserCount} misspelled last names.&amp;quot;;&lt;br /&gt;
} catch (\Exception $e) {&lt;br /&gt;
    echo &amp;quot;I couldn't update client names. {$e-&amp;gt;getMessage()}&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==The Schema Manager==&lt;br /&gt;
&lt;br /&gt;
Use the '''Capsule::schema()''' method to access the schema manager to modify table schema if necessary. The schema manager has support for creating, dropping and truncating tables and for modifying columns, indexes, and keys. &lt;br /&gt;
&lt;br /&gt;
'''Note''': WHMCS does not recommend changing default table schema as that can affect product functionality.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
use Illuminate\Database\Capsule\Manager as Capsule;&lt;br /&gt;
&lt;br /&gt;
// Create a new table.&lt;br /&gt;
try {&lt;br /&gt;
    Capsule::schema()-&amp;gt;create(&lt;br /&gt;
        'my_table',&lt;br /&gt;
        function ($table) {&lt;br /&gt;
            /** @var \Illuminate\Database\Schema\Blueprint $table */&lt;br /&gt;
            $table-&amp;gt;increments('id');&lt;br /&gt;
            $table-&amp;gt;string('name');&lt;br /&gt;
            $table-&amp;gt;integer('serial_number');&lt;br /&gt;
            $table-&amp;gt;boolean('is_required');&lt;br /&gt;
            $table-&amp;gt;timestamps();&lt;br /&gt;
        }&lt;br /&gt;
    );&lt;br /&gt;
} catch (\Exception $e) {&lt;br /&gt;
    echo &amp;quot;Unable to create my_table: {$e-&amp;gt;getMessage()}&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==The Connection Manager==&lt;br /&gt;
&lt;br /&gt;
The '''Capsule::connection()''' method provides low-level access to the database connection itself. Use it to initiate transactions with automatic commit and rollback or to access the underlying PDO connection to perform manual database queries outside the DBAL. The connection manager also has methods to retrieve query and schema managers.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
use Illuminate\Database\Capsule\Manager as Capsule;&lt;br /&gt;
&lt;br /&gt;
// Perform potentially risky queries in a transaction for easy rollback.&lt;br /&gt;
try {&lt;br /&gt;
    Capsule::connection()-&amp;gt;transaction(&lt;br /&gt;
        function ($connectionManager)&lt;br /&gt;
        {&lt;br /&gt;
            /** @var \Illuminate\Database\Connection $connectionManager */&lt;br /&gt;
            $connectionManager-&amp;gt;table('my_table')-&amp;gt;insert(&lt;br /&gt;
                [&lt;br /&gt;
                    'name' =&amp;gt; $_POST['name'],&lt;br /&gt;
                    'serial_number' =&amp;gt; $_POST['serialNumber'],&lt;br /&gt;
                    'is_required' =&amp;gt; (int)(bool) $_POST['isRequired'],&lt;br /&gt;
                ]&lt;br /&gt;
            );&lt;br /&gt;
        }&lt;br /&gt;
    );&lt;br /&gt;
} catch (\Exception $e) {&lt;br /&gt;
    echo &amp;quot;Uh oh! Inserting didn't work, but I was able to rollback. {$e-&amp;gt;getMessage()}&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Getting to PDO===&lt;br /&gt;
&lt;br /&gt;
Use the connection manager's '''getPdo()''' method to retrieve the underlying PDO connection instance. Use the PDO connection to perform manual queries and advanced database usage.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
use Illuminate\Database\Capsule\Manager as Capsule;&lt;br /&gt;
&lt;br /&gt;
// Perform potentially risky queries in a transaction for easy rollback.    &lt;br /&gt;
$pdo = Capsule::connection()-&amp;gt;getPdo();&lt;br /&gt;
$pdo-&amp;gt;beginTransaction();&lt;br /&gt;
&lt;br /&gt;
try {&lt;br /&gt;
    $statement = $pdo-&amp;gt;prepare(&lt;br /&gt;
        'insert into my_table (name, serial_number, is_required) values (:name, :serialNumber, :isRequired)'&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    $statement-&amp;gt;execute(&lt;br /&gt;
        [&lt;br /&gt;
            ':name' =&amp;gt; $_POST['name'],&lt;br /&gt;
            ':serialNumber' =&amp;gt; $_POST['serialNumber'],&lt;br /&gt;
            ':isRequired' =&amp;gt; (bool) $_POST['isRequired'],&lt;br /&gt;
        ]&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    $pdo-&amp;gt;commit();&lt;br /&gt;
} catch (\Exception $e) {&lt;br /&gt;
    echo &amp;quot;Uh oh! {$e-&amp;gt;getMessage()}&amp;quot;;&lt;br /&gt;
    $pdo-&amp;gt;rollBack();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Troubleshooting=&lt;br /&gt;
&lt;br /&gt;
==Exceptions==&lt;br /&gt;
&lt;br /&gt;
All Capsule methods throw an exception on failure. Catch these exceptions and analyze their messages and stack traces to help determine the nature of the failure. WHMCS recommends placing all database interactivity in &amp;lt;tt&amp;gt;try&amp;lt;/tt&amp;gt;/&amp;lt;tt&amp;gt;catch&amp;lt;/tt&amp;gt; blocks for graceful error handling.&lt;br /&gt;
&lt;br /&gt;
==The Capsule Query Log==&lt;br /&gt;
&lt;br /&gt;
The connection manager's '''getQueryLog()''' method returns an array of all queries made during the life of the page request. Queries are stored in the log as an array containing the query run, the parameter bindings passed to the query, and the time it took for the query to execute, measured in milliseconds.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
use Illuminate\Database\Capsule\Manager as Capsule;&lt;br /&gt;
&lt;br /&gt;
// Loop through each Capsule query made during the page request.&lt;br /&gt;
foreach (Capsule::connection()-&amp;gt;getQueryLog() as $query) {&lt;br /&gt;
    echo &amp;quot;Query: {$query['query']}&amp;quot; . PHP_EOL;&lt;br /&gt;
    echo &amp;quot;Execution Time: {$query['time']}ms&amp;quot; . PHP_EOL;&lt;br /&gt;
    echo &amp;quot;Parameters: &amp;quot; . PHP_EOL;&lt;br /&gt;
&lt;br /&gt;
    foreach ($query['bindings'] as $key =&amp;gt; $value) {&lt;br /&gt;
        echo &amp;quot;{$key} =&amp;gt; {$value}&amp;quot; . PHP_EOL;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==The WHMCS Activity Log==&lt;br /&gt;
&lt;br /&gt;
All uncaught PDO-based query failures, including those made by Capsule and manual PDO queries, are written to to the WHMCS activity log. View the system activity log to view the details of these failed queries.&lt;br /&gt;
&lt;br /&gt;
=See Also=&lt;br /&gt;
* [[SQL Helper Functions]] (functional, but deprecated in WHMCS 6.0)&lt;br /&gt;
&lt;br /&gt;
=External Links=&lt;br /&gt;
* [http://laravel.com/docs/4.2/queries Query Builder - Laravel 4.2]&lt;br /&gt;
* [http://laravel.com/docs/5.2/queries Query Builder - Laravel 5.2]&lt;br /&gt;
* [http://laravel.com/docs/4.2/schema Schema Builder - Laravel 4.2]&lt;br /&gt;
* [https://laravel.com/docs/5.0/schema - Laravel 5.0]&lt;br /&gt;
* [http://php.net/manual/en/book.pdo.php PHP: PDO]&lt;br /&gt;
&lt;br /&gt;
=References=&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Nicolas</name></author>	</entry>

	<entry>
		<id>http://3.19.219.109/index.php?title=Interacting_With_The_Database&amp;diff=19302</id>
		<title>Interacting With The Database</title>
		<link rel="alternate" type="text/html" href="http://3.19.219.109/index.php?title=Interacting_With_The_Database&amp;diff=19302"/>
				<updated>2016-07-11T17:35:21Z</updated>
		
		<summary type="html">&lt;p&gt;Nicolas: /* External Links */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Database connectivity changes in WHMCS 6.0=&lt;br /&gt;
&lt;br /&gt;
The mysql PHP extension was deprecated when PHP 5.5 was released in June 2013&amp;lt;ref&amp;gt;http://php.net/ChangeLog-5.php#5.5.0&amp;lt;/ref&amp;gt; and is scheduled to be removed in PHP 7&amp;lt;ref&amp;gt;https://wiki.php.net/rfc/remove_deprecated_functionality_in_php7&amp;lt;/ref&amp;gt;. WHMCS 6.0 introduces a new database connection and library to ensure compatibility with modern PHP environments and best practices.&lt;br /&gt;
&lt;br /&gt;
==New functionality==&lt;br /&gt;
&lt;br /&gt;
WHMCS 6.0 incorporates the Laravel framework 4.1's database component (''WHMCS 7.0 incorporates 5.2''). This library includes a Database Abstraction Layer (DBAL) called &amp;quot;Capsule&amp;quot; and an Object Relational Mapping (ORM) library called &amp;quot;Eloquent&amp;quot;. The new DBAL is based on the PHP Data Objects (PDO MySQL) extension and uses WHMCS's existing &amp;lt;tt&amp;gt;configuration.php&amp;lt;/tt&amp;gt; file. No configuration file changes are required to use the new database connection.&lt;br /&gt;
&lt;br /&gt;
The Capsule DBAL component introduces two libraries to WHMCS, a query manager for running database queries and a schema manager for an abstracted API to table management. Capsule's underlying PDO connection is also available for advanced database usage. Capsule has three static methods to get to these components:&lt;br /&gt;
&lt;br /&gt;
* '''Capsule::table(string $tableName)''': Access the query manager for the given table.&lt;br /&gt;
* '''Capsule::schema()''': Access the schema manager for the WHMCS database. &lt;br /&gt;
* '''Capsule::connection()''': Access the connection manager to interact with the underlying database connection.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' WHMCS 6.0 makes two connections to the database. One connection is made through the legacy mysql extension to handle existing hooks, modules, and other customizations. The other connection is made by PDO to drive new DBAL and model based functionality in the program. &lt;br /&gt;
&lt;br /&gt;
==Deprecated functionality==&lt;br /&gt;
&lt;br /&gt;
The current [[SQL Helper Functions]] are present in WHMCS 6.0 and above, but are now deprecated and may be removed in a later version of the product:&lt;br /&gt;
* '''select_query()'''&lt;br /&gt;
* '''update_query()'''&lt;br /&gt;
* '''insert_query()'''&lt;br /&gt;
* '''full_query()'''&lt;br /&gt;
&lt;br /&gt;
The mysql extension driven database connection is now deprecated and may be discontinued in a later version of the product. WHMCS encourages all third party developers to use the Capsule DBAL and PDO connection for all new database interaction.&lt;br /&gt;
&lt;br /&gt;
=Using Capsule=&lt;br /&gt;
&lt;br /&gt;
Declare an alias to Laravel's database manager in your project file's &amp;lt;tt&amp;gt;use&amp;lt;/tt&amp;gt; block to access Capsule:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
use Illuminate\Database\Capsule\Manager as Capsule;&lt;br /&gt;
&lt;br /&gt;
// Run queries or modify tables as you like.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==The Query Manager==&lt;br /&gt;
&lt;br /&gt;
: ''Please see [https://laravel.com/docs/5.2/queries Laravel's query documentation] for more information.''&lt;br /&gt;
&lt;br /&gt;
The '''Capsule::table(string $tableName)''' method provides access to the query manager. Declare it with the name of the table you wish to query as it's first parameter to interact with that table. The query manager has a wide range of functionality to perform advanced select, join, insert, update, and delete statements. Capsule's select calls return rows as ''stdClass'' objects.&lt;br /&gt;
&lt;br /&gt;
Capsule escapes all input, so it is not necessary to add escaping slashes to variables passed to these methods.&lt;br /&gt;
&lt;br /&gt;
All of Capsule's methods throw an exception on failure. Please place Capusle calls in &amp;lt;tt&amp;gt;try&amp;lt;/tt&amp;gt;/&amp;lt;tt&amp;gt;catch&amp;lt;/tt&amp;gt; blocks for graceful error handling and to avoid potential fatal errors in your hook, module, or other customization.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
use Illuminate\Database\Capsule\Manager as Capsule;&lt;br /&gt;
&lt;br /&gt;
// Print all client first names using a simple select.&lt;br /&gt;
&lt;br /&gt;
/** @var stdClass $client */&lt;br /&gt;
foreach (Capsule::table('tblclients')-&amp;gt;get() as $client) {&lt;br /&gt;
    echo $client-&amp;gt;firstname . PHP_EOL;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Rename all clients named &amp;quot;John Deo&amp;quot; to &amp;quot;John Doe&amp;quot; using an update statement. &lt;br /&gt;
try {&lt;br /&gt;
    $updatedUserCount = Capsule::table('tblclients')&lt;br /&gt;
        -&amp;gt;where('firstname', 'John')&lt;br /&gt;
        -&amp;gt;where('lastname', 'Deo')&lt;br /&gt;
        -&amp;gt;update(&lt;br /&gt;
            [&lt;br /&gt;
                'lastname' =&amp;gt; 'Doe',&lt;br /&gt;
            ]&lt;br /&gt;
        );&lt;br /&gt;
&lt;br /&gt;
    echo &amp;quot;Fixed {$updatedUserCount} misspelled last names.&amp;quot;;&lt;br /&gt;
} catch (\Exception $e) {&lt;br /&gt;
    echo &amp;quot;I couldn't update client names. {$e-&amp;gt;getMessage()}&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==The Schema Manager==&lt;br /&gt;
&lt;br /&gt;
Use the '''Capsule::schema()''' method to access the schema manager to modify table schema if necessary. The schema manager has support for creating, dropping and truncating tables and for modifying columns, indexes, and keys. &lt;br /&gt;
&lt;br /&gt;
'''Note''': WHMCS does not recommend changing default table schema as that can affect product functionality.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
use Illuminate\Database\Capsule\Manager as Capsule;&lt;br /&gt;
&lt;br /&gt;
// Create a new table.&lt;br /&gt;
try {&lt;br /&gt;
    Capsule::schema()-&amp;gt;create(&lt;br /&gt;
        'my_table',&lt;br /&gt;
        function ($table) {&lt;br /&gt;
            /** @var \Illuminate\Database\Schema\Blueprint $table */&lt;br /&gt;
            $table-&amp;gt;increments('id');&lt;br /&gt;
            $table-&amp;gt;string('name');&lt;br /&gt;
            $table-&amp;gt;integer('serial_number');&lt;br /&gt;
            $table-&amp;gt;boolean('is_required');&lt;br /&gt;
            $table-&amp;gt;timestamps();&lt;br /&gt;
        }&lt;br /&gt;
    );&lt;br /&gt;
} catch (\Exception $e) {&lt;br /&gt;
    echo &amp;quot;Unable to create my_table: {$e-&amp;gt;getMessage()}&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==The Connection Manager==&lt;br /&gt;
&lt;br /&gt;
The '''Capsule::connection()''' method provides low-level access to the database connection itself. Use it to initiate transactions with automatic commit and rollback or to access the underlying PDO connection to perform manual database queries outside the DBAL. The connection manager also has methods to retrieve query and schema managers.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
use Illuminate\Database\Capsule\Manager as Capsule;&lt;br /&gt;
&lt;br /&gt;
// Perform potentially risky queries in a transaction for easy rollback.&lt;br /&gt;
try {&lt;br /&gt;
    Capsule::connection()-&amp;gt;transaction(&lt;br /&gt;
        function ($connectionManager)&lt;br /&gt;
        {&lt;br /&gt;
            /** @var \Illuminate\Database\Connection $connectionManager */&lt;br /&gt;
            $connectionManager-&amp;gt;table('my_table')-&amp;gt;insert(&lt;br /&gt;
                [&lt;br /&gt;
                    'name' =&amp;gt; $_POST['name'],&lt;br /&gt;
                    'serial_number' =&amp;gt; $_POST['serialNumber'],&lt;br /&gt;
                    'is_required' =&amp;gt; (int)(bool) $_POST['isRequired'],&lt;br /&gt;
                ]&lt;br /&gt;
            );&lt;br /&gt;
        }&lt;br /&gt;
    );&lt;br /&gt;
} catch (\Exception $e) {&lt;br /&gt;
    echo &amp;quot;Uh oh! Inserting didn't work, but I was able to rollback. {$e-&amp;gt;getMessage()}&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Getting to PDO===&lt;br /&gt;
&lt;br /&gt;
Use the connection manager's '''getPdo()''' method to retrieve the underlying PDO connection instance. Use the PDO connection to perform manual queries and advanced database usage.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
use Illuminate\Database\Capsule\Manager as Capsule;&lt;br /&gt;
&lt;br /&gt;
// Perform potentially risky queries in a transaction for easy rollback.    &lt;br /&gt;
$pdo = Capsule::connection()-&amp;gt;getPdo();&lt;br /&gt;
$pdo-&amp;gt;beginTransaction();&lt;br /&gt;
&lt;br /&gt;
try {&lt;br /&gt;
    $statement = $pdo-&amp;gt;prepare(&lt;br /&gt;
        'insert into my_table (name, serial_number, is_required) values (:name, :serialNumber, :isRequired)'&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    $statement-&amp;gt;execute(&lt;br /&gt;
        [&lt;br /&gt;
            ':name' =&amp;gt; $_POST['name'],&lt;br /&gt;
            ':serialNumber' =&amp;gt; $_POST['serialNumber'],&lt;br /&gt;
            ':isRequired' =&amp;gt; (bool) $_POST['isRequired'],&lt;br /&gt;
        ]&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    $pdo-&amp;gt;commit();&lt;br /&gt;
} catch (\Exception $e) {&lt;br /&gt;
    echo &amp;quot;Uh oh! {$e-&amp;gt;getMessage()}&amp;quot;;&lt;br /&gt;
    $pdo-&amp;gt;rollBack();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Troubleshooting=&lt;br /&gt;
&lt;br /&gt;
==Exceptions==&lt;br /&gt;
&lt;br /&gt;
All Capsule methods throw an exception on failure. Catch these exceptions and analyze their messages and stack traces to help determine the nature of the failure. WHMCS recommends placing all database interactivity in &amp;lt;tt&amp;gt;try&amp;lt;/tt&amp;gt;/&amp;lt;tt&amp;gt;catch&amp;lt;/tt&amp;gt; blocks for graceful error handling.&lt;br /&gt;
&lt;br /&gt;
==The Capsule Query Log==&lt;br /&gt;
&lt;br /&gt;
The connection manager's '''getQueryLog()''' method returns an array of all queries made during the life of the page request. Queries are stored in the log as an array containing the query run, the parameter bindings passed to the query, and the time it took for the query to execute, measured in milliseconds.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
use Illuminate\Database\Capsule\Manager as Capsule;&lt;br /&gt;
&lt;br /&gt;
// Loop through each Capsule query made during the page request.&lt;br /&gt;
foreach (Capsule::connection()-&amp;gt;getQueryLog() as $query) {&lt;br /&gt;
    echo &amp;quot;Query: {$query['query']}&amp;quot; . PHP_EOL;&lt;br /&gt;
    echo &amp;quot;Execution Time: {$query['time']}ms&amp;quot; . PHP_EOL;&lt;br /&gt;
    echo &amp;quot;Parameters: &amp;quot; . PHP_EOL;&lt;br /&gt;
&lt;br /&gt;
    foreach ($query['bindings'] as $key =&amp;gt; $value) {&lt;br /&gt;
        echo &amp;quot;{$key} =&amp;gt; {$value}&amp;quot; . PHP_EOL;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==The WHMCS Activity Log==&lt;br /&gt;
&lt;br /&gt;
All uncaught PDO-based query failures, including those made by Capsule and manual PDO queries, are written to to the WHMCS activity log. View the system activity log to view the details of these failed queries.&lt;br /&gt;
&lt;br /&gt;
=See Also=&lt;br /&gt;
* [[SQL Helper Functions]] (functional, but deprecated in WHMCS 6.0)&lt;br /&gt;
&lt;br /&gt;
=External Links=&lt;br /&gt;
* [http://laravel.com/docs/4.2/queries Query Builder - Laravel 4.2]&lt;br /&gt;
* [http://laravel.com/docs/5.2/queries Query Builder - Laravel 5.2]&lt;br /&gt;
* [http://laravel.com/docs/4.2/schema Schema Builder - Laravel 4.2]&lt;br /&gt;
* [https://laravel.com/docs/5.0/schema - Laravel 5.2]&lt;br /&gt;
* [http://php.net/manual/en/book.pdo.php PHP: PDO]&lt;br /&gt;
&lt;br /&gt;
=References=&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Nicolas</name></author>	</entry>

	<entry>
		<id>http://3.19.219.109/index.php?title=Interacting_With_The_Database&amp;diff=19298</id>
		<title>Interacting With The Database</title>
		<link rel="alternate" type="text/html" href="http://3.19.219.109/index.php?title=Interacting_With_The_Database&amp;diff=19298"/>
				<updated>2016-07-11T17:22:10Z</updated>
		
		<summary type="html">&lt;p&gt;Nicolas: /* External Links */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Database connectivity changes in WHMCS 6.0=&lt;br /&gt;
&lt;br /&gt;
The mysql PHP extension was deprecated when PHP 5.5 was released in June 2013&amp;lt;ref&amp;gt;http://php.net/ChangeLog-5.php#5.5.0&amp;lt;/ref&amp;gt; and is scheduled to be removed in PHP 7&amp;lt;ref&amp;gt;https://wiki.php.net/rfc/remove_deprecated_functionality_in_php7&amp;lt;/ref&amp;gt;. WHMCS 6.0 introduces a new database connection and library to ensure compatibility with modern PHP environments and best practices.&lt;br /&gt;
&lt;br /&gt;
==New functionality==&lt;br /&gt;
&lt;br /&gt;
WHMCS 6.0 incorporates the Laravel framework 4.1's database component (''WHMCS 7.0 incorporates 5.2''). This library includes a Database Abstraction Layer (DBAL) called &amp;quot;Capsule&amp;quot; and an Object Relational Mapping (ORM) library called &amp;quot;Eloquent&amp;quot;. The new DBAL is based on the PHP Data Objects (PDO MySQL) extension and uses WHMCS's existing &amp;lt;tt&amp;gt;configuration.php&amp;lt;/tt&amp;gt; file. No configuration file changes are required to use the new database connection.&lt;br /&gt;
&lt;br /&gt;
The Capsule DBAL component introduces two libraries to WHMCS, a query manager for running database queries and a schema manager for an abstracted API to table management. Capsule's underlying PDO connection is also available for advanced database usage. Capsule has three static methods to get to these components:&lt;br /&gt;
&lt;br /&gt;
* '''Capsule::table(string $tableName)''': Access the query manager for the given table.&lt;br /&gt;
* '''Capsule::schema()''': Access the schema manager for the WHMCS database. &lt;br /&gt;
* '''Capsule::connection()''': Access the connection manager to interact with the underlying database connection.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' WHMCS 6.0 makes two connections to the database. One connection is made through the legacy mysql extension to handle existing hooks, modules, and other customizations. The other connection is made by PDO to drive new DBAL and model based functionality in the program. &lt;br /&gt;
&lt;br /&gt;
==Deprecated functionality==&lt;br /&gt;
&lt;br /&gt;
The current [[SQL Helper Functions]] are present in WHMCS 6.0 and above, but are now deprecated and may be removed in a later version of the product:&lt;br /&gt;
* '''select_query()'''&lt;br /&gt;
* '''update_query()'''&lt;br /&gt;
* '''insert_query()'''&lt;br /&gt;
* '''full_query()'''&lt;br /&gt;
&lt;br /&gt;
The mysql extension driven database connection is now deprecated and may be discontinued in a later version of the product. WHMCS encourages all third party developers to use the Capsule DBAL and PDO connection for all new database interaction.&lt;br /&gt;
&lt;br /&gt;
=Using Capsule=&lt;br /&gt;
&lt;br /&gt;
Declare an alias to Laravel's database manager in your project file's &amp;lt;tt&amp;gt;use&amp;lt;/tt&amp;gt; block to access Capsule:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
use Illuminate\Database\Capsule\Manager as Capsule;&lt;br /&gt;
&lt;br /&gt;
// Run queries or modify tables as you like.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==The Query Manager==&lt;br /&gt;
&lt;br /&gt;
: ''Please see [https://laravel.com/docs/5.2/queries Laravel's query documentation] for more information.''&lt;br /&gt;
&lt;br /&gt;
The '''Capsule::table(string $tableName)''' method provides access to the query manager. Declare it with the name of the table you wish to query as it's first parameter to interact with that table. The query manager has a wide range of functionality to perform advanced select, join, insert, update, and delete statements. Capsule's select calls return rows as ''stdClass'' objects.&lt;br /&gt;
&lt;br /&gt;
Capsule escapes all input, so it is not necessary to add escaping slashes to variables passed to these methods.&lt;br /&gt;
&lt;br /&gt;
All of Capsule's methods throw an exception on failure. Please place Capusle calls in &amp;lt;tt&amp;gt;try&amp;lt;/tt&amp;gt;/&amp;lt;tt&amp;gt;catch&amp;lt;/tt&amp;gt; blocks for graceful error handling and to avoid potential fatal errors in your hook, module, or other customization.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
use Illuminate\Database\Capsule\Manager as Capsule;&lt;br /&gt;
&lt;br /&gt;
// Print all client first names using a simple select.&lt;br /&gt;
&lt;br /&gt;
/** @var stdClass $client */&lt;br /&gt;
foreach (Capsule::table('tblclients')-&amp;gt;get() as $client) {&lt;br /&gt;
    echo $client-&amp;gt;firstname . PHP_EOL;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Rename all clients named &amp;quot;John Deo&amp;quot; to &amp;quot;John Doe&amp;quot; using an update statement. &lt;br /&gt;
try {&lt;br /&gt;
    $updatedUserCount = Capsule::table('tblclients')&lt;br /&gt;
        -&amp;gt;where('firstname', 'John')&lt;br /&gt;
        -&amp;gt;where('lastname', 'Deo')&lt;br /&gt;
        -&amp;gt;update(&lt;br /&gt;
            [&lt;br /&gt;
                'lastname' =&amp;gt; 'Doe',&lt;br /&gt;
            ]&lt;br /&gt;
        );&lt;br /&gt;
&lt;br /&gt;
    echo &amp;quot;Fixed {$updatedUserCount} misspelled last names.&amp;quot;;&lt;br /&gt;
} catch (\Exception $e) {&lt;br /&gt;
    echo &amp;quot;I couldn't update client names. {$e-&amp;gt;getMessage()}&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==The Schema Manager==&lt;br /&gt;
&lt;br /&gt;
Use the '''Capsule::schema()''' method to access the schema manager to modify table schema if necessary. The schema manager has support for creating, dropping and truncating tables and for modifying columns, indexes, and keys. &lt;br /&gt;
&lt;br /&gt;
'''Note''': WHMCS does not recommend changing default table schema as that can affect product functionality.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
use Illuminate\Database\Capsule\Manager as Capsule;&lt;br /&gt;
&lt;br /&gt;
// Create a new table.&lt;br /&gt;
try {&lt;br /&gt;
    Capsule::schema()-&amp;gt;create(&lt;br /&gt;
        'my_table',&lt;br /&gt;
        function ($table) {&lt;br /&gt;
            /** @var \Illuminate\Database\Schema\Blueprint $table */&lt;br /&gt;
            $table-&amp;gt;increments('id');&lt;br /&gt;
            $table-&amp;gt;string('name');&lt;br /&gt;
            $table-&amp;gt;integer('serial_number');&lt;br /&gt;
            $table-&amp;gt;boolean('is_required');&lt;br /&gt;
            $table-&amp;gt;timestamps();&lt;br /&gt;
        }&lt;br /&gt;
    );&lt;br /&gt;
} catch (\Exception $e) {&lt;br /&gt;
    echo &amp;quot;Unable to create my_table: {$e-&amp;gt;getMessage()}&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==The Connection Manager==&lt;br /&gt;
&lt;br /&gt;
The '''Capsule::connection()''' method provides low-level access to the database connection itself. Use it to initiate transactions with automatic commit and rollback or to access the underlying PDO connection to perform manual database queries outside the DBAL. The connection manager also has methods to retrieve query and schema managers.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
use Illuminate\Database\Capsule\Manager as Capsule;&lt;br /&gt;
&lt;br /&gt;
// Perform potentially risky queries in a transaction for easy rollback.&lt;br /&gt;
try {&lt;br /&gt;
    Capsule::connection()-&amp;gt;transaction(&lt;br /&gt;
        function ($connectionManager)&lt;br /&gt;
        {&lt;br /&gt;
            /** @var \Illuminate\Database\Connection $connectionManager */&lt;br /&gt;
            $connectionManager-&amp;gt;table('my_table')-&amp;gt;insert(&lt;br /&gt;
                [&lt;br /&gt;
                    'name' =&amp;gt; $_POST['name'],&lt;br /&gt;
                    'serial_number' =&amp;gt; $_POST['serialNumber'],&lt;br /&gt;
                    'is_required' =&amp;gt; (int)(bool) $_POST['isRequired'],&lt;br /&gt;
                ]&lt;br /&gt;
            );&lt;br /&gt;
        }&lt;br /&gt;
    );&lt;br /&gt;
} catch (\Exception $e) {&lt;br /&gt;
    echo &amp;quot;Uh oh! Inserting didn't work, but I was able to rollback. {$e-&amp;gt;getMessage()}&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Getting to PDO===&lt;br /&gt;
&lt;br /&gt;
Use the connection manager's '''getPdo()''' method to retrieve the underlying PDO connection instance. Use the PDO connection to perform manual queries and advanced database usage.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
use Illuminate\Database\Capsule\Manager as Capsule;&lt;br /&gt;
&lt;br /&gt;
// Perform potentially risky queries in a transaction for easy rollback.    &lt;br /&gt;
$pdo = Capsule::connection()-&amp;gt;getPdo();&lt;br /&gt;
$pdo-&amp;gt;beginTransaction();&lt;br /&gt;
&lt;br /&gt;
try {&lt;br /&gt;
    $statement = $pdo-&amp;gt;prepare(&lt;br /&gt;
        'insert into my_table (name, serial_number, is_required) values (:name, :serialNumber, :isRequired)'&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    $statement-&amp;gt;execute(&lt;br /&gt;
        [&lt;br /&gt;
            ':name' =&amp;gt; $_POST['name'],&lt;br /&gt;
            ':serialNumber' =&amp;gt; $_POST['serialNumber'],&lt;br /&gt;
            ':isRequired' =&amp;gt; (bool) $_POST['isRequired'],&lt;br /&gt;
        ]&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    $pdo-&amp;gt;commit();&lt;br /&gt;
} catch (\Exception $e) {&lt;br /&gt;
    echo &amp;quot;Uh oh! {$e-&amp;gt;getMessage()}&amp;quot;;&lt;br /&gt;
    $pdo-&amp;gt;rollBack();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Troubleshooting=&lt;br /&gt;
&lt;br /&gt;
==Exceptions==&lt;br /&gt;
&lt;br /&gt;
All Capsule methods throw an exception on failure. Catch these exceptions and analyze their messages and stack traces to help determine the nature of the failure. WHMCS recommends placing all database interactivity in &amp;lt;tt&amp;gt;try&amp;lt;/tt&amp;gt;/&amp;lt;tt&amp;gt;catch&amp;lt;/tt&amp;gt; blocks for graceful error handling.&lt;br /&gt;
&lt;br /&gt;
==The Capsule Query Log==&lt;br /&gt;
&lt;br /&gt;
The connection manager's '''getQueryLog()''' method returns an array of all queries made during the life of the page request. Queries are stored in the log as an array containing the query run, the parameter bindings passed to the query, and the time it took for the query to execute, measured in milliseconds.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
use Illuminate\Database\Capsule\Manager as Capsule;&lt;br /&gt;
&lt;br /&gt;
// Loop through each Capsule query made during the page request.&lt;br /&gt;
foreach (Capsule::connection()-&amp;gt;getQueryLog() as $query) {&lt;br /&gt;
    echo &amp;quot;Query: {$query['query']}&amp;quot; . PHP_EOL;&lt;br /&gt;
    echo &amp;quot;Execution Time: {$query['time']}ms&amp;quot; . PHP_EOL;&lt;br /&gt;
    echo &amp;quot;Parameters: &amp;quot; . PHP_EOL;&lt;br /&gt;
&lt;br /&gt;
    foreach ($query['bindings'] as $key =&amp;gt; $value) {&lt;br /&gt;
        echo &amp;quot;{$key} =&amp;gt; {$value}&amp;quot; . PHP_EOL;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==The WHMCS Activity Log==&lt;br /&gt;
&lt;br /&gt;
All uncaught PDO-based query failures, including those made by Capsule and manual PDO queries, are written to to the WHMCS activity log. View the system activity log to view the details of these failed queries.&lt;br /&gt;
&lt;br /&gt;
=See Also=&lt;br /&gt;
* [[SQL Helper Functions]] (functional, but deprecated in WHMCS 6.0)&lt;br /&gt;
&lt;br /&gt;
=External Links=&lt;br /&gt;
* [http://laravel.com/docs/4.2/queries Query Builder - Laravel 4.2]&lt;br /&gt;
* [http://laravel.com/docs/5.2/queries Query Builder - Laravel 5.2]&lt;br /&gt;
* [http://laravel.com/docs/4.2/schema Schema Builder - Laravel 4.2]&lt;br /&gt;
* [http://php.net/manual/en/book.pdo.php PHP: PDO]&lt;br /&gt;
&lt;br /&gt;
=References=&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Nicolas</name></author>	</entry>

	<entry>
		<id>http://3.19.219.109/index.php?title=Creating_Pages&amp;diff=19294</id>
		<title>Creating Pages</title>
		<link rel="alternate" type="text/html" href="http://3.19.219.109/index.php?title=Creating_Pages&amp;diff=19294"/>
				<updated>2016-07-11T17:01:31Z</updated>
		
		<summary type="html">&lt;p&gt;Nicolas: /* Page with a Sidebar */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Creating your own custom pages for WHMCS is simple. Use this to extend the client area. For example, building the whole site around WHMCS, or creating custom pages to provide extra functionality to clients.&lt;br /&gt;
&lt;br /&gt;
==Standard Page==&lt;br /&gt;
&lt;br /&gt;
To get started, copy &amp;amp; paste the code below into a new PHP file and save it in the main WHMCS directory.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
use WHMCS\Database\Capsule;&lt;br /&gt;
&lt;br /&gt;
define(&amp;quot;CLIENTAREA&amp;quot;, true);&lt;br /&gt;
//define(&amp;quot;FORCESSL&amp;quot;, true); // Uncomment to force the page to use https://&lt;br /&gt;
&lt;br /&gt;
require(&amp;quot;init.php&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
$ca = new WHMCS_ClientArea();&lt;br /&gt;
&lt;br /&gt;
$ca-&amp;gt;setPageTitle(&amp;quot;Your Page Title Goes Here&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
$ca-&amp;gt;addToBreadCrumb('index.php', Lang::trans('globalsystemname'));&lt;br /&gt;
$ca-&amp;gt;addToBreadCrumb('mypage.php', 'Your Custom Page Name');&lt;br /&gt;
&lt;br /&gt;
$ca-&amp;gt;initPage();&lt;br /&gt;
&lt;br /&gt;
//$ca-&amp;gt;requireLogin(); // Uncomment this line to require a login to access this page&lt;br /&gt;
&lt;br /&gt;
# To assign variables to the template system use the following syntax.&lt;br /&gt;
# These can then be referenced using {$variablename} in the template.&lt;br /&gt;
&lt;br /&gt;
$ca-&amp;gt;assign('variablename', $value);&lt;br /&gt;
&lt;br /&gt;
# Check login status&lt;br /&gt;
if ($ca-&amp;gt;isLoggedIn()) {&lt;br /&gt;
&lt;br /&gt;
  # User is logged in - put any code you like here&lt;br /&gt;
&lt;br /&gt;
  # Here's an example to get the currently logged in clients first name&lt;br /&gt;
&lt;br /&gt;
  $clientName = Capsule::table('tblclients')&lt;br /&gt;
      -&amp;gt;where('id', '=', $ca-&amp;gt;getUserID())-&amp;gt;pluck('firstname');&lt;br /&gt;
      // 'pluck' was renamed within WHMCS 7.0.  Replace it with 'value' instead.&lt;br /&gt;
      // -&amp;gt;where('id', '=', $ca-&amp;gt;getUserID())-&amp;gt;value('firstname');&lt;br /&gt;
&lt;br /&gt;
  $ca-&amp;gt;assign('clientname', $clientName);&lt;br /&gt;
&lt;br /&gt;
} else {&lt;br /&gt;
&lt;br /&gt;
  # User is not logged in&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
# Define the template filename to be used without the .tpl extension&lt;br /&gt;
&lt;br /&gt;
$ca-&amp;gt;setTemplate('mypage');&lt;br /&gt;
&lt;br /&gt;
$ca-&amp;gt;output();&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This example above shows you the required layout of a custom page.  It demonstrates:&lt;br /&gt;
&lt;br /&gt;
*How to initiate the page&lt;br /&gt;
*How to force the page to use SSL (FORCESSL)&lt;br /&gt;
*How to reference the language file variables (Lang::trans)&lt;br /&gt;
*How to check if a user is logged in ($ca-&amp;gt;isLoggedIn())&lt;br /&gt;
*How to define template variables ($ca-&amp;gt;assign)&lt;br /&gt;
*How to set the template to use and then output it&lt;br /&gt;
&lt;br /&gt;
The template file should be a filename in the active WHMCS system template folder. So, for the example above the path would be /templates/default/mypage.tpl.&lt;br /&gt;
&lt;br /&gt;
Now when ready to test, upload both the PHP and TPL file to the appropriate folders. Then visit the PHP file in the root WHMCS directory to run.&lt;br /&gt;
&lt;br /&gt;
==Page with a Sidebar==&lt;br /&gt;
It is possible to define a [[Editing_Client_Area_Menus|sidebar]] display on a custom page. The following shows how to create a custom page, and also define a sidebar to display alongside. It demonstrates:&lt;br /&gt;
&lt;br /&gt;
*How to set contact for the sidebar, thereby influencing what data passes to the menu&lt;br /&gt;
*How to define both the primary and secondary sidebars for display&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
use WHMCS\ClientArea;&lt;br /&gt;
use WHMCS\Database\Capsule;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
define('CLIENTAREA', true);&lt;br /&gt;
//define('FORCESSL', true); // Uncomment to force the page to use https://&lt;br /&gt;
&lt;br /&gt;
require __DIR__ . '/init.php';&lt;br /&gt;
&lt;br /&gt;
$ca = new ClientArea();&lt;br /&gt;
&lt;br /&gt;
$ca-&amp;gt;setPageTitle('Your Page Title Goes Here');&lt;br /&gt;
&lt;br /&gt;
$ca-&amp;gt;addToBreadCrumb('index.php', Lang::trans('globalsystemname'));&lt;br /&gt;
$ca-&amp;gt;addToBreadCrumb('mypage.php', 'Your Custom Page Name');&lt;br /&gt;
&lt;br /&gt;
$ca-&amp;gt;initPage();&lt;br /&gt;
&lt;br /&gt;
//$ca-&amp;gt;requireLogin(); // Uncomment this line to require a login to access this page&lt;br /&gt;
&lt;br /&gt;
// To assign variables to the template system use the following syntax.&lt;br /&gt;
// These can then be referenced using {$variablename} in the template.&lt;br /&gt;
&lt;br /&gt;
//$ca-&amp;gt;assign('variablename', $value);&lt;br /&gt;
&lt;br /&gt;
// Check login status&lt;br /&gt;
if ($ca-&amp;gt;isLoggedIn()) {&lt;br /&gt;
&lt;br /&gt;
    /**&lt;br /&gt;
     * User is logged in - put any code you like here&lt;br /&gt;
     *&lt;br /&gt;
     * Here's an example to get the currently logged in clients first name&lt;br /&gt;
     */&lt;br /&gt;
&lt;br /&gt;
    $clientName = Capsule::table('tblclients')&lt;br /&gt;
        -&amp;gt;where('id', '=', $ca-&amp;gt;getUserID())-&amp;gt;pluck('firstname');&lt;br /&gt;
        // 'pluck' was renamed within WHMCS 7.0.  Replace it with 'value' instead.&lt;br /&gt;
        // -&amp;gt;where('id', '=', $ca-&amp;gt;getUserID())-&amp;gt;value('firstname');&lt;br /&gt;
    $ca-&amp;gt;assign('clientname', $clientName);&lt;br /&gt;
&lt;br /&gt;
} else {&lt;br /&gt;
&lt;br /&gt;
    // User is not logged in&lt;br /&gt;
    $ca-&amp;gt;assign('clientname', 'Random User');&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Set a context for sidebars&lt;br /&gt;
 *&lt;br /&gt;
 * @link http://docs.whmcs.com/Editing_Client_Area_Menus#Context&lt;br /&gt;
 */&lt;br /&gt;
Menu::addContext();&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Setup the primary and secondary sidebars&lt;br /&gt;
 *&lt;br /&gt;
 * @link http://docs.whmcs.com/Editing_Client_Area_Menus#Context&lt;br /&gt;
 */&lt;br /&gt;
Menu::primarySidebar('announcementList');&lt;br /&gt;
Menu::secondarySidebar('announcementList');&lt;br /&gt;
&lt;br /&gt;
# Define the template filename to be used without the .tpl extension&lt;br /&gt;
&lt;br /&gt;
$ca-&amp;gt;setTemplate('mypage');&lt;br /&gt;
&lt;br /&gt;
$ca-&amp;gt;output();&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Developer_Links}}&lt;/div&gt;</summary>
		<author><name>Nicolas</name></author>	</entry>

	<entry>
		<id>http://3.19.219.109/index.php?title=Creating_Pages&amp;diff=19290</id>
		<title>Creating Pages</title>
		<link rel="alternate" type="text/html" href="http://3.19.219.109/index.php?title=Creating_Pages&amp;diff=19290"/>
				<updated>2016-07-11T17:00:35Z</updated>
		
		<summary type="html">&lt;p&gt;Nicolas: /* Standard Page */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Creating your own custom pages for WHMCS is simple. Use this to extend the client area. For example, building the whole site around WHMCS, or creating custom pages to provide extra functionality to clients.&lt;br /&gt;
&lt;br /&gt;
==Standard Page==&lt;br /&gt;
&lt;br /&gt;
To get started, copy &amp;amp; paste the code below into a new PHP file and save it in the main WHMCS directory.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
use WHMCS\Database\Capsule;&lt;br /&gt;
&lt;br /&gt;
define(&amp;quot;CLIENTAREA&amp;quot;, true);&lt;br /&gt;
//define(&amp;quot;FORCESSL&amp;quot;, true); // Uncomment to force the page to use https://&lt;br /&gt;
&lt;br /&gt;
require(&amp;quot;init.php&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
$ca = new WHMCS_ClientArea();&lt;br /&gt;
&lt;br /&gt;
$ca-&amp;gt;setPageTitle(&amp;quot;Your Page Title Goes Here&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
$ca-&amp;gt;addToBreadCrumb('index.php', Lang::trans('globalsystemname'));&lt;br /&gt;
$ca-&amp;gt;addToBreadCrumb('mypage.php', 'Your Custom Page Name');&lt;br /&gt;
&lt;br /&gt;
$ca-&amp;gt;initPage();&lt;br /&gt;
&lt;br /&gt;
//$ca-&amp;gt;requireLogin(); // Uncomment this line to require a login to access this page&lt;br /&gt;
&lt;br /&gt;
# To assign variables to the template system use the following syntax.&lt;br /&gt;
# These can then be referenced using {$variablename} in the template.&lt;br /&gt;
&lt;br /&gt;
$ca-&amp;gt;assign('variablename', $value);&lt;br /&gt;
&lt;br /&gt;
# Check login status&lt;br /&gt;
if ($ca-&amp;gt;isLoggedIn()) {&lt;br /&gt;
&lt;br /&gt;
  # User is logged in - put any code you like here&lt;br /&gt;
&lt;br /&gt;
  # Here's an example to get the currently logged in clients first name&lt;br /&gt;
&lt;br /&gt;
  $clientName = Capsule::table('tblclients')&lt;br /&gt;
      -&amp;gt;where('id', '=', $ca-&amp;gt;getUserID())-&amp;gt;pluck('firstname');&lt;br /&gt;
      // 'pluck' was renamed within WHMCS 7.0.  Replace it with 'value' instead.&lt;br /&gt;
      // -&amp;gt;where('id', '=', $ca-&amp;gt;getUserID())-&amp;gt;value('firstname');&lt;br /&gt;
&lt;br /&gt;
  $ca-&amp;gt;assign('clientname', $clientName);&lt;br /&gt;
&lt;br /&gt;
} else {&lt;br /&gt;
&lt;br /&gt;
  # User is not logged in&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
# Define the template filename to be used without the .tpl extension&lt;br /&gt;
&lt;br /&gt;
$ca-&amp;gt;setTemplate('mypage');&lt;br /&gt;
&lt;br /&gt;
$ca-&amp;gt;output();&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This example above shows you the required layout of a custom page.  It demonstrates:&lt;br /&gt;
&lt;br /&gt;
*How to initiate the page&lt;br /&gt;
*How to force the page to use SSL (FORCESSL)&lt;br /&gt;
*How to reference the language file variables (Lang::trans)&lt;br /&gt;
*How to check if a user is logged in ($ca-&amp;gt;isLoggedIn())&lt;br /&gt;
*How to define template variables ($ca-&amp;gt;assign)&lt;br /&gt;
*How to set the template to use and then output it&lt;br /&gt;
&lt;br /&gt;
The template file should be a filename in the active WHMCS system template folder. So, for the example above the path would be /templates/default/mypage.tpl.&lt;br /&gt;
&lt;br /&gt;
Now when ready to test, upload both the PHP and TPL file to the appropriate folders. Then visit the PHP file in the root WHMCS directory to run.&lt;br /&gt;
&lt;br /&gt;
==Page with a Sidebar==&lt;br /&gt;
It is possible to define a [[Editing_Client_Area_Menus|sidebar]] display on a custom page. The following shows how to create a custom page, and also define a sidebar to display alongside. It demonstrates:&lt;br /&gt;
&lt;br /&gt;
*How to set contact for the sidebar, thereby influencing what data passes to the menu&lt;br /&gt;
*How to define both the primary and secondary sidebars for display&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
use WHMCS\ClientArea;&lt;br /&gt;
use WHMCS\Database\Capsule;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
define('CLIENTAREA', true);&lt;br /&gt;
//define('FORCESSL', true); // Uncomment to force the page to use https://&lt;br /&gt;
&lt;br /&gt;
require __DIR__ . '/init.php';&lt;br /&gt;
&lt;br /&gt;
$ca = new ClientArea();&lt;br /&gt;
&lt;br /&gt;
$ca-&amp;gt;setPageTitle('Your Page Title Goes Here');&lt;br /&gt;
&lt;br /&gt;
$ca-&amp;gt;addToBreadCrumb('index.php', Lang::trans('globalsystemname'));&lt;br /&gt;
$ca-&amp;gt;addToBreadCrumb('mypage.php', 'Your Custom Page Name');&lt;br /&gt;
&lt;br /&gt;
$ca-&amp;gt;initPage();&lt;br /&gt;
&lt;br /&gt;
//$ca-&amp;gt;requireLogin(); // Uncomment this line to require a login to access this page&lt;br /&gt;
&lt;br /&gt;
// To assign variables to the template system use the following syntax.&lt;br /&gt;
// These can then be referenced using {$variablename} in the template.&lt;br /&gt;
&lt;br /&gt;
//$ca-&amp;gt;assign('variablename', $value);&lt;br /&gt;
&lt;br /&gt;
// Check login status&lt;br /&gt;
if ($ca-&amp;gt;isLoggedIn()) {&lt;br /&gt;
&lt;br /&gt;
    /**&lt;br /&gt;
     * User is logged in - put any code you like here&lt;br /&gt;
     *&lt;br /&gt;
     * Here's an example to get the currently logged in clients first name&lt;br /&gt;
     */&lt;br /&gt;
&lt;br /&gt;
    $clientName = Capsule::table('tblclients')&lt;br /&gt;
        -&amp;gt;where('id', '=', $ca-&amp;gt;getUserID())-&amp;gt;pluck('firstname');&lt;br /&gt;
    $ca-&amp;gt;assign('clientname', $clientName);&lt;br /&gt;
&lt;br /&gt;
} else {&lt;br /&gt;
&lt;br /&gt;
    // User is not logged in&lt;br /&gt;
    $ca-&amp;gt;assign('clientname', 'Random User');&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Set a context for sidebars&lt;br /&gt;
 *&lt;br /&gt;
 * @link http://docs.whmcs.com/Editing_Client_Area_Menus#Context&lt;br /&gt;
 */&lt;br /&gt;
Menu::addContext();&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Setup the primary and secondary sidebars&lt;br /&gt;
 *&lt;br /&gt;
 * @link http://docs.whmcs.com/Editing_Client_Area_Menus#Context&lt;br /&gt;
 */&lt;br /&gt;
Menu::primarySidebar('announcementList');&lt;br /&gt;
Menu::secondarySidebar('announcementList');&lt;br /&gt;
&lt;br /&gt;
# Define the template filename to be used without the .tpl extension&lt;br /&gt;
&lt;br /&gt;
$ca-&amp;gt;setTemplate('mypage');&lt;br /&gt;
&lt;br /&gt;
$ca-&amp;gt;output();&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Developer_Links}}&lt;/div&gt;</summary>
		<author><name>Nicolas</name></author>	</entry>

	<entry>
		<id>http://3.19.219.109/index.php?title=Interacting_With_The_Database&amp;diff=19286</id>
		<title>Interacting With The Database</title>
		<link rel="alternate" type="text/html" href="http://3.19.219.109/index.php?title=Interacting_With_The_Database&amp;diff=19286"/>
				<updated>2016-07-11T16:43:22Z</updated>
		
		<summary type="html">&lt;p&gt;Nicolas: /* Database connectivity changes in WHMCS 6.0 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Database connectivity changes in WHMCS 6.0=&lt;br /&gt;
&lt;br /&gt;
The mysql PHP extension was deprecated when PHP 5.5 was released in June 2013&amp;lt;ref&amp;gt;http://php.net/ChangeLog-5.php#5.5.0&amp;lt;/ref&amp;gt; and is scheduled to be removed in PHP 7&amp;lt;ref&amp;gt;https://wiki.php.net/rfc/remove_deprecated_functionality_in_php7&amp;lt;/ref&amp;gt;. WHMCS 6.0 introduces a new database connection and library to ensure compatibility with modern PHP environments and best practices.&lt;br /&gt;
&lt;br /&gt;
==New functionality==&lt;br /&gt;
&lt;br /&gt;
WHMCS 6.0 incorporates the Laravel framework 4.1's database component (''WHMCS 7.0 incorporates 5.2''). This library includes a Database Abstraction Layer (DBAL) called &amp;quot;Capsule&amp;quot; and an Object Relational Mapping (ORM) library called &amp;quot;Eloquent&amp;quot;. The new DBAL is based on the PHP Data Objects (PDO MySQL) extension and uses WHMCS's existing &amp;lt;tt&amp;gt;configuration.php&amp;lt;/tt&amp;gt; file. No configuration file changes are required to use the new database connection.&lt;br /&gt;
&lt;br /&gt;
The Capsule DBAL component introduces two libraries to WHMCS, a query manager for running database queries and a schema manager for an abstracted API to table management. Capsule's underlying PDO connection is also available for advanced database usage. Capsule has three static methods to get to these components:&lt;br /&gt;
&lt;br /&gt;
* '''Capsule::table(string $tableName)''': Access the query manager for the given table.&lt;br /&gt;
* '''Capsule::schema()''': Access the schema manager for the WHMCS database. &lt;br /&gt;
* '''Capsule::connection()''': Access the connection manager to interact with the underlying database connection.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' WHMCS 6.0 makes two connections to the database. One connection is made through the legacy mysql extension to handle existing hooks, modules, and other customizations. The other connection is made by PDO to drive new DBAL and model based functionality in the program. &lt;br /&gt;
&lt;br /&gt;
==Deprecated functionality==&lt;br /&gt;
&lt;br /&gt;
The current [[SQL Helper Functions]] are present in WHMCS 6.0 and above, but are now deprecated and may be removed in a later version of the product:&lt;br /&gt;
* '''select_query()'''&lt;br /&gt;
* '''update_query()'''&lt;br /&gt;
* '''insert_query()'''&lt;br /&gt;
* '''full_query()'''&lt;br /&gt;
&lt;br /&gt;
The mysql extension driven database connection is now deprecated and may be discontinued in a later version of the product. WHMCS encourages all third party developers to use the Capsule DBAL and PDO connection for all new database interaction.&lt;br /&gt;
&lt;br /&gt;
=Using Capsule=&lt;br /&gt;
&lt;br /&gt;
Declare an alias to Laravel's database manager in your project file's &amp;lt;tt&amp;gt;use&amp;lt;/tt&amp;gt; block to access Capsule:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
use Illuminate\Database\Capsule\Manager as Capsule;&lt;br /&gt;
&lt;br /&gt;
// Run queries or modify tables as you like.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==The Query Manager==&lt;br /&gt;
&lt;br /&gt;
: ''Please see [https://laravel.com/docs/5.2/queries Laravel's query documentation] for more information.''&lt;br /&gt;
&lt;br /&gt;
The '''Capsule::table(string $tableName)''' method provides access to the query manager. Declare it with the name of the table you wish to query as it's first parameter to interact with that table. The query manager has a wide range of functionality to perform advanced select, join, insert, update, and delete statements. Capsule's select calls return rows as ''stdClass'' objects.&lt;br /&gt;
&lt;br /&gt;
Capsule escapes all input, so it is not necessary to add escaping slashes to variables passed to these methods.&lt;br /&gt;
&lt;br /&gt;
All of Capsule's methods throw an exception on failure. Please place Capusle calls in &amp;lt;tt&amp;gt;try&amp;lt;/tt&amp;gt;/&amp;lt;tt&amp;gt;catch&amp;lt;/tt&amp;gt; blocks for graceful error handling and to avoid potential fatal errors in your hook, module, or other customization.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
use Illuminate\Database\Capsule\Manager as Capsule;&lt;br /&gt;
&lt;br /&gt;
// Print all client first names using a simple select.&lt;br /&gt;
&lt;br /&gt;
/** @var stdClass $client */&lt;br /&gt;
foreach (Capsule::table('tblclients')-&amp;gt;get() as $client) {&lt;br /&gt;
    echo $client-&amp;gt;firstname . PHP_EOL;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Rename all clients named &amp;quot;John Deo&amp;quot; to &amp;quot;John Doe&amp;quot; using an update statement. &lt;br /&gt;
try {&lt;br /&gt;
    $updatedUserCount = Capsule::table('tblclients')&lt;br /&gt;
        -&amp;gt;where('firstname', 'John')&lt;br /&gt;
        -&amp;gt;where('lastname', 'Deo')&lt;br /&gt;
        -&amp;gt;update(&lt;br /&gt;
            [&lt;br /&gt;
                'lastname' =&amp;gt; 'Doe',&lt;br /&gt;
            ]&lt;br /&gt;
        );&lt;br /&gt;
&lt;br /&gt;
    echo &amp;quot;Fixed {$updatedUserCount} misspelled last names.&amp;quot;;&lt;br /&gt;
} catch (\Exception $e) {&lt;br /&gt;
    echo &amp;quot;I couldn't update client names. {$e-&amp;gt;getMessage()}&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==The Schema Manager==&lt;br /&gt;
&lt;br /&gt;
Use the '''Capsule::schema()''' method to access the schema manager to modify table schema if necessary. The schema manager has support for creating, dropping and truncating tables and for modifying columns, indexes, and keys. &lt;br /&gt;
&lt;br /&gt;
'''Note''': WHMCS does not recommend changing default table schema as that can affect product functionality.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
use Illuminate\Database\Capsule\Manager as Capsule;&lt;br /&gt;
&lt;br /&gt;
// Create a new table.&lt;br /&gt;
try {&lt;br /&gt;
    Capsule::schema()-&amp;gt;create(&lt;br /&gt;
        'my_table',&lt;br /&gt;
        function ($table) {&lt;br /&gt;
            /** @var \Illuminate\Database\Schema\Blueprint $table */&lt;br /&gt;
            $table-&amp;gt;increments('id');&lt;br /&gt;
            $table-&amp;gt;string('name');&lt;br /&gt;
            $table-&amp;gt;integer('serial_number');&lt;br /&gt;
            $table-&amp;gt;boolean('is_required');&lt;br /&gt;
            $table-&amp;gt;timestamps();&lt;br /&gt;
        }&lt;br /&gt;
    );&lt;br /&gt;
} catch (\Exception $e) {&lt;br /&gt;
    echo &amp;quot;Unable to create my_table: {$e-&amp;gt;getMessage()}&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==The Connection Manager==&lt;br /&gt;
&lt;br /&gt;
The '''Capsule::connection()''' method provides low-level access to the database connection itself. Use it to initiate transactions with automatic commit and rollback or to access the underlying PDO connection to perform manual database queries outside the DBAL. The connection manager also has methods to retrieve query and schema managers.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
use Illuminate\Database\Capsule\Manager as Capsule;&lt;br /&gt;
&lt;br /&gt;
// Perform potentially risky queries in a transaction for easy rollback.&lt;br /&gt;
try {&lt;br /&gt;
    Capsule::connection()-&amp;gt;transaction(&lt;br /&gt;
        function ($connectionManager)&lt;br /&gt;
        {&lt;br /&gt;
            /** @var \Illuminate\Database\Connection $connectionManager */&lt;br /&gt;
            $connectionManager-&amp;gt;table('my_table')-&amp;gt;insert(&lt;br /&gt;
                [&lt;br /&gt;
                    'name' =&amp;gt; $_POST['name'],&lt;br /&gt;
                    'serial_number' =&amp;gt; $_POST['serialNumber'],&lt;br /&gt;
                    'is_required' =&amp;gt; (int)(bool) $_POST['isRequired'],&lt;br /&gt;
                ]&lt;br /&gt;
            );&lt;br /&gt;
        }&lt;br /&gt;
    );&lt;br /&gt;
} catch (\Exception $e) {&lt;br /&gt;
    echo &amp;quot;Uh oh! Inserting didn't work, but I was able to rollback. {$e-&amp;gt;getMessage()}&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Getting to PDO===&lt;br /&gt;
&lt;br /&gt;
Use the connection manager's '''getPdo()''' method to retrieve the underlying PDO connection instance. Use the PDO connection to perform manual queries and advanced database usage.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
use Illuminate\Database\Capsule\Manager as Capsule;&lt;br /&gt;
&lt;br /&gt;
// Perform potentially risky queries in a transaction for easy rollback.    &lt;br /&gt;
$pdo = Capsule::connection()-&amp;gt;getPdo();&lt;br /&gt;
$pdo-&amp;gt;beginTransaction();&lt;br /&gt;
&lt;br /&gt;
try {&lt;br /&gt;
    $statement = $pdo-&amp;gt;prepare(&lt;br /&gt;
        'insert into my_table (name, serial_number, is_required) values (:name, :serialNumber, :isRequired)'&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    $statement-&amp;gt;execute(&lt;br /&gt;
        [&lt;br /&gt;
            ':name' =&amp;gt; $_POST['name'],&lt;br /&gt;
            ':serialNumber' =&amp;gt; $_POST['serialNumber'],&lt;br /&gt;
            ':isRequired' =&amp;gt; (bool) $_POST['isRequired'],&lt;br /&gt;
        ]&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    $pdo-&amp;gt;commit();&lt;br /&gt;
} catch (\Exception $e) {&lt;br /&gt;
    echo &amp;quot;Uh oh! {$e-&amp;gt;getMessage()}&amp;quot;;&lt;br /&gt;
    $pdo-&amp;gt;rollBack();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Troubleshooting=&lt;br /&gt;
&lt;br /&gt;
==Exceptions==&lt;br /&gt;
&lt;br /&gt;
All Capsule methods throw an exception on failure. Catch these exceptions and analyze their messages and stack traces to help determine the nature of the failure. WHMCS recommends placing all database interactivity in &amp;lt;tt&amp;gt;try&amp;lt;/tt&amp;gt;/&amp;lt;tt&amp;gt;catch&amp;lt;/tt&amp;gt; blocks for graceful error handling.&lt;br /&gt;
&lt;br /&gt;
==The Capsule Query Log==&lt;br /&gt;
&lt;br /&gt;
The connection manager's '''getQueryLog()''' method returns an array of all queries made during the life of the page request. Queries are stored in the log as an array containing the query run, the parameter bindings passed to the query, and the time it took for the query to execute, measured in milliseconds.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
use Illuminate\Database\Capsule\Manager as Capsule;&lt;br /&gt;
&lt;br /&gt;
// Loop through each Capsule query made during the page request.&lt;br /&gt;
foreach (Capsule::connection()-&amp;gt;getQueryLog() as $query) {&lt;br /&gt;
    echo &amp;quot;Query: {$query['query']}&amp;quot; . PHP_EOL;&lt;br /&gt;
    echo &amp;quot;Execution Time: {$query['time']}ms&amp;quot; . PHP_EOL;&lt;br /&gt;
    echo &amp;quot;Parameters: &amp;quot; . PHP_EOL;&lt;br /&gt;
&lt;br /&gt;
    foreach ($query['bindings'] as $key =&amp;gt; $value) {&lt;br /&gt;
        echo &amp;quot;{$key} =&amp;gt; {$value}&amp;quot; . PHP_EOL;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==The WHMCS Activity Log==&lt;br /&gt;
&lt;br /&gt;
All uncaught PDO-based query failures, including those made by Capsule and manual PDO queries, are written to to the WHMCS activity log. View the system activity log to view the details of these failed queries.&lt;br /&gt;
&lt;br /&gt;
=See Also=&lt;br /&gt;
* [[SQL Helper Functions]] (functional, but deprecated in WHMCS 6.0)&lt;br /&gt;
&lt;br /&gt;
=External Links=&lt;br /&gt;
* [http://laravel.com/docs/4.2/queries Query Builder - Laravel 4.2]&lt;br /&gt;
* [http://laravel.com/docs/4.2/schema Schema Builder - Laravel 4.2]&lt;br /&gt;
* [http://php.net/manual/en/book.pdo.php PHP: PDO]&lt;br /&gt;
&lt;br /&gt;
=References=&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Nicolas</name></author>	</entry>

	<entry>
		<id>http://3.19.219.109/index.php?title=Interacting_With_The_Database&amp;diff=19282</id>
		<title>Interacting With The Database</title>
		<link rel="alternate" type="text/html" href="http://3.19.219.109/index.php?title=Interacting_With_The_Database&amp;diff=19282"/>
				<updated>2016-07-11T16:01:43Z</updated>
		
		<summary type="html">&lt;p&gt;Nicolas: /* The Query Manager */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Database connectivity changes in WHMCS 6.0=&lt;br /&gt;
&lt;br /&gt;
The mysql PHP extension was deprecated when PHP 5.5 was released in June 2013&amp;lt;ref&amp;gt;http://php.net/ChangeLog-5.php#5.5.0&amp;lt;/ref&amp;gt; and is scheduled to be removed in PHP 7&amp;lt;ref&amp;gt;https://wiki.php.net/rfc/remove_deprecated_functionality_in_php7&amp;lt;/ref&amp;gt;. WHMCS 6.0 introduces a new database connection and library to ensure compatibility with modern PHP environments and best practices.&lt;br /&gt;
&lt;br /&gt;
==New functionality==&lt;br /&gt;
&lt;br /&gt;
WHMCS 6.0 incorporates the Laravel framework 4.1's database component. This library includes a Database Abstraction Layer (DBAL) called &amp;quot;Capsule&amp;quot; and an Object Relational Mapping (ORM) library called &amp;quot;Eloquent&amp;quot;. The new DBAL is based on the PHP Data Objects (PDO MySQL) extension and uses WHMCS's existing &amp;lt;tt&amp;gt;configuration.php&amp;lt;/tt&amp;gt; file. No configuration file changes are required to use the new database connection.&lt;br /&gt;
&lt;br /&gt;
The Capsule DBAL component introduces two libraries to WHMCS, a query manager for running database queries and a schema manager for an abstracted API to table management. Capsule's underlying PDO connection is also available for advanced database usage. Capsule has three static methods to get to these components:&lt;br /&gt;
&lt;br /&gt;
* '''Capsule::table(string $tableName)''': Access the query manager for the given table.&lt;br /&gt;
* '''Capsule::schema()''': Access the schema manager for the WHMCS database. &lt;br /&gt;
* '''Capsule::connection()''': Access the connection manager to interact with the underlying database connection.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' WHMCS 6.0 makes two connections to the database. One connection is made through the legacy mysql extension to handle existing hooks, modules, and other customizations. The other connection is made by PDO to drive new DBAL and model based functionality in the program. &lt;br /&gt;
&lt;br /&gt;
==Deprecated functionality==&lt;br /&gt;
&lt;br /&gt;
The current [[SQL Helper Functions]] are present in WHMCS 6.0 and above, but are now deprecated and may be removed in a later version of the product:&lt;br /&gt;
* '''select_query()'''&lt;br /&gt;
* '''update_query()'''&lt;br /&gt;
* '''insert_query()'''&lt;br /&gt;
* '''full_query()'''&lt;br /&gt;
&lt;br /&gt;
The mysql extension driven database connection is now deprecated and may be discontinued in a later version of the product. WHMCS encourages all third party developers to use the Capsule DBAL and PDO connection for all new database interaction.&lt;br /&gt;
&lt;br /&gt;
=Using Capsule=&lt;br /&gt;
&lt;br /&gt;
Declare an alias to Laravel's database manager in your project file's &amp;lt;tt&amp;gt;use&amp;lt;/tt&amp;gt; block to access Capsule:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
use Illuminate\Database\Capsule\Manager as Capsule;&lt;br /&gt;
&lt;br /&gt;
// Run queries or modify tables as you like.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==The Query Manager==&lt;br /&gt;
&lt;br /&gt;
: ''Please see [https://laravel.com/docs/5.2/queries Laravel's query documentation] for more information.''&lt;br /&gt;
&lt;br /&gt;
The '''Capsule::table(string $tableName)''' method provides access to the query manager. Declare it with the name of the table you wish to query as it's first parameter to interact with that table. The query manager has a wide range of functionality to perform advanced select, join, insert, update, and delete statements. Capsule's select calls return rows as ''stdClass'' objects.&lt;br /&gt;
&lt;br /&gt;
Capsule escapes all input, so it is not necessary to add escaping slashes to variables passed to these methods.&lt;br /&gt;
&lt;br /&gt;
All of Capsule's methods throw an exception on failure. Please place Capusle calls in &amp;lt;tt&amp;gt;try&amp;lt;/tt&amp;gt;/&amp;lt;tt&amp;gt;catch&amp;lt;/tt&amp;gt; blocks for graceful error handling and to avoid potential fatal errors in your hook, module, or other customization.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
use Illuminate\Database\Capsule\Manager as Capsule;&lt;br /&gt;
&lt;br /&gt;
// Print all client first names using a simple select.&lt;br /&gt;
&lt;br /&gt;
/** @var stdClass $client */&lt;br /&gt;
foreach (Capsule::table('tblclients')-&amp;gt;get() as $client) {&lt;br /&gt;
    echo $client-&amp;gt;firstname . PHP_EOL;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Rename all clients named &amp;quot;John Deo&amp;quot; to &amp;quot;John Doe&amp;quot; using an update statement. &lt;br /&gt;
try {&lt;br /&gt;
    $updatedUserCount = Capsule::table('tblclients')&lt;br /&gt;
        -&amp;gt;where('firstname', 'John')&lt;br /&gt;
        -&amp;gt;where('lastname', 'Deo')&lt;br /&gt;
        -&amp;gt;update(&lt;br /&gt;
            [&lt;br /&gt;
                'lastname' =&amp;gt; 'Doe',&lt;br /&gt;
            ]&lt;br /&gt;
        );&lt;br /&gt;
&lt;br /&gt;
    echo &amp;quot;Fixed {$updatedUserCount} misspelled last names.&amp;quot;;&lt;br /&gt;
} catch (\Exception $e) {&lt;br /&gt;
    echo &amp;quot;I couldn't update client names. {$e-&amp;gt;getMessage()}&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==The Schema Manager==&lt;br /&gt;
&lt;br /&gt;
Use the '''Capsule::schema()''' method to access the schema manager to modify table schema if necessary. The schema manager has support for creating, dropping and truncating tables and for modifying columns, indexes, and keys. &lt;br /&gt;
&lt;br /&gt;
'''Note''': WHMCS does not recommend changing default table schema as that can affect product functionality.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
use Illuminate\Database\Capsule\Manager as Capsule;&lt;br /&gt;
&lt;br /&gt;
// Create a new table.&lt;br /&gt;
try {&lt;br /&gt;
    Capsule::schema()-&amp;gt;create(&lt;br /&gt;
        'my_table',&lt;br /&gt;
        function ($table) {&lt;br /&gt;
            /** @var \Illuminate\Database\Schema\Blueprint $table */&lt;br /&gt;
            $table-&amp;gt;increments('id');&lt;br /&gt;
            $table-&amp;gt;string('name');&lt;br /&gt;
            $table-&amp;gt;integer('serial_number');&lt;br /&gt;
            $table-&amp;gt;boolean('is_required');&lt;br /&gt;
            $table-&amp;gt;timestamps();&lt;br /&gt;
        }&lt;br /&gt;
    );&lt;br /&gt;
} catch (\Exception $e) {&lt;br /&gt;
    echo &amp;quot;Unable to create my_table: {$e-&amp;gt;getMessage()}&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==The Connection Manager==&lt;br /&gt;
&lt;br /&gt;
The '''Capsule::connection()''' method provides low-level access to the database connection itself. Use it to initiate transactions with automatic commit and rollback or to access the underlying PDO connection to perform manual database queries outside the DBAL. The connection manager also has methods to retrieve query and schema managers.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
use Illuminate\Database\Capsule\Manager as Capsule;&lt;br /&gt;
&lt;br /&gt;
// Perform potentially risky queries in a transaction for easy rollback.&lt;br /&gt;
try {&lt;br /&gt;
    Capsule::connection()-&amp;gt;transaction(&lt;br /&gt;
        function ($connectionManager)&lt;br /&gt;
        {&lt;br /&gt;
            /** @var \Illuminate\Database\Connection $connectionManager */&lt;br /&gt;
            $connectionManager-&amp;gt;table('my_table')-&amp;gt;insert(&lt;br /&gt;
                [&lt;br /&gt;
                    'name' =&amp;gt; $_POST['name'],&lt;br /&gt;
                    'serial_number' =&amp;gt; $_POST['serialNumber'],&lt;br /&gt;
                    'is_required' =&amp;gt; (int)(bool) $_POST['isRequired'],&lt;br /&gt;
                ]&lt;br /&gt;
            );&lt;br /&gt;
        }&lt;br /&gt;
    );&lt;br /&gt;
} catch (\Exception $e) {&lt;br /&gt;
    echo &amp;quot;Uh oh! Inserting didn't work, but I was able to rollback. {$e-&amp;gt;getMessage()}&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Getting to PDO===&lt;br /&gt;
&lt;br /&gt;
Use the connection manager's '''getPdo()''' method to retrieve the underlying PDO connection instance. Use the PDO connection to perform manual queries and advanced database usage.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
use Illuminate\Database\Capsule\Manager as Capsule;&lt;br /&gt;
&lt;br /&gt;
// Perform potentially risky queries in a transaction for easy rollback.    &lt;br /&gt;
$pdo = Capsule::connection()-&amp;gt;getPdo();&lt;br /&gt;
$pdo-&amp;gt;beginTransaction();&lt;br /&gt;
&lt;br /&gt;
try {&lt;br /&gt;
    $statement = $pdo-&amp;gt;prepare(&lt;br /&gt;
        'insert into my_table (name, serial_number, is_required) values (:name, :serialNumber, :isRequired)'&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    $statement-&amp;gt;execute(&lt;br /&gt;
        [&lt;br /&gt;
            ':name' =&amp;gt; $_POST['name'],&lt;br /&gt;
            ':serialNumber' =&amp;gt; $_POST['serialNumber'],&lt;br /&gt;
            ':isRequired' =&amp;gt; (bool) $_POST['isRequired'],&lt;br /&gt;
        ]&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    $pdo-&amp;gt;commit();&lt;br /&gt;
} catch (\Exception $e) {&lt;br /&gt;
    echo &amp;quot;Uh oh! {$e-&amp;gt;getMessage()}&amp;quot;;&lt;br /&gt;
    $pdo-&amp;gt;rollBack();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Troubleshooting=&lt;br /&gt;
&lt;br /&gt;
==Exceptions==&lt;br /&gt;
&lt;br /&gt;
All Capsule methods throw an exception on failure. Catch these exceptions and analyze their messages and stack traces to help determine the nature of the failure. WHMCS recommends placing all database interactivity in &amp;lt;tt&amp;gt;try&amp;lt;/tt&amp;gt;/&amp;lt;tt&amp;gt;catch&amp;lt;/tt&amp;gt; blocks for graceful error handling.&lt;br /&gt;
&lt;br /&gt;
==The Capsule Query Log==&lt;br /&gt;
&lt;br /&gt;
The connection manager's '''getQueryLog()''' method returns an array of all queries made during the life of the page request. Queries are stored in the log as an array containing the query run, the parameter bindings passed to the query, and the time it took for the query to execute, measured in milliseconds.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
use Illuminate\Database\Capsule\Manager as Capsule;&lt;br /&gt;
&lt;br /&gt;
// Loop through each Capsule query made during the page request.&lt;br /&gt;
foreach (Capsule::connection()-&amp;gt;getQueryLog() as $query) {&lt;br /&gt;
    echo &amp;quot;Query: {$query['query']}&amp;quot; . PHP_EOL;&lt;br /&gt;
    echo &amp;quot;Execution Time: {$query['time']}ms&amp;quot; . PHP_EOL;&lt;br /&gt;
    echo &amp;quot;Parameters: &amp;quot; . PHP_EOL;&lt;br /&gt;
&lt;br /&gt;
    foreach ($query['bindings'] as $key =&amp;gt; $value) {&lt;br /&gt;
        echo &amp;quot;{$key} =&amp;gt; {$value}&amp;quot; . PHP_EOL;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==The WHMCS Activity Log==&lt;br /&gt;
&lt;br /&gt;
All uncaught PDO-based query failures, including those made by Capsule and manual PDO queries, are written to to the WHMCS activity log. View the system activity log to view the details of these failed queries.&lt;br /&gt;
&lt;br /&gt;
=See Also=&lt;br /&gt;
* [[SQL Helper Functions]] (functional, but deprecated in WHMCS 6.0)&lt;br /&gt;
&lt;br /&gt;
=External Links=&lt;br /&gt;
* [http://laravel.com/docs/4.2/queries Query Builder - Laravel 4.2]&lt;br /&gt;
* [http://laravel.com/docs/4.2/schema Schema Builder - Laravel 4.2]&lt;br /&gt;
* [http://php.net/manual/en/book.pdo.php PHP: PDO]&lt;br /&gt;
&lt;br /&gt;
=References=&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Nicolas</name></author>	</entry>

	<entry>
		<id>http://3.19.219.109/index.php?title=Client_Email_Verification&amp;diff=18247</id>
		<title>Client Email Verification</title>
		<link rel="alternate" type="text/html" href="http://3.19.219.109/index.php?title=Client_Email_Verification&amp;diff=18247"/>
				<updated>2016-03-08T16:27:17Z</updated>
		
		<summary type="html">&lt;p&gt;Nicolas: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Email Verification''' is an optional feature which allows admins to request that users confirm their email addresses on signup or change of email address.  This adds a layer of security when manually accepting client orders, as well as ensuring that correct information is provided.  To enable email verification, navigate to ''Setup &amp;gt;&amp;gt; General Settings &amp;gt;&amp;gt; Security tab''.  Tick the '''Email Verification''' checkbox and save the changes. &lt;br /&gt;
&lt;br /&gt;
[[File:Enable_email_verification.png|center|850x250px|Enable email verification in general settings]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
When viewing the '''Client Profile''' page, a warning banner displays notifying admins if that specific client has an unverified email address on file.  By clicking the '''Resend Verification Email''' button, a new verification email is sent to the client, which contains a link that is valid for 24 hours and invalidates the previous link.  No banner will display after the client has verified their email address.  A similar banner displays on the Manage Orders page, with the same option to resend the verification email, advising the admin when the email address on file has not been verified.&lt;br /&gt;
&lt;br /&gt;
[[File:Client_profile_verification_banner.png|400x150px|Client profile verification banner]]&lt;br /&gt;
[[File:Manage_orders_verification_banner.png|400x150px|Manage orders client verification status]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A badge will also display alongside the client's email address throughout the admin backend denoting whether the client's email address is verified or not.&lt;br /&gt;
[[File:Unverified_badge.png|right|400x250px|Unverified email badge]]&lt;br /&gt;
[[File:Verified_badge.png|400x250px|Verified email badge]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The client will be able to log into their account associated with the unverified email address, however, a banner reminding them to take action will display, as well as the '''Resend Verification Email''' button.  No functionality is limited in the client area for clients with an unverified email address.&lt;br /&gt;
&lt;br /&gt;
[[File:Client_verification_banner.png|center|850x250px|Email verification banner on client side]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Clicking the '''Resend Verification Email''' button sends an email with a link that is valid for 24 hours.  If the link is followed after the 24 hour window or if the button is clicked (which invalidates the previous link), then an error will display when the client tries to log in, but they will be allowed to generate and send a new email once they authenticate.&lt;br /&gt;
&lt;br /&gt;
[[File:Expired_verification_warning.png|200x150px|Expired verification key warning]][[File:Expired_verification_banner.png|400x150px|Expired verification key banner]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Upon the client following the link sent in the verification email, the client will be required to log into the client area.  Even if the client is already logged in, they will be required to re-authenticate.  Once logged in, the client will see a success message on the first page.&lt;br /&gt;
&lt;br /&gt;
[[File:Verified_banner.png|850x250px|Verified email successfully]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In the admin area, the email verification banner will no longer be present and a Verified badge will display alongside the client's email address. &lt;br /&gt;
&lt;br /&gt;
[[File:Verified_client_profile.png|850x250px|Verified email in client profile view]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Changing of the email address, whether via the admin interface or in the client area will cause the email verification banner and Unverified badge to re-appear.&lt;br /&gt;
&lt;br /&gt;
'''Email Verification''' is a useful optional feature which assists admins in judging whether to manually accept an order and encourages correct information from clients.  While no functionality is limited in the client area for clients with unverified email addresses, the verification email's link is masked when viewing email history in the client area.  The link is not masked when viewing the email from the admin area.&lt;/div&gt;</summary>
		<author><name>Nicolas</name></author>	</entry>

	<entry>
		<id>http://3.19.219.109/index.php?title=Gateway_Module_Developer_Docs&amp;diff=17566</id>
		<title>Gateway Module Developer Docs</title>
		<link rel="alternate" type="text/html" href="http://3.19.219.109/index.php?title=Gateway_Module_Developer_Docs&amp;diff=17566"/>
				<updated>2016-01-06T20:50:50Z</updated>
		
		<summary type="html">&lt;p&gt;Nicolas: /* App Store */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Creating a gateway module allows you to connect WHMCS to third party payment and credit card processors that aren’t natively supported in WHMCS as standard.&lt;br /&gt;
&lt;br /&gt;
There are 2 core types of gateway module:&lt;br /&gt;
&lt;br /&gt;
#'''Third Party Gateways''' – this is where the customer leaves your site to pay and is returned once the payment process is completed&lt;br /&gt;
#'''Merchant Gateways''' – this is where the customer enters credit card details directly on your website and the payment is then processed in the background (can also include 3D Secure where the user leaves your site)&lt;br /&gt;
&lt;br /&gt;
{{Developer_Links}}&lt;br /&gt;
&lt;br /&gt;
So the first decision you need to make before starting your module for WHMCS is which type of gateway module you will be creating.  Once you have that, you're ready to begin.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Introduction==&lt;br /&gt;
&lt;br /&gt;
Gateway modules allow a connection between WHMCS and gateways or credit card processors that aren't natively supported in WHMCS.&lt;br /&gt;
&lt;br /&gt;
This documentation will explain the module's structure and contains everything needed in order to successfully create a gateway module for WHMCS.&lt;br /&gt;
&lt;br /&gt;
==Getting Started==&lt;br /&gt;
&lt;br /&gt;
To get started, begin by downloading the module development kit from our GitHub site. There are two sample modules available, depending upon the [[#Module Type|type of gateway]] being developed:&lt;br /&gt;
*Third Party Gateway: https://github.com/WHMCS/sample-gateway-module&lt;br /&gt;
*Merchant Gateway: https://github.com/WHMCS/sample-merchant-gateway&lt;br /&gt;
Take the gateway module template &amp;quot;template.php&amp;quot; from this download and rename it to &amp;quot;yourgatewayname.php&amp;quot;.  It should be all lowercase and must start with a letter.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;docs-alert-info&amp;quot;&amp;gt;&lt;br /&gt;
All functions within a gateway module must be prefixed with the filename.  Open the file and replace all occurrences of '''template_''' with '''yougatewayname_'''&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Config Array===&lt;br /&gt;
&lt;br /&gt;
'''Configure the yourgatewayname_config array'''. This function is the primary function required by all gateway modules and defines both the friendly display name for the module and any custom fields/options/settings that the gateway module requires.&lt;br /&gt;
&lt;br /&gt;
The available field types are &amp;quot;text&amp;quot;, &amp;quot;dropdown&amp;quot;, &amp;quot;textarea&amp;quot; and &amp;quot;yesno&amp;quot; (checkboxes).   The sample config array in &amp;quot;template.php&amp;quot; demonstrates how to use each of these types. &lt;br /&gt;
&lt;br /&gt;
The general formula:&lt;br /&gt;
#Specify a system name (''all in lowercase for the setting to be referenced by in the module code itself'')&lt;br /&gt;
#A FriendlyName&lt;br /&gt;
#Type&lt;br /&gt;
#Any settings specific to that field type.&lt;br /&gt;
&lt;br /&gt;
Any fields defined here will be available in all gateway module functions in the $params array, so avoid common names like currency, invoiceid, etc, as these will conflict with the standard variables.&lt;br /&gt;
&lt;br /&gt;
===Module Type===&lt;br /&gt;
&lt;br /&gt;
Determine which type of module needs to be created from the 2 core types:&lt;br /&gt;
&lt;br /&gt;
#'''Third Party Gateways''' – the customer leaves your site to pay and is returned once the payment process is completed.&lt;br /&gt;
#'''Merchant Gateways''' – where the customer enters credit card details directly on your website and the payment is then processed in the background (can also include 3D Secure where the user leaves your site).&lt;br /&gt;
&lt;br /&gt;
For a Third Party gateway go to [[#Third_Party_Gateway]], and for a merchant gateway go to [[#Merchant_Gateway]].&lt;br /&gt;
&lt;br /&gt;
==Third Party Gateway==&lt;br /&gt;
&lt;br /&gt;
Follow the steps below to create a third party gateway module (one where the customer leaves your site to make the payment on the gateway provider's website):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;docs-alert-warning&amp;quot;&amp;gt;The '''_capture''' function must be deleted before activating the new gateway module in WHMCS.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# Delete the '''_capture''' function from the module template.&lt;br /&gt;
# Enter the gateway-specific code for taking the user to the payment process within the _link function.  An example of this step is shown in the gateway module template supplied with the dev kit.  Normally, the code output by this function is the HTML for a '''&amp;lt;form&amp;gt;''' with a ''post'' method.&lt;br /&gt;
&lt;br /&gt;
The available variables are:&lt;br /&gt;
&lt;br /&gt;
===Invoice Variables===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['invoiceid'] # Invoice ID Number&lt;br /&gt;
$params['description'] # Description (eg. Company Name - Invoice #xxx)&lt;br /&gt;
$params['amount'] # Format: xxx.xx&lt;br /&gt;
$params['currency'] # Currency Code (eg. GBD, USD, etc...)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Client Variables===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['clientdetails']['firstname'] # Clients First Name&lt;br /&gt;
$params['clientdetails']['lastname'] # Clients Last Name&lt;br /&gt;
$params['clientdetails']['email'] # Clients Email Address&lt;br /&gt;
$params['clientdetails']['address1'] # Clients Address&lt;br /&gt;
$params['clientdetails']['address2'] &lt;br /&gt;
$params['clientdetails']['city']&lt;br /&gt;
$params['clientdetails']['state']&lt;br /&gt;
$params['clientdetails']['postcode']&lt;br /&gt;
$params['clientdetails']['country']&lt;br /&gt;
$params['clientdetails']['phonenumber']&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===System Variables===&lt;br /&gt;
&amp;lt;source lang = &amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['companyname'] # your Company Name setting in WHMCS&lt;br /&gt;
$params['systemurl'] # the url to the Client Area&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# The processing of a payment is handled by a callback file separate from the module (see page 9 for more information).&lt;br /&gt;
# If your gateway provider doesn't support automated refunds or you won't be including them in the module, then delete the '''_refund''' function.  Otherwise, refer to the Refund section on page 7.&lt;br /&gt;
&lt;br /&gt;
==Merchant Gateway==&lt;br /&gt;
&lt;br /&gt;
A merchant gateway module is a module where the customer enters their card details directly via the client area, without leaving the site.  To create one:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;docs-alert-warning&amp;quot;&amp;gt;&lt;br /&gt;
The '''_link''' function must be deleted before activating the new gateway module in WHMCS.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# Delete the '''_link''' function from the module template.&lt;br /&gt;
# Enter the gateway-specific code for processing the payment into the '''_capture''' function.  This normally takes the format of an HTTP/Curl request to the gateway provider's API.&lt;br /&gt;
&lt;br /&gt;
The variables available are:&lt;br /&gt;
&lt;br /&gt;
===Invoice Variables===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['invoiceid'] # Invoice ID Number&lt;br /&gt;
$params['description'] # Description (eg. Company Name - Invoice #xxx)&lt;br /&gt;
$params['amount'] # Format: xxx.xx&lt;br /&gt;
$params['currency'] # Currency Code (eg. GBP, USD, etc...)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Client Variables===&lt;br /&gt;
&amp;lt;source lang = &amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['clientdetails']['firstname'] # Clients First Name&lt;br /&gt;
$params['clientdetails']['lastname'] # Clients Last Name&lt;br /&gt;
$params['clientdetails']['email'] # Clients Email Address&lt;br /&gt;
$params['clientdetails']['address1'] # Clients Address&lt;br /&gt;
$params['clientdetails']['address2']&lt;br /&gt;
$params['clientdetails']['city']&lt;br /&gt;
$params['clientdetails']['state']&lt;br /&gt;
$params['clientdetails']['postcode']&lt;br /&gt;
$params['clientdetails']['country']&lt;br /&gt;
$params['clientdetails']['phonenumber']&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===System Variables===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['companyname'] # your Company Name setting in WHMCS&lt;br /&gt;
$params['systemurl'] # the url to the Client Area&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Card Details===&lt;br /&gt;
&amp;lt;source lang = &amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['cardtype'] # the Card Type (Visa, MasterCard, etc…)&lt;br /&gt;
$params['cardnum'] # the Card Number&lt;br /&gt;
$params['cardexp'] # the Card’s Expiry Date (Format: MMYY)&lt;br /&gt;
$params['cardstart'] # the Card’s Start Date (Format: MMYY)&lt;br /&gt;
$params['cardissuenum'] # the Card’s Issue Number (Switch/Solo Cards)&lt;br /&gt;
$params['cccvv'] # Not always present (recurring transactions)&lt;br /&gt;
# but would always be present for client initiated attempts&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# Once the transaction has been processed and a response has been received, an array with the results needs to be returned to WHMCS.   For a successful capture, use the following format:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
return array(&lt;br /&gt;
    &amp;quot;status&amp;quot; =&amp;gt; &amp;quot;success&amp;quot;,&lt;br /&gt;
    &amp;quot;transid&amp;quot; =&amp;gt; $results[&amp;quot;transid&amp;quot;],&lt;br /&gt;
    &amp;quot;rawdata&amp;quot; =&amp;gt; $results,&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# The status index ''must be'' '''success''' to tell WHMCS that the capture was successful.  &lt;br /&gt;
# The transid index should be passed the value of the transaction ID that came back from the gateway.&lt;br /&gt;
# The rawdata index should be passed an array of the data returned from the gateway to be stored in the WHMCS Gateway Log.&lt;br /&gt;
&lt;br /&gt;
If the transaction were to fail, use the following format:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
return array(&lt;br /&gt;
    &amp;quot;status&amp;quot; =&amp;gt; &amp;quot;declined&amp;quot;,&lt;br /&gt;
    &amp;quot;rawdata&amp;quot; =&amp;gt; $results,&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# The status index can be any value (''declined, error, invalid hash, etc'').  This value is displayed as the reason for failure, in the gateway log.&lt;br /&gt;
# The rawdata index should be passed an array of the data returned from the gateway to be stored in the WHMCS Gateway Log for debugging purposes.&lt;br /&gt;
&lt;br /&gt;
If the gateway supports 3D Secure (Verified by Visa or MasterCard Secure Code) then please refer to page 8.&lt;br /&gt;
&lt;br /&gt;
===Refunds===&lt;br /&gt;
&lt;br /&gt;
# If the gateway provider supports automated refunds, then code for processing a refund goes into the '''_refund''' function.  This is passed all of the same variables as the '''_capture''' function, but with an added transaction id:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['transid'] # the transaction ID of the original transaction to be refunded&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The return arrays for a success or failure should be done exactly the same as described above for the '''_capture''' function.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;docs-alert-danger&amp;quot;&amp;gt;&lt;br /&gt;
If the gateway provider does not support refunds, then the '''_refund''' function should be deleted from the module file.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Callbacks==&lt;br /&gt;
If the gateway provider supports notifying a script when a payment is successful, then a callback file can be created to detect and apply those calls as payments inside WHMCS.&lt;br /&gt;
&lt;br /&gt;
A sample callback file is included in the dev kit for this purpose named '''callback.php''':&lt;br /&gt;
&lt;br /&gt;
# Rename it to match the gateway module.&lt;br /&gt;
# Modify the variables within it, as per the comments in the code.&lt;br /&gt;
# Modify it to match the variables that the specific gateway returns.&lt;br /&gt;
&lt;br /&gt;
These are some helper functions within the sample:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$GATEWAY = getGatewayVariables(‘yourgatewayname’);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function can be used to retrieve the configuration data for the module as specified in&lt;br /&gt;
the '''_config''' array. For example, it might be needed to get a gateway username or secret key to&lt;br /&gt;
validate a callback.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$invoiceid = checkCbInvoiceID($invoiceid, $GATEWAY[‘name’]);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function can be used to check that the invoice ID received back is valid. Pass the $invoiceid and the gateway name into the function.  If the invoice number is valid, the script will continue executing.  Otherwise, the script will be halted and an appropriate gateway log entry will be created.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang =&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
checkCbTransID($transid);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function can be used to check for any existing transactions already recorded for a given transaction ID, which protects against duplicate callbacks.  If the transaction ID is already in the database, the callback script execution will be halted.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
logTransaction($GATEWAY[‘name’], $_POST, &amp;quot;Successful&amp;quot;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function can be used to create a gateway log entry. The first variable needs to be the name of the gateway module, the second should be an array of data, such as the '''$_POST''' or '''$_REQUEST''' super globals, and the last variable should be the result or status to show in the log.&lt;br /&gt;
&lt;br /&gt;
== 3D Secure Process ==&lt;br /&gt;
&lt;br /&gt;
If the merchant gateway supports 3D Secure (also known as ''Verified by Visa'' or ''MasterCard Secure Code''), then it can be utilized within WHMCS.&lt;br /&gt;
&lt;br /&gt;
# Add a function to the module named '''yourgatewayname_3dsecure''' &lt;br /&gt;
# Return the HTML for the '''&amp;lt;form&amp;gt;''' post method to take the user to the 3D Secure process. &lt;br /&gt;
&lt;br /&gt;
An example of this is below:&lt;br /&gt;
&lt;br /&gt;
The '''_3dsecure''' function is passed all the same variables that the '''_capture''' function is (see page 6). The return url should be a callback file to handle the response (see page 9).&lt;br /&gt;
&lt;br /&gt;
==Example==&lt;br /&gt;
&amp;lt;source lang = &amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
function yourgatewayname_3dsecure($params) {&lt;br /&gt;
$code = '&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;https://www.gateway.com/3dsecure/&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;gwlogin&amp;quot; value=&amp;quot;'.$params[&amp;quot;loginid&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;invoiceid&amp;quot; value=&amp;quot;'.$params[&amp;quot;invoiceid&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;amount&amp;quot; value=&amp;quot;'. $params[&amp;quot;amount&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;firstname&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;firstname&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;lastname&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;lastname&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;address&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;address1&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;city&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;city&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;state&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;state&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;postcode&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;postcode&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;country&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;country&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;phonenumber&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;phonenumber&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;email&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;email&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;ccnumber&amp;quot; value=&amp;quot;'. $params[&amp;quot;cardnum&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;expirymonth&amp;quot; value=&amp;quot;'.substr($params['cardexp'],0,2).'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;expiryyear&amp;quot; value=&amp;quot;'.substr($params['cardexp'],2,2).'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;cvv2&amp;quot; value=&amp;quot;'. $params[&amp;quot;cccvv&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;return_url&amp;quot; value=&amp;quot;'.&lt;br /&gt;
$params['systemurl'].'/modules/gateways/callback/yourgatewayname.php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;noscript&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;errorbox&amp;quot;&amp;gt;&amp;lt;b&amp;gt;JavaScript is currently disabled or is not supported by your&lt;br /&gt;
browser.&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Please click the continue button to proceed with the processing of your&lt;br /&gt;
transaction.&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Continue &amp;gt;&amp;gt;&amp;quot; /&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/noscript&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;';&lt;br /&gt;
      return $code;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Tokenised Remote Storage==&lt;br /&gt;
&lt;br /&gt;
With the increasing rules &amp;amp; requirements surrounding the storing of credit card details, many merchant gateways are offering services where repeat rebills can be performed without needing to store credit card details locally, on the system.  Gateway modules can utilize this functionality:&lt;br /&gt;
&lt;br /&gt;
The basic logic behind token gateways in WHMCS is that clients must either have a credit card number or a token stored in order for recurring billing to be attempted. So if you create a function named '''_storeremote''' in your custom gateway module, this function will then override the default local storage when new credit card details are entered. And instead of&lt;br /&gt;
saving in the database, that function then needs to communicate with the gateways API, and return the token that gets assigned to WHMCS.&lt;br /&gt;
&lt;br /&gt;
The variables passed into the '''_storeremote''' function are as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang =&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['gatewayid'] # the token stored for the client&lt;br /&gt;
$params['cardtype'] #the Card Type (Visa, MasterCard, etc…)&lt;br /&gt;
$params['cardnum'] # the Card Number&lt;br /&gt;
$params['cardexp'] # the Card’s Expiry Date (Format: MMYY)&lt;br /&gt;
$params['cardstart'] # the Card’s Start Date (Format: MMYY)&lt;br /&gt;
$params['cardissuenum'] # the Card’s Issue Number (Switch/Solo Cards)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
On the first call, the gatewayid will be empty. So when empty you need to create a new profile at the gateway. On subsequent calls the gatewayid that was originally created and stored will be passed in and the existing profile simply needs to be updated. And if the cardnum variable is empty, this indicates that deleting/removal of the stored credit card&lt;br /&gt;
details has been requested.&lt;br /&gt;
&lt;br /&gt;
Once the card details have been updated or stored remotely, return either a success or failure response to tell WHMCS if it worked, and if it did, the token that has been assigned:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang =&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
return array(&lt;br /&gt;
    &amp;quot;status&amp;quot; =&amp;gt; &amp;quot;success&amp;quot;,&lt;br /&gt;
    &amp;quot;gatewayid&amp;quot; =&amp;gt; $results[&amp;quot;token&amp;quot;],&lt;br /&gt;
    &amp;quot;rawdata&amp;quot; =&amp;gt; $results,&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
return array(&lt;br /&gt;
    &amp;quot;status&amp;quot; =&amp;gt; &amp;quot;failed&amp;quot;,&lt;br /&gt;
    &amp;quot;rawdata&amp;quot; =&amp;gt; $results,&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When this function exists in a gateway module, WHMCS will only store the card type, expiry date and the last 4 digits locally in the database. So you and your clients will still be able to see exactly what card is stored remotely from within WHMCS.&lt;br /&gt;
&lt;br /&gt;
Then within the capture function, instead of $params[‘cardnum’] you will be passed $params[‘gatewayid’] with which to perform the capture.&lt;br /&gt;
&lt;br /&gt;
==Installation &amp;amp; Activation==&lt;br /&gt;
&lt;br /&gt;
To install the new module, upload it to the '''/modules/gateways/''' folder and then go to ''Setup'' &amp;gt; ''Payment Gateways'' to activate. If there is a callback file,  then that should be uploaded to the '''/modules/gateways/callback/''' folder.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;docs-alert-warning&amp;quot;&amp;gt;&lt;br /&gt;
'''Important:''' It is important that the gateway is not activated until step 1 has been completed for both the third party gateway or the merchant gateway modules, because the type of module created is stored in the database upon activation.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Blank Screen/Errors==&lt;br /&gt;
&lt;br /&gt;
If there is a blank page or error within the ''Setup'' &amp;gt; ''Payment Gateways'' page after uploading the new module file, then there is a syntax error within the new code. To debug that, add the following line to the '''configuration.php''' file to turn on error reporting:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$display_errors = true;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This enables PHP error reporting and should show the cause of any issues. Remove this line once testing has completed.&lt;br /&gt;
&lt;br /&gt;
==App Store==&lt;br /&gt;
WHMCS offers an app store in which completed gateway modules can be submitted.  The listings are displayed under the Addons tab within the administration area and online at http://www.whmcs.com/appstore . This is a great way to make WHMCS users aware of your module!&lt;br /&gt;
&lt;br /&gt;
In order to submit a listing you'll need a login for whmcs.com/members, if you do not have one please [https://www.whmcs.com/members/submitticket.php?step=2&amp;amp;deptid=5 Contact Us]. Once logged in, visit the app store page at the above URL and click the &amp;quot;Submit your Addon&amp;quot; link. We aim to review submissions in 1-2 weeks.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Developer_Links}}&lt;/div&gt;</summary>
		<author><name>Nicolas</name></author>	</entry>

	<entry>
		<id>http://3.19.219.109/index.php?title=Gateway_Module_Developer_Docs&amp;diff=17562</id>
		<title>Gateway Module Developer Docs</title>
		<link rel="alternate" type="text/html" href="http://3.19.219.109/index.php?title=Gateway_Module_Developer_Docs&amp;diff=17562"/>
				<updated>2016-01-06T20:49:54Z</updated>
		
		<summary type="html">&lt;p&gt;Nicolas: /* Blank Screen/Errors */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Creating a gateway module allows you to connect WHMCS to third party payment and credit card processors that aren’t natively supported in WHMCS as standard.&lt;br /&gt;
&lt;br /&gt;
There are 2 core types of gateway module:&lt;br /&gt;
&lt;br /&gt;
#'''Third Party Gateways''' – this is where the customer leaves your site to pay and is returned once the payment process is completed&lt;br /&gt;
#'''Merchant Gateways''' – this is where the customer enters credit card details directly on your website and the payment is then processed in the background (can also include 3D Secure where the user leaves your site)&lt;br /&gt;
&lt;br /&gt;
{{Developer_Links}}&lt;br /&gt;
&lt;br /&gt;
So the first decision you need to make before starting your module for WHMCS is which type of gateway module you will be creating.  Once you have that, you're ready to begin.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Introduction==&lt;br /&gt;
&lt;br /&gt;
Gateway modules allow a connection between WHMCS and gateways or credit card processors that aren't natively supported in WHMCS.&lt;br /&gt;
&lt;br /&gt;
This documentation will explain the module's structure and contains everything needed in order to successfully create a gateway module for WHMCS.&lt;br /&gt;
&lt;br /&gt;
==Getting Started==&lt;br /&gt;
&lt;br /&gt;
To get started, begin by downloading the module development kit from our GitHub site. There are two sample modules available, depending upon the [[#Module Type|type of gateway]] being developed:&lt;br /&gt;
*Third Party Gateway: https://github.com/WHMCS/sample-gateway-module&lt;br /&gt;
*Merchant Gateway: https://github.com/WHMCS/sample-merchant-gateway&lt;br /&gt;
Take the gateway module template &amp;quot;template.php&amp;quot; from this download and rename it to &amp;quot;yourgatewayname.php&amp;quot;.  It should be all lowercase and must start with a letter.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;docs-alert-info&amp;quot;&amp;gt;&lt;br /&gt;
All functions within a gateway module must be prefixed with the filename.  Open the file and replace all occurrences of '''template_''' with '''yougatewayname_'''&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Config Array===&lt;br /&gt;
&lt;br /&gt;
'''Configure the yourgatewayname_config array'''. This function is the primary function required by all gateway modules and defines both the friendly display name for the module and any custom fields/options/settings that the gateway module requires.&lt;br /&gt;
&lt;br /&gt;
The available field types are &amp;quot;text&amp;quot;, &amp;quot;dropdown&amp;quot;, &amp;quot;textarea&amp;quot; and &amp;quot;yesno&amp;quot; (checkboxes).   The sample config array in &amp;quot;template.php&amp;quot; demonstrates how to use each of these types. &lt;br /&gt;
&lt;br /&gt;
The general formula:&lt;br /&gt;
#Specify a system name (''all in lowercase for the setting to be referenced by in the module code itself'')&lt;br /&gt;
#A FriendlyName&lt;br /&gt;
#Type&lt;br /&gt;
#Any settings specific to that field type.&lt;br /&gt;
&lt;br /&gt;
Any fields defined here will be available in all gateway module functions in the $params array, so avoid common names like currency, invoiceid, etc, as these will conflict with the standard variables.&lt;br /&gt;
&lt;br /&gt;
===Module Type===&lt;br /&gt;
&lt;br /&gt;
Determine which type of module needs to be created from the 2 core types:&lt;br /&gt;
&lt;br /&gt;
#'''Third Party Gateways''' – the customer leaves your site to pay and is returned once the payment process is completed.&lt;br /&gt;
#'''Merchant Gateways''' – where the customer enters credit card details directly on your website and the payment is then processed in the background (can also include 3D Secure where the user leaves your site).&lt;br /&gt;
&lt;br /&gt;
For a Third Party gateway go to [[#Third_Party_Gateway]], and for a merchant gateway go to [[#Merchant_Gateway]].&lt;br /&gt;
&lt;br /&gt;
==Third Party Gateway==&lt;br /&gt;
&lt;br /&gt;
Follow the steps below to create a third party gateway module (one where the customer leaves your site to make the payment on the gateway provider's website):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;docs-alert-warning&amp;quot;&amp;gt;The '''_capture''' function must be deleted before activating the new gateway module in WHMCS.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# Delete the '''_capture''' function from the module template.&lt;br /&gt;
# Enter the gateway-specific code for taking the user to the payment process within the _link function.  An example of this step is shown in the gateway module template supplied with the dev kit.  Normally, the code output by this function is the HTML for a '''&amp;lt;form&amp;gt;''' with a ''post'' method.&lt;br /&gt;
&lt;br /&gt;
The available variables are:&lt;br /&gt;
&lt;br /&gt;
===Invoice Variables===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['invoiceid'] # Invoice ID Number&lt;br /&gt;
$params['description'] # Description (eg. Company Name - Invoice #xxx)&lt;br /&gt;
$params['amount'] # Format: xxx.xx&lt;br /&gt;
$params['currency'] # Currency Code (eg. GBD, USD, etc...)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Client Variables===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['clientdetails']['firstname'] # Clients First Name&lt;br /&gt;
$params['clientdetails']['lastname'] # Clients Last Name&lt;br /&gt;
$params['clientdetails']['email'] # Clients Email Address&lt;br /&gt;
$params['clientdetails']['address1'] # Clients Address&lt;br /&gt;
$params['clientdetails']['address2'] &lt;br /&gt;
$params['clientdetails']['city']&lt;br /&gt;
$params['clientdetails']['state']&lt;br /&gt;
$params['clientdetails']['postcode']&lt;br /&gt;
$params['clientdetails']['country']&lt;br /&gt;
$params['clientdetails']['phonenumber']&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===System Variables===&lt;br /&gt;
&amp;lt;source lang = &amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['companyname'] # your Company Name setting in WHMCS&lt;br /&gt;
$params['systemurl'] # the url to the Client Area&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# The processing of a payment is handled by a callback file separate from the module (see page 9 for more information).&lt;br /&gt;
# If your gateway provider doesn't support automated refunds or you won't be including them in the module, then delete the '''_refund''' function.  Otherwise, refer to the Refund section on page 7.&lt;br /&gt;
&lt;br /&gt;
==Merchant Gateway==&lt;br /&gt;
&lt;br /&gt;
A merchant gateway module is a module where the customer enters their card details directly via the client area, without leaving the site.  To create one:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;docs-alert-warning&amp;quot;&amp;gt;&lt;br /&gt;
The '''_link''' function must be deleted before activating the new gateway module in WHMCS.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# Delete the '''_link''' function from the module template.&lt;br /&gt;
# Enter the gateway-specific code for processing the payment into the '''_capture''' function.  This normally takes the format of an HTTP/Curl request to the gateway provider's API.&lt;br /&gt;
&lt;br /&gt;
The variables available are:&lt;br /&gt;
&lt;br /&gt;
===Invoice Variables===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['invoiceid'] # Invoice ID Number&lt;br /&gt;
$params['description'] # Description (eg. Company Name - Invoice #xxx)&lt;br /&gt;
$params['amount'] # Format: xxx.xx&lt;br /&gt;
$params['currency'] # Currency Code (eg. GBP, USD, etc...)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Client Variables===&lt;br /&gt;
&amp;lt;source lang = &amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['clientdetails']['firstname'] # Clients First Name&lt;br /&gt;
$params['clientdetails']['lastname'] # Clients Last Name&lt;br /&gt;
$params['clientdetails']['email'] # Clients Email Address&lt;br /&gt;
$params['clientdetails']['address1'] # Clients Address&lt;br /&gt;
$params['clientdetails']['address2']&lt;br /&gt;
$params['clientdetails']['city']&lt;br /&gt;
$params['clientdetails']['state']&lt;br /&gt;
$params['clientdetails']['postcode']&lt;br /&gt;
$params['clientdetails']['country']&lt;br /&gt;
$params['clientdetails']['phonenumber']&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===System Variables===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['companyname'] # your Company Name setting in WHMCS&lt;br /&gt;
$params['systemurl'] # the url to the Client Area&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Card Details===&lt;br /&gt;
&amp;lt;source lang = &amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['cardtype'] # the Card Type (Visa, MasterCard, etc…)&lt;br /&gt;
$params['cardnum'] # the Card Number&lt;br /&gt;
$params['cardexp'] # the Card’s Expiry Date (Format: MMYY)&lt;br /&gt;
$params['cardstart'] # the Card’s Start Date (Format: MMYY)&lt;br /&gt;
$params['cardissuenum'] # the Card’s Issue Number (Switch/Solo Cards)&lt;br /&gt;
$params['cccvv'] # Not always present (recurring transactions)&lt;br /&gt;
# but would always be present for client initiated attempts&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# Once the transaction has been processed and a response has been received, an array with the results needs to be returned to WHMCS.   For a successful capture, use the following format:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
return array(&lt;br /&gt;
    &amp;quot;status&amp;quot; =&amp;gt; &amp;quot;success&amp;quot;,&lt;br /&gt;
    &amp;quot;transid&amp;quot; =&amp;gt; $results[&amp;quot;transid&amp;quot;],&lt;br /&gt;
    &amp;quot;rawdata&amp;quot; =&amp;gt; $results,&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# The status index ''must be'' '''success''' to tell WHMCS that the capture was successful.  &lt;br /&gt;
# The transid index should be passed the value of the transaction ID that came back from the gateway.&lt;br /&gt;
# The rawdata index should be passed an array of the data returned from the gateway to be stored in the WHMCS Gateway Log.&lt;br /&gt;
&lt;br /&gt;
If the transaction were to fail, use the following format:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
return array(&lt;br /&gt;
    &amp;quot;status&amp;quot; =&amp;gt; &amp;quot;declined&amp;quot;,&lt;br /&gt;
    &amp;quot;rawdata&amp;quot; =&amp;gt; $results,&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# The status index can be any value (''declined, error, invalid hash, etc'').  This value is displayed as the reason for failure, in the gateway log.&lt;br /&gt;
# The rawdata index should be passed an array of the data returned from the gateway to be stored in the WHMCS Gateway Log for debugging purposes.&lt;br /&gt;
&lt;br /&gt;
If the gateway supports 3D Secure (Verified by Visa or MasterCard Secure Code) then please refer to page 8.&lt;br /&gt;
&lt;br /&gt;
===Refunds===&lt;br /&gt;
&lt;br /&gt;
# If the gateway provider supports automated refunds, then code for processing a refund goes into the '''_refund''' function.  This is passed all of the same variables as the '''_capture''' function, but with an added transaction id:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['transid'] # the transaction ID of the original transaction to be refunded&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The return arrays for a success or failure should be done exactly the same as described above for the '''_capture''' function.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;docs-alert-danger&amp;quot;&amp;gt;&lt;br /&gt;
If the gateway provider does not support refunds, then the '''_refund''' function should be deleted from the module file.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Callbacks==&lt;br /&gt;
If the gateway provider supports notifying a script when a payment is successful, then a callback file can be created to detect and apply those calls as payments inside WHMCS.&lt;br /&gt;
&lt;br /&gt;
A sample callback file is included in the dev kit for this purpose named '''callback.php''':&lt;br /&gt;
&lt;br /&gt;
# Rename it to match the gateway module.&lt;br /&gt;
# Modify the variables within it, as per the comments in the code.&lt;br /&gt;
# Modify it to match the variables that the specific gateway returns.&lt;br /&gt;
&lt;br /&gt;
These are some helper functions within the sample:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$GATEWAY = getGatewayVariables(‘yourgatewayname’);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function can be used to retrieve the configuration data for the module as specified in&lt;br /&gt;
the '''_config''' array. For example, it might be needed to get a gateway username or secret key to&lt;br /&gt;
validate a callback.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$invoiceid = checkCbInvoiceID($invoiceid, $GATEWAY[‘name’]);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function can be used to check that the invoice ID received back is valid. Pass the $invoiceid and the gateway name into the function.  If the invoice number is valid, the script will continue executing.  Otherwise, the script will be halted and an appropriate gateway log entry will be created.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang =&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
checkCbTransID($transid);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function can be used to check for any existing transactions already recorded for a given transaction ID, which protects against duplicate callbacks.  If the transaction ID is already in the database, the callback script execution will be halted.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
logTransaction($GATEWAY[‘name’], $_POST, &amp;quot;Successful&amp;quot;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function can be used to create a gateway log entry. The first variable needs to be the name of the gateway module, the second should be an array of data, such as the '''$_POST''' or '''$_REQUEST''' super globals, and the last variable should be the result or status to show in the log.&lt;br /&gt;
&lt;br /&gt;
== 3D Secure Process ==&lt;br /&gt;
&lt;br /&gt;
If the merchant gateway supports 3D Secure (also known as ''Verified by Visa'' or ''MasterCard Secure Code''), then it can be utilized within WHMCS.&lt;br /&gt;
&lt;br /&gt;
# Add a function to the module named '''yourgatewayname_3dsecure''' &lt;br /&gt;
# Return the HTML for the '''&amp;lt;form&amp;gt;''' post method to take the user to the 3D Secure process. &lt;br /&gt;
&lt;br /&gt;
An example of this is below:&lt;br /&gt;
&lt;br /&gt;
The '''_3dsecure''' function is passed all the same variables that the '''_capture''' function is (see page 6). The return url should be a callback file to handle the response (see page 9).&lt;br /&gt;
&lt;br /&gt;
==Example==&lt;br /&gt;
&amp;lt;source lang = &amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
function yourgatewayname_3dsecure($params) {&lt;br /&gt;
$code = '&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;https://www.gateway.com/3dsecure/&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;gwlogin&amp;quot; value=&amp;quot;'.$params[&amp;quot;loginid&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;invoiceid&amp;quot; value=&amp;quot;'.$params[&amp;quot;invoiceid&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;amount&amp;quot; value=&amp;quot;'. $params[&amp;quot;amount&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;firstname&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;firstname&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;lastname&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;lastname&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;address&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;address1&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;city&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;city&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;state&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;state&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;postcode&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;postcode&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;country&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;country&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;phonenumber&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;phonenumber&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;email&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;email&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;ccnumber&amp;quot; value=&amp;quot;'. $params[&amp;quot;cardnum&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;expirymonth&amp;quot; value=&amp;quot;'.substr($params['cardexp'],0,2).'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;expiryyear&amp;quot; value=&amp;quot;'.substr($params['cardexp'],2,2).'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;cvv2&amp;quot; value=&amp;quot;'. $params[&amp;quot;cccvv&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;return_url&amp;quot; value=&amp;quot;'.&lt;br /&gt;
$params['systemurl'].'/modules/gateways/callback/yourgatewayname.php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;noscript&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;errorbox&amp;quot;&amp;gt;&amp;lt;b&amp;gt;JavaScript is currently disabled or is not supported by your&lt;br /&gt;
browser.&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Please click the continue button to proceed with the processing of your&lt;br /&gt;
transaction.&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Continue &amp;gt;&amp;gt;&amp;quot; /&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/noscript&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;';&lt;br /&gt;
      return $code;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Tokenised Remote Storage==&lt;br /&gt;
&lt;br /&gt;
With the increasing rules &amp;amp; requirements surrounding the storing of credit card details, many merchant gateways are offering services where repeat rebills can be performed without needing to store credit card details locally, on the system.  Gateway modules can utilize this functionality:&lt;br /&gt;
&lt;br /&gt;
The basic logic behind token gateways in WHMCS is that clients must either have a credit card number or a token stored in order for recurring billing to be attempted. So if you create a function named '''_storeremote''' in your custom gateway module, this function will then override the default local storage when new credit card details are entered. And instead of&lt;br /&gt;
saving in the database, that function then needs to communicate with the gateways API, and return the token that gets assigned to WHMCS.&lt;br /&gt;
&lt;br /&gt;
The variables passed into the '''_storeremote''' function are as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang =&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['gatewayid'] # the token stored for the client&lt;br /&gt;
$params['cardtype'] #the Card Type (Visa, MasterCard, etc…)&lt;br /&gt;
$params['cardnum'] # the Card Number&lt;br /&gt;
$params['cardexp'] # the Card’s Expiry Date (Format: MMYY)&lt;br /&gt;
$params['cardstart'] # the Card’s Start Date (Format: MMYY)&lt;br /&gt;
$params['cardissuenum'] # the Card’s Issue Number (Switch/Solo Cards)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
On the first call, the gatewayid will be empty. So when empty you need to create a new profile at the gateway. On subsequent calls the gatewayid that was originally created and stored will be passed in and the existing profile simply needs to be updated. And if the cardnum variable is empty, this indicates that deleting/removal of the stored credit card&lt;br /&gt;
details has been requested.&lt;br /&gt;
&lt;br /&gt;
Once the card details have been updated or stored remotely, return either a success or failure response to tell WHMCS if it worked, and if it did, the token that has been assigned:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang =&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
return array(&lt;br /&gt;
    &amp;quot;status&amp;quot; =&amp;gt; &amp;quot;success&amp;quot;,&lt;br /&gt;
    &amp;quot;gatewayid&amp;quot; =&amp;gt; $results[&amp;quot;token&amp;quot;],&lt;br /&gt;
    &amp;quot;rawdata&amp;quot; =&amp;gt; $results,&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
return array(&lt;br /&gt;
    &amp;quot;status&amp;quot; =&amp;gt; &amp;quot;failed&amp;quot;,&lt;br /&gt;
    &amp;quot;rawdata&amp;quot; =&amp;gt; $results,&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When this function exists in a gateway module, WHMCS will only store the card type, expiry date and the last 4 digits locally in the database. So you and your clients will still be able to see exactly what card is stored remotely from within WHMCS.&lt;br /&gt;
&lt;br /&gt;
Then within the capture function, instead of $params[‘cardnum’] you will be passed $params[‘gatewayid’] with which to perform the capture.&lt;br /&gt;
&lt;br /&gt;
==Installation &amp;amp; Activation==&lt;br /&gt;
&lt;br /&gt;
To install the new module, upload it to the '''/modules/gateways/''' folder and then go to ''Setup'' &amp;gt; ''Payment Gateways'' to activate. If there is a callback file,  then that should be uploaded to the '''/modules/gateways/callback/''' folder.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;docs-alert-warning&amp;quot;&amp;gt;&lt;br /&gt;
'''Important:''' It is important that the gateway is not activated until step 1 has been completed for both the third party gateway or the merchant gateway modules, because the type of module created is stored in the database upon activation.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Blank Screen/Errors==&lt;br /&gt;
&lt;br /&gt;
If there is a blank page or error within the ''Setup'' &amp;gt; ''Payment Gateways'' page after uploading the new module file, then there is a syntax error within the new code. To debug that, add the following line to the '''configuration.php''' file to turn on error reporting:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$display_errors = true;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This enables PHP error reporting and should show the cause of any issues. Remove this line once testing has completed.&lt;br /&gt;
&lt;br /&gt;
==App Store==&lt;br /&gt;
WHMCS offers an app store in which completed gateway modules can be submitted.  The listings are displayed under the Addons tab within the administration area and online at http://www.whmcs.com/appstore . This is a great way to make WHMCS users aware of your module.&lt;br /&gt;
&lt;br /&gt;
In order to submit a listing you'll need a login for whmcs.com/members, if you do not have one please [https://www.whmcs.com/members/submitticket.php?step=2&amp;amp;deptid=5 Contact Us]. Once logged in, visit the app store page at the above URL and click the &amp;quot;Submit your Addon&amp;quot; link. We aim to review submissions in 1-2 weeks.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Developer_Links}}&lt;/div&gt;</summary>
		<author><name>Nicolas</name></author>	</entry>

	<entry>
		<id>http://3.19.219.109/index.php?title=Gateway_Module_Developer_Docs&amp;diff=17558</id>
		<title>Gateway Module Developer Docs</title>
		<link rel="alternate" type="text/html" href="http://3.19.219.109/index.php?title=Gateway_Module_Developer_Docs&amp;diff=17558"/>
				<updated>2016-01-06T20:47:51Z</updated>
		
		<summary type="html">&lt;p&gt;Nicolas: /* Installation &amp;amp; Activation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Creating a gateway module allows you to connect WHMCS to third party payment and credit card processors that aren’t natively supported in WHMCS as standard.&lt;br /&gt;
&lt;br /&gt;
There are 2 core types of gateway module:&lt;br /&gt;
&lt;br /&gt;
#'''Third Party Gateways''' – this is where the customer leaves your site to pay and is returned once the payment process is completed&lt;br /&gt;
#'''Merchant Gateways''' – this is where the customer enters credit card details directly on your website and the payment is then processed in the background (can also include 3D Secure where the user leaves your site)&lt;br /&gt;
&lt;br /&gt;
{{Developer_Links}}&lt;br /&gt;
&lt;br /&gt;
So the first decision you need to make before starting your module for WHMCS is which type of gateway module you will be creating.  Once you have that, you're ready to begin.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Introduction==&lt;br /&gt;
&lt;br /&gt;
Gateway modules allow a connection between WHMCS and gateways or credit card processors that aren't natively supported in WHMCS.&lt;br /&gt;
&lt;br /&gt;
This documentation will explain the module's structure and contains everything needed in order to successfully create a gateway module for WHMCS.&lt;br /&gt;
&lt;br /&gt;
==Getting Started==&lt;br /&gt;
&lt;br /&gt;
To get started, begin by downloading the module development kit from our GitHub site. There are two sample modules available, depending upon the [[#Module Type|type of gateway]] being developed:&lt;br /&gt;
*Third Party Gateway: https://github.com/WHMCS/sample-gateway-module&lt;br /&gt;
*Merchant Gateway: https://github.com/WHMCS/sample-merchant-gateway&lt;br /&gt;
Take the gateway module template &amp;quot;template.php&amp;quot; from this download and rename it to &amp;quot;yourgatewayname.php&amp;quot;.  It should be all lowercase and must start with a letter.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;docs-alert-info&amp;quot;&amp;gt;&lt;br /&gt;
All functions within a gateway module must be prefixed with the filename.  Open the file and replace all occurrences of '''template_''' with '''yougatewayname_'''&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Config Array===&lt;br /&gt;
&lt;br /&gt;
'''Configure the yourgatewayname_config array'''. This function is the primary function required by all gateway modules and defines both the friendly display name for the module and any custom fields/options/settings that the gateway module requires.&lt;br /&gt;
&lt;br /&gt;
The available field types are &amp;quot;text&amp;quot;, &amp;quot;dropdown&amp;quot;, &amp;quot;textarea&amp;quot; and &amp;quot;yesno&amp;quot; (checkboxes).   The sample config array in &amp;quot;template.php&amp;quot; demonstrates how to use each of these types. &lt;br /&gt;
&lt;br /&gt;
The general formula:&lt;br /&gt;
#Specify a system name (''all in lowercase for the setting to be referenced by in the module code itself'')&lt;br /&gt;
#A FriendlyName&lt;br /&gt;
#Type&lt;br /&gt;
#Any settings specific to that field type.&lt;br /&gt;
&lt;br /&gt;
Any fields defined here will be available in all gateway module functions in the $params array, so avoid common names like currency, invoiceid, etc, as these will conflict with the standard variables.&lt;br /&gt;
&lt;br /&gt;
===Module Type===&lt;br /&gt;
&lt;br /&gt;
Determine which type of module needs to be created from the 2 core types:&lt;br /&gt;
&lt;br /&gt;
#'''Third Party Gateways''' – the customer leaves your site to pay and is returned once the payment process is completed.&lt;br /&gt;
#'''Merchant Gateways''' – where the customer enters credit card details directly on your website and the payment is then processed in the background (can also include 3D Secure where the user leaves your site).&lt;br /&gt;
&lt;br /&gt;
For a Third Party gateway go to [[#Third_Party_Gateway]], and for a merchant gateway go to [[#Merchant_Gateway]].&lt;br /&gt;
&lt;br /&gt;
==Third Party Gateway==&lt;br /&gt;
&lt;br /&gt;
Follow the steps below to create a third party gateway module (one where the customer leaves your site to make the payment on the gateway provider's website):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;docs-alert-warning&amp;quot;&amp;gt;The '''_capture''' function must be deleted before activating the new gateway module in WHMCS.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# Delete the '''_capture''' function from the module template.&lt;br /&gt;
# Enter the gateway-specific code for taking the user to the payment process within the _link function.  An example of this step is shown in the gateway module template supplied with the dev kit.  Normally, the code output by this function is the HTML for a '''&amp;lt;form&amp;gt;''' with a ''post'' method.&lt;br /&gt;
&lt;br /&gt;
The available variables are:&lt;br /&gt;
&lt;br /&gt;
===Invoice Variables===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['invoiceid'] # Invoice ID Number&lt;br /&gt;
$params['description'] # Description (eg. Company Name - Invoice #xxx)&lt;br /&gt;
$params['amount'] # Format: xxx.xx&lt;br /&gt;
$params['currency'] # Currency Code (eg. GBD, USD, etc...)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Client Variables===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['clientdetails']['firstname'] # Clients First Name&lt;br /&gt;
$params['clientdetails']['lastname'] # Clients Last Name&lt;br /&gt;
$params['clientdetails']['email'] # Clients Email Address&lt;br /&gt;
$params['clientdetails']['address1'] # Clients Address&lt;br /&gt;
$params['clientdetails']['address2'] &lt;br /&gt;
$params['clientdetails']['city']&lt;br /&gt;
$params['clientdetails']['state']&lt;br /&gt;
$params['clientdetails']['postcode']&lt;br /&gt;
$params['clientdetails']['country']&lt;br /&gt;
$params['clientdetails']['phonenumber']&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===System Variables===&lt;br /&gt;
&amp;lt;source lang = &amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['companyname'] # your Company Name setting in WHMCS&lt;br /&gt;
$params['systemurl'] # the url to the Client Area&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# The processing of a payment is handled by a callback file separate from the module (see page 9 for more information).&lt;br /&gt;
# If your gateway provider doesn't support automated refunds or you won't be including them in the module, then delete the '''_refund''' function.  Otherwise, refer to the Refund section on page 7.&lt;br /&gt;
&lt;br /&gt;
==Merchant Gateway==&lt;br /&gt;
&lt;br /&gt;
A merchant gateway module is a module where the customer enters their card details directly via the client area, without leaving the site.  To create one:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;docs-alert-warning&amp;quot;&amp;gt;&lt;br /&gt;
The '''_link''' function must be deleted before activating the new gateway module in WHMCS.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# Delete the '''_link''' function from the module template.&lt;br /&gt;
# Enter the gateway-specific code for processing the payment into the '''_capture''' function.  This normally takes the format of an HTTP/Curl request to the gateway provider's API.&lt;br /&gt;
&lt;br /&gt;
The variables available are:&lt;br /&gt;
&lt;br /&gt;
===Invoice Variables===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['invoiceid'] # Invoice ID Number&lt;br /&gt;
$params['description'] # Description (eg. Company Name - Invoice #xxx)&lt;br /&gt;
$params['amount'] # Format: xxx.xx&lt;br /&gt;
$params['currency'] # Currency Code (eg. GBP, USD, etc...)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Client Variables===&lt;br /&gt;
&amp;lt;source lang = &amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['clientdetails']['firstname'] # Clients First Name&lt;br /&gt;
$params['clientdetails']['lastname'] # Clients Last Name&lt;br /&gt;
$params['clientdetails']['email'] # Clients Email Address&lt;br /&gt;
$params['clientdetails']['address1'] # Clients Address&lt;br /&gt;
$params['clientdetails']['address2']&lt;br /&gt;
$params['clientdetails']['city']&lt;br /&gt;
$params['clientdetails']['state']&lt;br /&gt;
$params['clientdetails']['postcode']&lt;br /&gt;
$params['clientdetails']['country']&lt;br /&gt;
$params['clientdetails']['phonenumber']&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===System Variables===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['companyname'] # your Company Name setting in WHMCS&lt;br /&gt;
$params['systemurl'] # the url to the Client Area&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Card Details===&lt;br /&gt;
&amp;lt;source lang = &amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['cardtype'] # the Card Type (Visa, MasterCard, etc…)&lt;br /&gt;
$params['cardnum'] # the Card Number&lt;br /&gt;
$params['cardexp'] # the Card’s Expiry Date (Format: MMYY)&lt;br /&gt;
$params['cardstart'] # the Card’s Start Date (Format: MMYY)&lt;br /&gt;
$params['cardissuenum'] # the Card’s Issue Number (Switch/Solo Cards)&lt;br /&gt;
$params['cccvv'] # Not always present (recurring transactions)&lt;br /&gt;
# but would always be present for client initiated attempts&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# Once the transaction has been processed and a response has been received, an array with the results needs to be returned to WHMCS.   For a successful capture, use the following format:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
return array(&lt;br /&gt;
    &amp;quot;status&amp;quot; =&amp;gt; &amp;quot;success&amp;quot;,&lt;br /&gt;
    &amp;quot;transid&amp;quot; =&amp;gt; $results[&amp;quot;transid&amp;quot;],&lt;br /&gt;
    &amp;quot;rawdata&amp;quot; =&amp;gt; $results,&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# The status index ''must be'' '''success''' to tell WHMCS that the capture was successful.  &lt;br /&gt;
# The transid index should be passed the value of the transaction ID that came back from the gateway.&lt;br /&gt;
# The rawdata index should be passed an array of the data returned from the gateway to be stored in the WHMCS Gateway Log.&lt;br /&gt;
&lt;br /&gt;
If the transaction were to fail, use the following format:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
return array(&lt;br /&gt;
    &amp;quot;status&amp;quot; =&amp;gt; &amp;quot;declined&amp;quot;,&lt;br /&gt;
    &amp;quot;rawdata&amp;quot; =&amp;gt; $results,&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# The status index can be any value (''declined, error, invalid hash, etc'').  This value is displayed as the reason for failure, in the gateway log.&lt;br /&gt;
# The rawdata index should be passed an array of the data returned from the gateway to be stored in the WHMCS Gateway Log for debugging purposes.&lt;br /&gt;
&lt;br /&gt;
If the gateway supports 3D Secure (Verified by Visa or MasterCard Secure Code) then please refer to page 8.&lt;br /&gt;
&lt;br /&gt;
===Refunds===&lt;br /&gt;
&lt;br /&gt;
# If the gateway provider supports automated refunds, then code for processing a refund goes into the '''_refund''' function.  This is passed all of the same variables as the '''_capture''' function, but with an added transaction id:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['transid'] # the transaction ID of the original transaction to be refunded&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The return arrays for a success or failure should be done exactly the same as described above for the '''_capture''' function.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;docs-alert-danger&amp;quot;&amp;gt;&lt;br /&gt;
If the gateway provider does not support refunds, then the '''_refund''' function should be deleted from the module file.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Callbacks==&lt;br /&gt;
If the gateway provider supports notifying a script when a payment is successful, then a callback file can be created to detect and apply those calls as payments inside WHMCS.&lt;br /&gt;
&lt;br /&gt;
A sample callback file is included in the dev kit for this purpose named '''callback.php''':&lt;br /&gt;
&lt;br /&gt;
# Rename it to match the gateway module.&lt;br /&gt;
# Modify the variables within it, as per the comments in the code.&lt;br /&gt;
# Modify it to match the variables that the specific gateway returns.&lt;br /&gt;
&lt;br /&gt;
These are some helper functions within the sample:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$GATEWAY = getGatewayVariables(‘yourgatewayname’);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function can be used to retrieve the configuration data for the module as specified in&lt;br /&gt;
the '''_config''' array. For example, it might be needed to get a gateway username or secret key to&lt;br /&gt;
validate a callback.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$invoiceid = checkCbInvoiceID($invoiceid, $GATEWAY[‘name’]);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function can be used to check that the invoice ID received back is valid. Pass the $invoiceid and the gateway name into the function.  If the invoice number is valid, the script will continue executing.  Otherwise, the script will be halted and an appropriate gateway log entry will be created.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang =&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
checkCbTransID($transid);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function can be used to check for any existing transactions already recorded for a given transaction ID, which protects against duplicate callbacks.  If the transaction ID is already in the database, the callback script execution will be halted.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
logTransaction($GATEWAY[‘name’], $_POST, &amp;quot;Successful&amp;quot;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function can be used to create a gateway log entry. The first variable needs to be the name of the gateway module, the second should be an array of data, such as the '''$_POST''' or '''$_REQUEST''' super globals, and the last variable should be the result or status to show in the log.&lt;br /&gt;
&lt;br /&gt;
== 3D Secure Process ==&lt;br /&gt;
&lt;br /&gt;
If the merchant gateway supports 3D Secure (also known as ''Verified by Visa'' or ''MasterCard Secure Code''), then it can be utilized within WHMCS.&lt;br /&gt;
&lt;br /&gt;
# Add a function to the module named '''yourgatewayname_3dsecure''' &lt;br /&gt;
# Return the HTML for the '''&amp;lt;form&amp;gt;''' post method to take the user to the 3D Secure process. &lt;br /&gt;
&lt;br /&gt;
An example of this is below:&lt;br /&gt;
&lt;br /&gt;
The '''_3dsecure''' function is passed all the same variables that the '''_capture''' function is (see page 6). The return url should be a callback file to handle the response (see page 9).&lt;br /&gt;
&lt;br /&gt;
==Example==&lt;br /&gt;
&amp;lt;source lang = &amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
function yourgatewayname_3dsecure($params) {&lt;br /&gt;
$code = '&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;https://www.gateway.com/3dsecure/&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;gwlogin&amp;quot; value=&amp;quot;'.$params[&amp;quot;loginid&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;invoiceid&amp;quot; value=&amp;quot;'.$params[&amp;quot;invoiceid&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;amount&amp;quot; value=&amp;quot;'. $params[&amp;quot;amount&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;firstname&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;firstname&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;lastname&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;lastname&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;address&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;address1&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;city&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;city&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;state&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;state&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;postcode&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;postcode&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;country&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;country&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;phonenumber&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;phonenumber&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;email&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;email&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;ccnumber&amp;quot; value=&amp;quot;'. $params[&amp;quot;cardnum&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;expirymonth&amp;quot; value=&amp;quot;'.substr($params['cardexp'],0,2).'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;expiryyear&amp;quot; value=&amp;quot;'.substr($params['cardexp'],2,2).'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;cvv2&amp;quot; value=&amp;quot;'. $params[&amp;quot;cccvv&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;return_url&amp;quot; value=&amp;quot;'.&lt;br /&gt;
$params['systemurl'].'/modules/gateways/callback/yourgatewayname.php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;noscript&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;errorbox&amp;quot;&amp;gt;&amp;lt;b&amp;gt;JavaScript is currently disabled or is not supported by your&lt;br /&gt;
browser.&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Please click the continue button to proceed with the processing of your&lt;br /&gt;
transaction.&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Continue &amp;gt;&amp;gt;&amp;quot; /&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/noscript&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;';&lt;br /&gt;
      return $code;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Tokenised Remote Storage==&lt;br /&gt;
&lt;br /&gt;
With the increasing rules &amp;amp; requirements surrounding the storing of credit card details, many merchant gateways are offering services where repeat rebills can be performed without needing to store credit card details locally, on the system.  Gateway modules can utilize this functionality:&lt;br /&gt;
&lt;br /&gt;
The basic logic behind token gateways in WHMCS is that clients must either have a credit card number or a token stored in order for recurring billing to be attempted. So if you create a function named '''_storeremote''' in your custom gateway module, this function will then override the default local storage when new credit card details are entered. And instead of&lt;br /&gt;
saving in the database, that function then needs to communicate with the gateways API, and return the token that gets assigned to WHMCS.&lt;br /&gt;
&lt;br /&gt;
The variables passed into the '''_storeremote''' function are as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang =&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['gatewayid'] # the token stored for the client&lt;br /&gt;
$params['cardtype'] #the Card Type (Visa, MasterCard, etc…)&lt;br /&gt;
$params['cardnum'] # the Card Number&lt;br /&gt;
$params['cardexp'] # the Card’s Expiry Date (Format: MMYY)&lt;br /&gt;
$params['cardstart'] # the Card’s Start Date (Format: MMYY)&lt;br /&gt;
$params['cardissuenum'] # the Card’s Issue Number (Switch/Solo Cards)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
On the first call, the gatewayid will be empty. So when empty you need to create a new profile at the gateway. On subsequent calls the gatewayid that was originally created and stored will be passed in and the existing profile simply needs to be updated. And if the cardnum variable is empty, this indicates that deleting/removal of the stored credit card&lt;br /&gt;
details has been requested.&lt;br /&gt;
&lt;br /&gt;
Once the card details have been updated or stored remotely, return either a success or failure response to tell WHMCS if it worked, and if it did, the token that has been assigned:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang =&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
return array(&lt;br /&gt;
    &amp;quot;status&amp;quot; =&amp;gt; &amp;quot;success&amp;quot;,&lt;br /&gt;
    &amp;quot;gatewayid&amp;quot; =&amp;gt; $results[&amp;quot;token&amp;quot;],&lt;br /&gt;
    &amp;quot;rawdata&amp;quot; =&amp;gt; $results,&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
return array(&lt;br /&gt;
    &amp;quot;status&amp;quot; =&amp;gt; &amp;quot;failed&amp;quot;,&lt;br /&gt;
    &amp;quot;rawdata&amp;quot; =&amp;gt; $results,&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When this function exists in a gateway module, WHMCS will only store the card type, expiry date and the last 4 digits locally in the database. So you and your clients will still be able to see exactly what card is stored remotely from within WHMCS.&lt;br /&gt;
&lt;br /&gt;
Then within the capture function, instead of $params[‘cardnum’] you will be passed $params[‘gatewayid’] with which to perform the capture.&lt;br /&gt;
&lt;br /&gt;
==Installation &amp;amp; Activation==&lt;br /&gt;
&lt;br /&gt;
To install the new module, upload it to the '''/modules/gateways/''' folder and then go to ''Setup'' &amp;gt; ''Payment Gateways'' to activate. If there is a callback file,  then that should be uploaded to the '''/modules/gateways/callback/''' folder.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;docs-alert-warning&amp;quot;&amp;gt;&lt;br /&gt;
'''Important:''' It is important that the gateway is not activated until step 1 has been completed for both the third party gateway or the merchant gateway modules, because the type of module created is stored in the database upon activation.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Blank Screen/Errors==&lt;br /&gt;
&lt;br /&gt;
If you get a blank page or errors in the Setup &amp;gt; Payment Gateways page after uploading your new module file then this indicates there is a syntax error in your code. To debug that, you can add the following line to your WHMCS configuration.php file to turn on error reporting:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$display_errors = true;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That will enable PHP error reporting and should show you the cause of any issues. Once you are done testing you must remember to remove that line again.&lt;br /&gt;
&lt;br /&gt;
==App Store==&lt;br /&gt;
WHMCS offers an app store in which completed gateway modules can be submitted.  The listings are displayed under the Addons tab within the administration area and online at http://www.whmcs.com/appstore . This is a great way to make WHMCS users aware of your module.&lt;br /&gt;
&lt;br /&gt;
In order to submit a listing you'll need a login for whmcs.com/members, if you do not have one please [https://www.whmcs.com/members/submitticket.php?step=2&amp;amp;deptid=5 Contact Us]. Once logged in, visit the app store page at the above URL and click the &amp;quot;Submit your Addon&amp;quot; link. We aim to review submissions in 1-2 weeks.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Developer_Links}}&lt;/div&gt;</summary>
		<author><name>Nicolas</name></author>	</entry>

	<entry>
		<id>http://3.19.219.109/index.php?title=Gateway_Module_Developer_Docs&amp;diff=17555</id>
		<title>Gateway Module Developer Docs</title>
		<link rel="alternate" type="text/html" href="http://3.19.219.109/index.php?title=Gateway_Module_Developer_Docs&amp;diff=17555"/>
				<updated>2016-01-06T20:44:04Z</updated>
		
		<summary type="html">&lt;p&gt;Nicolas: /* Tokenised Remote Storage */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Creating a gateway module allows you to connect WHMCS to third party payment and credit card processors that aren’t natively supported in WHMCS as standard.&lt;br /&gt;
&lt;br /&gt;
There are 2 core types of gateway module:&lt;br /&gt;
&lt;br /&gt;
#'''Third Party Gateways''' – this is where the customer leaves your site to pay and is returned once the payment process is completed&lt;br /&gt;
#'''Merchant Gateways''' – this is where the customer enters credit card details directly on your website and the payment is then processed in the background (can also include 3D Secure where the user leaves your site)&lt;br /&gt;
&lt;br /&gt;
{{Developer_Links}}&lt;br /&gt;
&lt;br /&gt;
So the first decision you need to make before starting your module for WHMCS is which type of gateway module you will be creating.  Once you have that, you're ready to begin.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Introduction==&lt;br /&gt;
&lt;br /&gt;
Gateway modules allow a connection between WHMCS and gateways or credit card processors that aren't natively supported in WHMCS.&lt;br /&gt;
&lt;br /&gt;
This documentation will explain the module's structure and contains everything needed in order to successfully create a gateway module for WHMCS.&lt;br /&gt;
&lt;br /&gt;
==Getting Started==&lt;br /&gt;
&lt;br /&gt;
To get started, begin by downloading the module development kit from our GitHub site. There are two sample modules available, depending upon the [[#Module Type|type of gateway]] being developed:&lt;br /&gt;
*Third Party Gateway: https://github.com/WHMCS/sample-gateway-module&lt;br /&gt;
*Merchant Gateway: https://github.com/WHMCS/sample-merchant-gateway&lt;br /&gt;
Take the gateway module template &amp;quot;template.php&amp;quot; from this download and rename it to &amp;quot;yourgatewayname.php&amp;quot;.  It should be all lowercase and must start with a letter.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;docs-alert-info&amp;quot;&amp;gt;&lt;br /&gt;
All functions within a gateway module must be prefixed with the filename.  Open the file and replace all occurrences of '''template_''' with '''yougatewayname_'''&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Config Array===&lt;br /&gt;
&lt;br /&gt;
'''Configure the yourgatewayname_config array'''. This function is the primary function required by all gateway modules and defines both the friendly display name for the module and any custom fields/options/settings that the gateway module requires.&lt;br /&gt;
&lt;br /&gt;
The available field types are &amp;quot;text&amp;quot;, &amp;quot;dropdown&amp;quot;, &amp;quot;textarea&amp;quot; and &amp;quot;yesno&amp;quot; (checkboxes).   The sample config array in &amp;quot;template.php&amp;quot; demonstrates how to use each of these types. &lt;br /&gt;
&lt;br /&gt;
The general formula:&lt;br /&gt;
#Specify a system name (''all in lowercase for the setting to be referenced by in the module code itself'')&lt;br /&gt;
#A FriendlyName&lt;br /&gt;
#Type&lt;br /&gt;
#Any settings specific to that field type.&lt;br /&gt;
&lt;br /&gt;
Any fields defined here will be available in all gateway module functions in the $params array, so avoid common names like currency, invoiceid, etc, as these will conflict with the standard variables.&lt;br /&gt;
&lt;br /&gt;
===Module Type===&lt;br /&gt;
&lt;br /&gt;
Determine which type of module needs to be created from the 2 core types:&lt;br /&gt;
&lt;br /&gt;
#'''Third Party Gateways''' – the customer leaves your site to pay and is returned once the payment process is completed.&lt;br /&gt;
#'''Merchant Gateways''' – where the customer enters credit card details directly on your website and the payment is then processed in the background (can also include 3D Secure where the user leaves your site).&lt;br /&gt;
&lt;br /&gt;
For a Third Party gateway go to [[#Third_Party_Gateway]], and for a merchant gateway go to [[#Merchant_Gateway]].&lt;br /&gt;
&lt;br /&gt;
==Third Party Gateway==&lt;br /&gt;
&lt;br /&gt;
Follow the steps below to create a third party gateway module (one where the customer leaves your site to make the payment on the gateway provider's website):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;docs-alert-warning&amp;quot;&amp;gt;The '''_capture''' function must be deleted before activating the new gateway module in WHMCS.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# Delete the '''_capture''' function from the module template.&lt;br /&gt;
# Enter the gateway-specific code for taking the user to the payment process within the _link function.  An example of this step is shown in the gateway module template supplied with the dev kit.  Normally, the code output by this function is the HTML for a '''&amp;lt;form&amp;gt;''' with a ''post'' method.&lt;br /&gt;
&lt;br /&gt;
The available variables are:&lt;br /&gt;
&lt;br /&gt;
===Invoice Variables===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['invoiceid'] # Invoice ID Number&lt;br /&gt;
$params['description'] # Description (eg. Company Name - Invoice #xxx)&lt;br /&gt;
$params['amount'] # Format: xxx.xx&lt;br /&gt;
$params['currency'] # Currency Code (eg. GBD, USD, etc...)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Client Variables===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['clientdetails']['firstname'] # Clients First Name&lt;br /&gt;
$params['clientdetails']['lastname'] # Clients Last Name&lt;br /&gt;
$params['clientdetails']['email'] # Clients Email Address&lt;br /&gt;
$params['clientdetails']['address1'] # Clients Address&lt;br /&gt;
$params['clientdetails']['address2'] &lt;br /&gt;
$params['clientdetails']['city']&lt;br /&gt;
$params['clientdetails']['state']&lt;br /&gt;
$params['clientdetails']['postcode']&lt;br /&gt;
$params['clientdetails']['country']&lt;br /&gt;
$params['clientdetails']['phonenumber']&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===System Variables===&lt;br /&gt;
&amp;lt;source lang = &amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['companyname'] # your Company Name setting in WHMCS&lt;br /&gt;
$params['systemurl'] # the url to the Client Area&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# The processing of a payment is handled by a callback file separate from the module (see page 9 for more information).&lt;br /&gt;
# If your gateway provider doesn't support automated refunds or you won't be including them in the module, then delete the '''_refund''' function.  Otherwise, refer to the Refund section on page 7.&lt;br /&gt;
&lt;br /&gt;
==Merchant Gateway==&lt;br /&gt;
&lt;br /&gt;
A merchant gateway module is a module where the customer enters their card details directly via the client area, without leaving the site.  To create one:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;docs-alert-warning&amp;quot;&amp;gt;&lt;br /&gt;
The '''_link''' function must be deleted before activating the new gateway module in WHMCS.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# Delete the '''_link''' function from the module template.&lt;br /&gt;
# Enter the gateway-specific code for processing the payment into the '''_capture''' function.  This normally takes the format of an HTTP/Curl request to the gateway provider's API.&lt;br /&gt;
&lt;br /&gt;
The variables available are:&lt;br /&gt;
&lt;br /&gt;
===Invoice Variables===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['invoiceid'] # Invoice ID Number&lt;br /&gt;
$params['description'] # Description (eg. Company Name - Invoice #xxx)&lt;br /&gt;
$params['amount'] # Format: xxx.xx&lt;br /&gt;
$params['currency'] # Currency Code (eg. GBP, USD, etc...)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Client Variables===&lt;br /&gt;
&amp;lt;source lang = &amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['clientdetails']['firstname'] # Clients First Name&lt;br /&gt;
$params['clientdetails']['lastname'] # Clients Last Name&lt;br /&gt;
$params['clientdetails']['email'] # Clients Email Address&lt;br /&gt;
$params['clientdetails']['address1'] # Clients Address&lt;br /&gt;
$params['clientdetails']['address2']&lt;br /&gt;
$params['clientdetails']['city']&lt;br /&gt;
$params['clientdetails']['state']&lt;br /&gt;
$params['clientdetails']['postcode']&lt;br /&gt;
$params['clientdetails']['country']&lt;br /&gt;
$params['clientdetails']['phonenumber']&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===System Variables===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['companyname'] # your Company Name setting in WHMCS&lt;br /&gt;
$params['systemurl'] # the url to the Client Area&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Card Details===&lt;br /&gt;
&amp;lt;source lang = &amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['cardtype'] # the Card Type (Visa, MasterCard, etc…)&lt;br /&gt;
$params['cardnum'] # the Card Number&lt;br /&gt;
$params['cardexp'] # the Card’s Expiry Date (Format: MMYY)&lt;br /&gt;
$params['cardstart'] # the Card’s Start Date (Format: MMYY)&lt;br /&gt;
$params['cardissuenum'] # the Card’s Issue Number (Switch/Solo Cards)&lt;br /&gt;
$params['cccvv'] # Not always present (recurring transactions)&lt;br /&gt;
# but would always be present for client initiated attempts&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# Once the transaction has been processed and a response has been received, an array with the results needs to be returned to WHMCS.   For a successful capture, use the following format:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
return array(&lt;br /&gt;
    &amp;quot;status&amp;quot; =&amp;gt; &amp;quot;success&amp;quot;,&lt;br /&gt;
    &amp;quot;transid&amp;quot; =&amp;gt; $results[&amp;quot;transid&amp;quot;],&lt;br /&gt;
    &amp;quot;rawdata&amp;quot; =&amp;gt; $results,&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# The status index ''must be'' '''success''' to tell WHMCS that the capture was successful.  &lt;br /&gt;
# The transid index should be passed the value of the transaction ID that came back from the gateway.&lt;br /&gt;
# The rawdata index should be passed an array of the data returned from the gateway to be stored in the WHMCS Gateway Log.&lt;br /&gt;
&lt;br /&gt;
If the transaction were to fail, use the following format:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
return array(&lt;br /&gt;
    &amp;quot;status&amp;quot; =&amp;gt; &amp;quot;declined&amp;quot;,&lt;br /&gt;
    &amp;quot;rawdata&amp;quot; =&amp;gt; $results,&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# The status index can be any value (''declined, error, invalid hash, etc'').  This value is displayed as the reason for failure, in the gateway log.&lt;br /&gt;
# The rawdata index should be passed an array of the data returned from the gateway to be stored in the WHMCS Gateway Log for debugging purposes.&lt;br /&gt;
&lt;br /&gt;
If the gateway supports 3D Secure (Verified by Visa or MasterCard Secure Code) then please refer to page 8.&lt;br /&gt;
&lt;br /&gt;
===Refunds===&lt;br /&gt;
&lt;br /&gt;
# If the gateway provider supports automated refunds, then code for processing a refund goes into the '''_refund''' function.  This is passed all of the same variables as the '''_capture''' function, but with an added transaction id:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['transid'] # the transaction ID of the original transaction to be refunded&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The return arrays for a success or failure should be done exactly the same as described above for the '''_capture''' function.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;docs-alert-danger&amp;quot;&amp;gt;&lt;br /&gt;
If the gateway provider does not support refunds, then the '''_refund''' function should be deleted from the module file.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Callbacks==&lt;br /&gt;
If the gateway provider supports notifying a script when a payment is successful, then a callback file can be created to detect and apply those calls as payments inside WHMCS.&lt;br /&gt;
&lt;br /&gt;
A sample callback file is included in the dev kit for this purpose named '''callback.php''':&lt;br /&gt;
&lt;br /&gt;
# Rename it to match the gateway module.&lt;br /&gt;
# Modify the variables within it, as per the comments in the code.&lt;br /&gt;
# Modify it to match the variables that the specific gateway returns.&lt;br /&gt;
&lt;br /&gt;
These are some helper functions within the sample:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$GATEWAY = getGatewayVariables(‘yourgatewayname’);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function can be used to retrieve the configuration data for the module as specified in&lt;br /&gt;
the '''_config''' array. For example, it might be needed to get a gateway username or secret key to&lt;br /&gt;
validate a callback.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$invoiceid = checkCbInvoiceID($invoiceid, $GATEWAY[‘name’]);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function can be used to check that the invoice ID received back is valid. Pass the $invoiceid and the gateway name into the function.  If the invoice number is valid, the script will continue executing.  Otherwise, the script will be halted and an appropriate gateway log entry will be created.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang =&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
checkCbTransID($transid);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function can be used to check for any existing transactions already recorded for a given transaction ID, which protects against duplicate callbacks.  If the transaction ID is already in the database, the callback script execution will be halted.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
logTransaction($GATEWAY[‘name’], $_POST, &amp;quot;Successful&amp;quot;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function can be used to create a gateway log entry. The first variable needs to be the name of the gateway module, the second should be an array of data, such as the '''$_POST''' or '''$_REQUEST''' super globals, and the last variable should be the result or status to show in the log.&lt;br /&gt;
&lt;br /&gt;
== 3D Secure Process ==&lt;br /&gt;
&lt;br /&gt;
If the merchant gateway supports 3D Secure (also known as ''Verified by Visa'' or ''MasterCard Secure Code''), then it can be utilized within WHMCS.&lt;br /&gt;
&lt;br /&gt;
# Add a function to the module named '''yourgatewayname_3dsecure''' &lt;br /&gt;
# Return the HTML for the '''&amp;lt;form&amp;gt;''' post method to take the user to the 3D Secure process. &lt;br /&gt;
&lt;br /&gt;
An example of this is below:&lt;br /&gt;
&lt;br /&gt;
The '''_3dsecure''' function is passed all the same variables that the '''_capture''' function is (see page 6). The return url should be a callback file to handle the response (see page 9).&lt;br /&gt;
&lt;br /&gt;
==Example==&lt;br /&gt;
&amp;lt;source lang = &amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
function yourgatewayname_3dsecure($params) {&lt;br /&gt;
$code = '&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;https://www.gateway.com/3dsecure/&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;gwlogin&amp;quot; value=&amp;quot;'.$params[&amp;quot;loginid&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;invoiceid&amp;quot; value=&amp;quot;'.$params[&amp;quot;invoiceid&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;amount&amp;quot; value=&amp;quot;'. $params[&amp;quot;amount&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;firstname&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;firstname&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;lastname&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;lastname&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;address&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;address1&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;city&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;city&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;state&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;state&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;postcode&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;postcode&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;country&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;country&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;phonenumber&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;phonenumber&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;email&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;email&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;ccnumber&amp;quot; value=&amp;quot;'. $params[&amp;quot;cardnum&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;expirymonth&amp;quot; value=&amp;quot;'.substr($params['cardexp'],0,2).'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;expiryyear&amp;quot; value=&amp;quot;'.substr($params['cardexp'],2,2).'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;cvv2&amp;quot; value=&amp;quot;'. $params[&amp;quot;cccvv&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;return_url&amp;quot; value=&amp;quot;'.&lt;br /&gt;
$params['systemurl'].'/modules/gateways/callback/yourgatewayname.php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;noscript&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;errorbox&amp;quot;&amp;gt;&amp;lt;b&amp;gt;JavaScript is currently disabled or is not supported by your&lt;br /&gt;
browser.&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Please click the continue button to proceed with the processing of your&lt;br /&gt;
transaction.&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Continue &amp;gt;&amp;gt;&amp;quot; /&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/noscript&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;';&lt;br /&gt;
      return $code;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Tokenised Remote Storage==&lt;br /&gt;
&lt;br /&gt;
With the increasing rules &amp;amp; requirements surrounding the storing of credit card details, many merchant gateways are offering services where repeat rebills can be performed without needing to store credit card details locally, on the system.  Gateway modules can utilize this functionality:&lt;br /&gt;
&lt;br /&gt;
The basic logic behind token gateways in WHMCS is that clients must either have a credit card number or a token stored in order for recurring billing to be attempted. So if you create a function named '''_storeremote''' in your custom gateway module, this function will then override the default local storage when new credit card details are entered. And instead of&lt;br /&gt;
saving in the database, that function then needs to communicate with the gateways API, and return the token that gets assigned to WHMCS.&lt;br /&gt;
&lt;br /&gt;
The variables passed into the '''_storeremote''' function are as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang =&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['gatewayid'] # the token stored for the client&lt;br /&gt;
$params['cardtype'] #the Card Type (Visa, MasterCard, etc…)&lt;br /&gt;
$params['cardnum'] # the Card Number&lt;br /&gt;
$params['cardexp'] # the Card’s Expiry Date (Format: MMYY)&lt;br /&gt;
$params['cardstart'] # the Card’s Start Date (Format: MMYY)&lt;br /&gt;
$params['cardissuenum'] # the Card’s Issue Number (Switch/Solo Cards)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
On the first call, the gatewayid will be empty. So when empty you need to create a new profile at the gateway. On subsequent calls the gatewayid that was originally created and stored will be passed in and the existing profile simply needs to be updated. And if the cardnum variable is empty, this indicates that deleting/removal of the stored credit card&lt;br /&gt;
details has been requested.&lt;br /&gt;
&lt;br /&gt;
Once the card details have been updated or stored remotely, return either a success or failure response to tell WHMCS if it worked, and if it did, the token that has been assigned:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang =&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
return array(&lt;br /&gt;
    &amp;quot;status&amp;quot; =&amp;gt; &amp;quot;success&amp;quot;,&lt;br /&gt;
    &amp;quot;gatewayid&amp;quot; =&amp;gt; $results[&amp;quot;token&amp;quot;],&lt;br /&gt;
    &amp;quot;rawdata&amp;quot; =&amp;gt; $results,&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
return array(&lt;br /&gt;
    &amp;quot;status&amp;quot; =&amp;gt; &amp;quot;failed&amp;quot;,&lt;br /&gt;
    &amp;quot;rawdata&amp;quot; =&amp;gt; $results,&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When this function exists in a gateway module, WHMCS will only store the card type, expiry date and the last 4 digits locally in the database. So you and your clients will still be able to see exactly what card is stored remotely from within WHMCS.&lt;br /&gt;
&lt;br /&gt;
Then within the capture function, instead of $params[‘cardnum’] you will be passed $params[‘gatewayid’] with which to perform the capture.&lt;br /&gt;
&lt;br /&gt;
==Installation &amp;amp; Activation==&lt;br /&gt;
&lt;br /&gt;
To install the module you’ve created, simply upload it to the /modules/gateways/ folder and then go to Setup &amp;gt; Payment Gateways to activate. If you have create a callback file as well then that should also be uploaded but to the /modules/gateways/callback/ folder.&lt;br /&gt;
&lt;br /&gt;
'''Important:''' It is important that you do not activate your gateway module until you have&lt;br /&gt;
completed step 1 of either the third party gateway or merchant gateway module&lt;br /&gt;
documentation steps to remove the appropriate functions as it’s at the time of activation&lt;br /&gt;
that the type of module you are setting up gets stored in the system.&lt;br /&gt;
&lt;br /&gt;
==Blank Screen/Errors==&lt;br /&gt;
&lt;br /&gt;
If you get a blank page or errors in the Setup &amp;gt; Payment Gateways page after uploading your new module file then this indicates there is a syntax error in your code. To debug that, you can add the following line to your WHMCS configuration.php file to turn on error reporting:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$display_errors = true;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That will enable PHP error reporting and should show you the cause of any issues. Once you are done testing you must remember to remove that line again.&lt;br /&gt;
&lt;br /&gt;
==App Store==&lt;br /&gt;
WHMCS offers an app store in which completed gateway modules can be submitted.  The listings are displayed under the Addons tab within the administration area and online at http://www.whmcs.com/appstore . This is a great way to make WHMCS users aware of your module.&lt;br /&gt;
&lt;br /&gt;
In order to submit a listing you'll need a login for whmcs.com/members, if you do not have one please [https://www.whmcs.com/members/submitticket.php?step=2&amp;amp;deptid=5 Contact Us]. Once logged in, visit the app store page at the above URL and click the &amp;quot;Submit your Addon&amp;quot; link. We aim to review submissions in 1-2 weeks.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Developer_Links}}&lt;/div&gt;</summary>
		<author><name>Nicolas</name></author>	</entry>

	<entry>
		<id>http://3.19.219.109/index.php?title=Gateway_Module_Developer_Docs&amp;diff=17554</id>
		<title>Gateway Module Developer Docs</title>
		<link rel="alternate" type="text/html" href="http://3.19.219.109/index.php?title=Gateway_Module_Developer_Docs&amp;diff=17554"/>
				<updated>2016-01-06T20:39:17Z</updated>
		
		<summary type="html">&lt;p&gt;Nicolas: /* 3D Secure Process */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Creating a gateway module allows you to connect WHMCS to third party payment and credit card processors that aren’t natively supported in WHMCS as standard.&lt;br /&gt;
&lt;br /&gt;
There are 2 core types of gateway module:&lt;br /&gt;
&lt;br /&gt;
#'''Third Party Gateways''' – this is where the customer leaves your site to pay and is returned once the payment process is completed&lt;br /&gt;
#'''Merchant Gateways''' – this is where the customer enters credit card details directly on your website and the payment is then processed in the background (can also include 3D Secure where the user leaves your site)&lt;br /&gt;
&lt;br /&gt;
{{Developer_Links}}&lt;br /&gt;
&lt;br /&gt;
So the first decision you need to make before starting your module for WHMCS is which type of gateway module you will be creating.  Once you have that, you're ready to begin.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Introduction==&lt;br /&gt;
&lt;br /&gt;
Gateway modules allow a connection between WHMCS and gateways or credit card processors that aren't natively supported in WHMCS.&lt;br /&gt;
&lt;br /&gt;
This documentation will explain the module's structure and contains everything needed in order to successfully create a gateway module for WHMCS.&lt;br /&gt;
&lt;br /&gt;
==Getting Started==&lt;br /&gt;
&lt;br /&gt;
To get started, begin by downloading the module development kit from our GitHub site. There are two sample modules available, depending upon the [[#Module Type|type of gateway]] being developed:&lt;br /&gt;
*Third Party Gateway: https://github.com/WHMCS/sample-gateway-module&lt;br /&gt;
*Merchant Gateway: https://github.com/WHMCS/sample-merchant-gateway&lt;br /&gt;
Take the gateway module template &amp;quot;template.php&amp;quot; from this download and rename it to &amp;quot;yourgatewayname.php&amp;quot;.  It should be all lowercase and must start with a letter.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;docs-alert-info&amp;quot;&amp;gt;&lt;br /&gt;
All functions within a gateway module must be prefixed with the filename.  Open the file and replace all occurrences of '''template_''' with '''yougatewayname_'''&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Config Array===&lt;br /&gt;
&lt;br /&gt;
'''Configure the yourgatewayname_config array'''. This function is the primary function required by all gateway modules and defines both the friendly display name for the module and any custom fields/options/settings that the gateway module requires.&lt;br /&gt;
&lt;br /&gt;
The available field types are &amp;quot;text&amp;quot;, &amp;quot;dropdown&amp;quot;, &amp;quot;textarea&amp;quot; and &amp;quot;yesno&amp;quot; (checkboxes).   The sample config array in &amp;quot;template.php&amp;quot; demonstrates how to use each of these types. &lt;br /&gt;
&lt;br /&gt;
The general formula:&lt;br /&gt;
#Specify a system name (''all in lowercase for the setting to be referenced by in the module code itself'')&lt;br /&gt;
#A FriendlyName&lt;br /&gt;
#Type&lt;br /&gt;
#Any settings specific to that field type.&lt;br /&gt;
&lt;br /&gt;
Any fields defined here will be available in all gateway module functions in the $params array, so avoid common names like currency, invoiceid, etc, as these will conflict with the standard variables.&lt;br /&gt;
&lt;br /&gt;
===Module Type===&lt;br /&gt;
&lt;br /&gt;
Determine which type of module needs to be created from the 2 core types:&lt;br /&gt;
&lt;br /&gt;
#'''Third Party Gateways''' – the customer leaves your site to pay and is returned once the payment process is completed.&lt;br /&gt;
#'''Merchant Gateways''' – where the customer enters credit card details directly on your website and the payment is then processed in the background (can also include 3D Secure where the user leaves your site).&lt;br /&gt;
&lt;br /&gt;
For a Third Party gateway go to [[#Third_Party_Gateway]], and for a merchant gateway go to [[#Merchant_Gateway]].&lt;br /&gt;
&lt;br /&gt;
==Third Party Gateway==&lt;br /&gt;
&lt;br /&gt;
Follow the steps below to create a third party gateway module (one where the customer leaves your site to make the payment on the gateway provider's website):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;docs-alert-warning&amp;quot;&amp;gt;The '''_capture''' function must be deleted before activating the new gateway module in WHMCS.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# Delete the '''_capture''' function from the module template.&lt;br /&gt;
# Enter the gateway-specific code for taking the user to the payment process within the _link function.  An example of this step is shown in the gateway module template supplied with the dev kit.  Normally, the code output by this function is the HTML for a '''&amp;lt;form&amp;gt;''' with a ''post'' method.&lt;br /&gt;
&lt;br /&gt;
The available variables are:&lt;br /&gt;
&lt;br /&gt;
===Invoice Variables===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['invoiceid'] # Invoice ID Number&lt;br /&gt;
$params['description'] # Description (eg. Company Name - Invoice #xxx)&lt;br /&gt;
$params['amount'] # Format: xxx.xx&lt;br /&gt;
$params['currency'] # Currency Code (eg. GBD, USD, etc...)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Client Variables===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['clientdetails']['firstname'] # Clients First Name&lt;br /&gt;
$params['clientdetails']['lastname'] # Clients Last Name&lt;br /&gt;
$params['clientdetails']['email'] # Clients Email Address&lt;br /&gt;
$params['clientdetails']['address1'] # Clients Address&lt;br /&gt;
$params['clientdetails']['address2'] &lt;br /&gt;
$params['clientdetails']['city']&lt;br /&gt;
$params['clientdetails']['state']&lt;br /&gt;
$params['clientdetails']['postcode']&lt;br /&gt;
$params['clientdetails']['country']&lt;br /&gt;
$params['clientdetails']['phonenumber']&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===System Variables===&lt;br /&gt;
&amp;lt;source lang = &amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['companyname'] # your Company Name setting in WHMCS&lt;br /&gt;
$params['systemurl'] # the url to the Client Area&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# The processing of a payment is handled by a callback file separate from the module (see page 9 for more information).&lt;br /&gt;
# If your gateway provider doesn't support automated refunds or you won't be including them in the module, then delete the '''_refund''' function.  Otherwise, refer to the Refund section on page 7.&lt;br /&gt;
&lt;br /&gt;
==Merchant Gateway==&lt;br /&gt;
&lt;br /&gt;
A merchant gateway module is a module where the customer enters their card details directly via the client area, without leaving the site.  To create one:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;docs-alert-warning&amp;quot;&amp;gt;&lt;br /&gt;
The '''_link''' function must be deleted before activating the new gateway module in WHMCS.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# Delete the '''_link''' function from the module template.&lt;br /&gt;
# Enter the gateway-specific code for processing the payment into the '''_capture''' function.  This normally takes the format of an HTTP/Curl request to the gateway provider's API.&lt;br /&gt;
&lt;br /&gt;
The variables available are:&lt;br /&gt;
&lt;br /&gt;
===Invoice Variables===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['invoiceid'] # Invoice ID Number&lt;br /&gt;
$params['description'] # Description (eg. Company Name - Invoice #xxx)&lt;br /&gt;
$params['amount'] # Format: xxx.xx&lt;br /&gt;
$params['currency'] # Currency Code (eg. GBP, USD, etc...)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Client Variables===&lt;br /&gt;
&amp;lt;source lang = &amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['clientdetails']['firstname'] # Clients First Name&lt;br /&gt;
$params['clientdetails']['lastname'] # Clients Last Name&lt;br /&gt;
$params['clientdetails']['email'] # Clients Email Address&lt;br /&gt;
$params['clientdetails']['address1'] # Clients Address&lt;br /&gt;
$params['clientdetails']['address2']&lt;br /&gt;
$params['clientdetails']['city']&lt;br /&gt;
$params['clientdetails']['state']&lt;br /&gt;
$params['clientdetails']['postcode']&lt;br /&gt;
$params['clientdetails']['country']&lt;br /&gt;
$params['clientdetails']['phonenumber']&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===System Variables===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['companyname'] # your Company Name setting in WHMCS&lt;br /&gt;
$params['systemurl'] # the url to the Client Area&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Card Details===&lt;br /&gt;
&amp;lt;source lang = &amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['cardtype'] # the Card Type (Visa, MasterCard, etc…)&lt;br /&gt;
$params['cardnum'] # the Card Number&lt;br /&gt;
$params['cardexp'] # the Card’s Expiry Date (Format: MMYY)&lt;br /&gt;
$params['cardstart'] # the Card’s Start Date (Format: MMYY)&lt;br /&gt;
$params['cardissuenum'] # the Card’s Issue Number (Switch/Solo Cards)&lt;br /&gt;
$params['cccvv'] # Not always present (recurring transactions)&lt;br /&gt;
# but would always be present for client initiated attempts&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# Once the transaction has been processed and a response has been received, an array with the results needs to be returned to WHMCS.   For a successful capture, use the following format:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
return array(&lt;br /&gt;
    &amp;quot;status&amp;quot; =&amp;gt; &amp;quot;success&amp;quot;,&lt;br /&gt;
    &amp;quot;transid&amp;quot; =&amp;gt; $results[&amp;quot;transid&amp;quot;],&lt;br /&gt;
    &amp;quot;rawdata&amp;quot; =&amp;gt; $results,&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# The status index ''must be'' '''success''' to tell WHMCS that the capture was successful.  &lt;br /&gt;
# The transid index should be passed the value of the transaction ID that came back from the gateway.&lt;br /&gt;
# The rawdata index should be passed an array of the data returned from the gateway to be stored in the WHMCS Gateway Log.&lt;br /&gt;
&lt;br /&gt;
If the transaction were to fail, use the following format:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
return array(&lt;br /&gt;
    &amp;quot;status&amp;quot; =&amp;gt; &amp;quot;declined&amp;quot;,&lt;br /&gt;
    &amp;quot;rawdata&amp;quot; =&amp;gt; $results,&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# The status index can be any value (''declined, error, invalid hash, etc'').  This value is displayed as the reason for failure, in the gateway log.&lt;br /&gt;
# The rawdata index should be passed an array of the data returned from the gateway to be stored in the WHMCS Gateway Log for debugging purposes.&lt;br /&gt;
&lt;br /&gt;
If the gateway supports 3D Secure (Verified by Visa or MasterCard Secure Code) then please refer to page 8.&lt;br /&gt;
&lt;br /&gt;
===Refunds===&lt;br /&gt;
&lt;br /&gt;
# If the gateway provider supports automated refunds, then code for processing a refund goes into the '''_refund''' function.  This is passed all of the same variables as the '''_capture''' function, but with an added transaction id:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['transid'] # the transaction ID of the original transaction to be refunded&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The return arrays for a success or failure should be done exactly the same as described above for the '''_capture''' function.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;docs-alert-danger&amp;quot;&amp;gt;&lt;br /&gt;
If the gateway provider does not support refunds, then the '''_refund''' function should be deleted from the module file.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Callbacks==&lt;br /&gt;
If the gateway provider supports notifying a script when a payment is successful, then a callback file can be created to detect and apply those calls as payments inside WHMCS.&lt;br /&gt;
&lt;br /&gt;
A sample callback file is included in the dev kit for this purpose named '''callback.php''':&lt;br /&gt;
&lt;br /&gt;
# Rename it to match the gateway module.&lt;br /&gt;
# Modify the variables within it, as per the comments in the code.&lt;br /&gt;
# Modify it to match the variables that the specific gateway returns.&lt;br /&gt;
&lt;br /&gt;
These are some helper functions within the sample:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$GATEWAY = getGatewayVariables(‘yourgatewayname’);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function can be used to retrieve the configuration data for the module as specified in&lt;br /&gt;
the '''_config''' array. For example, it might be needed to get a gateway username or secret key to&lt;br /&gt;
validate a callback.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$invoiceid = checkCbInvoiceID($invoiceid, $GATEWAY[‘name’]);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function can be used to check that the invoice ID received back is valid. Pass the $invoiceid and the gateway name into the function.  If the invoice number is valid, the script will continue executing.  Otherwise, the script will be halted and an appropriate gateway log entry will be created.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang =&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
checkCbTransID($transid);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function can be used to check for any existing transactions already recorded for a given transaction ID, which protects against duplicate callbacks.  If the transaction ID is already in the database, the callback script execution will be halted.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
logTransaction($GATEWAY[‘name’], $_POST, &amp;quot;Successful&amp;quot;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function can be used to create a gateway log entry. The first variable needs to be the name of the gateway module, the second should be an array of data, such as the '''$_POST''' or '''$_REQUEST''' super globals, and the last variable should be the result or status to show in the log.&lt;br /&gt;
&lt;br /&gt;
== 3D Secure Process ==&lt;br /&gt;
&lt;br /&gt;
If the merchant gateway supports 3D Secure (also known as ''Verified by Visa'' or ''MasterCard Secure Code''), then it can be utilized within WHMCS.&lt;br /&gt;
&lt;br /&gt;
# Add a function to the module named '''yourgatewayname_3dsecure''' &lt;br /&gt;
# Return the HTML for the '''&amp;lt;form&amp;gt;''' post method to take the user to the 3D Secure process. &lt;br /&gt;
&lt;br /&gt;
An example of this is below:&lt;br /&gt;
&lt;br /&gt;
The '''_3dsecure''' function is passed all the same variables that the '''_capture''' function is (see page 6). The return url should be a callback file to handle the response (see page 9).&lt;br /&gt;
&lt;br /&gt;
==Example==&lt;br /&gt;
&amp;lt;source lang = &amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
function yourgatewayname_3dsecure($params) {&lt;br /&gt;
$code = '&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;https://www.gateway.com/3dsecure/&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;gwlogin&amp;quot; value=&amp;quot;'.$params[&amp;quot;loginid&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;invoiceid&amp;quot; value=&amp;quot;'.$params[&amp;quot;invoiceid&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;amount&amp;quot; value=&amp;quot;'. $params[&amp;quot;amount&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;firstname&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;firstname&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;lastname&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;lastname&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;address&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;address1&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;city&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;city&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;state&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;state&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;postcode&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;postcode&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;country&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;country&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;phonenumber&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;phonenumber&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;email&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;email&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;ccnumber&amp;quot; value=&amp;quot;'. $params[&amp;quot;cardnum&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;expirymonth&amp;quot; value=&amp;quot;'.substr($params['cardexp'],0,2).'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;expiryyear&amp;quot; value=&amp;quot;'.substr($params['cardexp'],2,2).'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;cvv2&amp;quot; value=&amp;quot;'. $params[&amp;quot;cccvv&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;return_url&amp;quot; value=&amp;quot;'.&lt;br /&gt;
$params['systemurl'].'/modules/gateways/callback/yourgatewayname.php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;noscript&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;errorbox&amp;quot;&amp;gt;&amp;lt;b&amp;gt;JavaScript is currently disabled or is not supported by your&lt;br /&gt;
browser.&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Please click the continue button to proceed with the processing of your&lt;br /&gt;
transaction.&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Continue &amp;gt;&amp;gt;&amp;quot; /&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/noscript&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;';&lt;br /&gt;
      return $code;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Tokenised Remote Storage==&lt;br /&gt;
&lt;br /&gt;
These days, with the increasing rules &amp;amp; requirements surrounding the storing of credit card details, many merchant gateways are offering services where you can perform repeat rebills without needing to store credit card details locally on your own system. And with WHMCS, gateway modules can utilise this functionality when available.&lt;br /&gt;
&lt;br /&gt;
The basic logic behind token gateways in WHMCS is that clients must either have a credit card number or a token stored in order for recurring billing to be attempted. So if you create a function named _storeremote in your custom gateway module, this function will then override the default local storage when new credit card details are entered. And instead of&lt;br /&gt;
saving in the database, that function then needs to communicate with the gateways API, and return the token that gets assigned to WHMCS.&lt;br /&gt;
&lt;br /&gt;
The variables passed into the _storeremote function are as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang =&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['gatewayid'] # the token stored for the client&lt;br /&gt;
$params['cardtype'] #the Card Type (Visa, MasterCard, etc…)&lt;br /&gt;
$params['cardnum'] # the Card Number&lt;br /&gt;
$params['cardexp'] # the Card’s Expiry Date (Format: MMYY)&lt;br /&gt;
$params['cardstart'] # the Card’s Start Date (Format: MMYY)&lt;br /&gt;
$params['cardissuenum'] # the Card’s Issue Number (Switch/Solo Cards)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
On the first call, the gatewayid will be empty. So when empty you need to create a new profile at the gateway. On subsequent calls the gatewayid that was originally created and stored will be passed in and the existing profile simply needs to be updated. And if the cardnum variable is empty, this indicates that deleting/removal of the stored credit card&lt;br /&gt;
details has been requested.&lt;br /&gt;
&lt;br /&gt;
Once the card details have been updated or stored remotely, you need to return either a success or failure response to tell WHMCS if it worked, and if it did, the token that has been assigned:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang =&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
return array(&amp;quot;status&amp;quot;=&amp;gt;&amp;quot;success&amp;quot;,&amp;quot;gatewayid&amp;quot;=&amp;gt;$results[&amp;quot;token&amp;quot;],&amp;quot;rawdata&amp;quot;=&amp;gt;$results);&lt;br /&gt;
&lt;br /&gt;
return array(&amp;quot;status&amp;quot;=&amp;gt;&amp;quot;failed&amp;quot;,&amp;quot;rawdata&amp;quot;=&amp;gt;$results);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When this function exists in a gateway module, WHMCS will only store the card type, expiry date and the last 4 digits (only) locally in the WHMCS database. So you and your clients will still be able to see exactly what card is stored remotely from within WHMCS.&lt;br /&gt;
&lt;br /&gt;
Then within the capture function, instead of $params[‘cardnum’] you will be passed $params[‘gatewayid’] with which to perform the capture.&lt;br /&gt;
&lt;br /&gt;
==Installation &amp;amp; Activation==&lt;br /&gt;
&lt;br /&gt;
To install the module you’ve created, simply upload it to the /modules/gateways/ folder and then go to Setup &amp;gt; Payment Gateways to activate. If you have create a callback file as well then that should also be uploaded but to the /modules/gateways/callback/ folder.&lt;br /&gt;
&lt;br /&gt;
'''Important:''' It is important that you do not activate your gateway module until you have&lt;br /&gt;
completed step 1 of either the third party gateway or merchant gateway module&lt;br /&gt;
documentation steps to remove the appropriate functions as it’s at the time of activation&lt;br /&gt;
that the type of module you are setting up gets stored in the system.&lt;br /&gt;
&lt;br /&gt;
==Blank Screen/Errors==&lt;br /&gt;
&lt;br /&gt;
If you get a blank page or errors in the Setup &amp;gt; Payment Gateways page after uploading your new module file then this indicates there is a syntax error in your code. To debug that, you can add the following line to your WHMCS configuration.php file to turn on error reporting:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$display_errors = true;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That will enable PHP error reporting and should show you the cause of any issues. Once you are done testing you must remember to remove that line again.&lt;br /&gt;
&lt;br /&gt;
==App Store==&lt;br /&gt;
WHMCS offers an app store in which completed gateway modules can be submitted.  The listings are displayed under the Addons tab within the administration area and online at http://www.whmcs.com/appstore . This is a great way to make WHMCS users aware of your module.&lt;br /&gt;
&lt;br /&gt;
In order to submit a listing you'll need a login for whmcs.com/members, if you do not have one please [https://www.whmcs.com/members/submitticket.php?step=2&amp;amp;deptid=5 Contact Us]. Once logged in, visit the app store page at the above URL and click the &amp;quot;Submit your Addon&amp;quot; link. We aim to review submissions in 1-2 weeks.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Developer_Links}}&lt;/div&gt;</summary>
		<author><name>Nicolas</name></author>	</entry>

	<entry>
		<id>http://3.19.219.109/index.php?title=Gateway_Module_Developer_Docs&amp;diff=17550</id>
		<title>Gateway Module Developer Docs</title>
		<link rel="alternate" type="text/html" href="http://3.19.219.109/index.php?title=Gateway_Module_Developer_Docs&amp;diff=17550"/>
				<updated>2016-01-06T20:35:51Z</updated>
		
		<summary type="html">&lt;p&gt;Nicolas: /* Callbacks */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Creating a gateway module allows you to connect WHMCS to third party payment and credit card processors that aren’t natively supported in WHMCS as standard.&lt;br /&gt;
&lt;br /&gt;
There are 2 core types of gateway module:&lt;br /&gt;
&lt;br /&gt;
#'''Third Party Gateways''' – this is where the customer leaves your site to pay and is returned once the payment process is completed&lt;br /&gt;
#'''Merchant Gateways''' – this is where the customer enters credit card details directly on your website and the payment is then processed in the background (can also include 3D Secure where the user leaves your site)&lt;br /&gt;
&lt;br /&gt;
{{Developer_Links}}&lt;br /&gt;
&lt;br /&gt;
So the first decision you need to make before starting your module for WHMCS is which type of gateway module you will be creating.  Once you have that, you're ready to begin.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Introduction==&lt;br /&gt;
&lt;br /&gt;
Gateway modules allow a connection between WHMCS and gateways or credit card processors that aren't natively supported in WHMCS.&lt;br /&gt;
&lt;br /&gt;
This documentation will explain the module's structure and contains everything needed in order to successfully create a gateway module for WHMCS.&lt;br /&gt;
&lt;br /&gt;
==Getting Started==&lt;br /&gt;
&lt;br /&gt;
To get started, begin by downloading the module development kit from our GitHub site. There are two sample modules available, depending upon the [[#Module Type|type of gateway]] being developed:&lt;br /&gt;
*Third Party Gateway: https://github.com/WHMCS/sample-gateway-module&lt;br /&gt;
*Merchant Gateway: https://github.com/WHMCS/sample-merchant-gateway&lt;br /&gt;
Take the gateway module template &amp;quot;template.php&amp;quot; from this download and rename it to &amp;quot;yourgatewayname.php&amp;quot;.  It should be all lowercase and must start with a letter.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;docs-alert-info&amp;quot;&amp;gt;&lt;br /&gt;
All functions within a gateway module must be prefixed with the filename.  Open the file and replace all occurrences of '''template_''' with '''yougatewayname_'''&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Config Array===&lt;br /&gt;
&lt;br /&gt;
'''Configure the yourgatewayname_config array'''. This function is the primary function required by all gateway modules and defines both the friendly display name for the module and any custom fields/options/settings that the gateway module requires.&lt;br /&gt;
&lt;br /&gt;
The available field types are &amp;quot;text&amp;quot;, &amp;quot;dropdown&amp;quot;, &amp;quot;textarea&amp;quot; and &amp;quot;yesno&amp;quot; (checkboxes).   The sample config array in &amp;quot;template.php&amp;quot; demonstrates how to use each of these types. &lt;br /&gt;
&lt;br /&gt;
The general formula:&lt;br /&gt;
#Specify a system name (''all in lowercase for the setting to be referenced by in the module code itself'')&lt;br /&gt;
#A FriendlyName&lt;br /&gt;
#Type&lt;br /&gt;
#Any settings specific to that field type.&lt;br /&gt;
&lt;br /&gt;
Any fields defined here will be available in all gateway module functions in the $params array, so avoid common names like currency, invoiceid, etc, as these will conflict with the standard variables.&lt;br /&gt;
&lt;br /&gt;
===Module Type===&lt;br /&gt;
&lt;br /&gt;
Determine which type of module needs to be created from the 2 core types:&lt;br /&gt;
&lt;br /&gt;
#'''Third Party Gateways''' – the customer leaves your site to pay and is returned once the payment process is completed.&lt;br /&gt;
#'''Merchant Gateways''' – where the customer enters credit card details directly on your website and the payment is then processed in the background (can also include 3D Secure where the user leaves your site).&lt;br /&gt;
&lt;br /&gt;
For a Third Party gateway go to [[#Third_Party_Gateway]], and for a merchant gateway go to [[#Merchant_Gateway]].&lt;br /&gt;
&lt;br /&gt;
==Third Party Gateway==&lt;br /&gt;
&lt;br /&gt;
Follow the steps below to create a third party gateway module (one where the customer leaves your site to make the payment on the gateway provider's website):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;docs-alert-warning&amp;quot;&amp;gt;The '''_capture''' function must be deleted before activating the new gateway module in WHMCS.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# Delete the '''_capture''' function from the module template.&lt;br /&gt;
# Enter the gateway-specific code for taking the user to the payment process within the _link function.  An example of this step is shown in the gateway module template supplied with the dev kit.  Normally, the code output by this function is the HTML for a '''&amp;lt;form&amp;gt;''' with a ''post'' method.&lt;br /&gt;
&lt;br /&gt;
The available variables are:&lt;br /&gt;
&lt;br /&gt;
===Invoice Variables===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['invoiceid'] # Invoice ID Number&lt;br /&gt;
$params['description'] # Description (eg. Company Name - Invoice #xxx)&lt;br /&gt;
$params['amount'] # Format: xxx.xx&lt;br /&gt;
$params['currency'] # Currency Code (eg. GBD, USD, etc...)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Client Variables===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['clientdetails']['firstname'] # Clients First Name&lt;br /&gt;
$params['clientdetails']['lastname'] # Clients Last Name&lt;br /&gt;
$params['clientdetails']['email'] # Clients Email Address&lt;br /&gt;
$params['clientdetails']['address1'] # Clients Address&lt;br /&gt;
$params['clientdetails']['address2'] &lt;br /&gt;
$params['clientdetails']['city']&lt;br /&gt;
$params['clientdetails']['state']&lt;br /&gt;
$params['clientdetails']['postcode']&lt;br /&gt;
$params['clientdetails']['country']&lt;br /&gt;
$params['clientdetails']['phonenumber']&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===System Variables===&lt;br /&gt;
&amp;lt;source lang = &amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['companyname'] # your Company Name setting in WHMCS&lt;br /&gt;
$params['systemurl'] # the url to the Client Area&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# The processing of a payment is handled by a callback file separate from the module (see page 9 for more information).&lt;br /&gt;
# If your gateway provider doesn't support automated refunds or you won't be including them in the module, then delete the '''_refund''' function.  Otherwise, refer to the Refund section on page 7.&lt;br /&gt;
&lt;br /&gt;
==Merchant Gateway==&lt;br /&gt;
&lt;br /&gt;
A merchant gateway module is a module where the customer enters their card details directly via the client area, without leaving the site.  To create one:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;docs-alert-warning&amp;quot;&amp;gt;&lt;br /&gt;
The '''_link''' function must be deleted before activating the new gateway module in WHMCS.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# Delete the '''_link''' function from the module template.&lt;br /&gt;
# Enter the gateway-specific code for processing the payment into the '''_capture''' function.  This normally takes the format of an HTTP/Curl request to the gateway provider's API.&lt;br /&gt;
&lt;br /&gt;
The variables available are:&lt;br /&gt;
&lt;br /&gt;
===Invoice Variables===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['invoiceid'] # Invoice ID Number&lt;br /&gt;
$params['description'] # Description (eg. Company Name - Invoice #xxx)&lt;br /&gt;
$params['amount'] # Format: xxx.xx&lt;br /&gt;
$params['currency'] # Currency Code (eg. GBP, USD, etc...)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Client Variables===&lt;br /&gt;
&amp;lt;source lang = &amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['clientdetails']['firstname'] # Clients First Name&lt;br /&gt;
$params['clientdetails']['lastname'] # Clients Last Name&lt;br /&gt;
$params['clientdetails']['email'] # Clients Email Address&lt;br /&gt;
$params['clientdetails']['address1'] # Clients Address&lt;br /&gt;
$params['clientdetails']['address2']&lt;br /&gt;
$params['clientdetails']['city']&lt;br /&gt;
$params['clientdetails']['state']&lt;br /&gt;
$params['clientdetails']['postcode']&lt;br /&gt;
$params['clientdetails']['country']&lt;br /&gt;
$params['clientdetails']['phonenumber']&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===System Variables===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['companyname'] # your Company Name setting in WHMCS&lt;br /&gt;
$params['systemurl'] # the url to the Client Area&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Card Details===&lt;br /&gt;
&amp;lt;source lang = &amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['cardtype'] # the Card Type (Visa, MasterCard, etc…)&lt;br /&gt;
$params['cardnum'] # the Card Number&lt;br /&gt;
$params['cardexp'] # the Card’s Expiry Date (Format: MMYY)&lt;br /&gt;
$params['cardstart'] # the Card’s Start Date (Format: MMYY)&lt;br /&gt;
$params['cardissuenum'] # the Card’s Issue Number (Switch/Solo Cards)&lt;br /&gt;
$params['cccvv'] # Not always present (recurring transactions)&lt;br /&gt;
# but would always be present for client initiated attempts&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# Once the transaction has been processed and a response has been received, an array with the results needs to be returned to WHMCS.   For a successful capture, use the following format:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
return array(&lt;br /&gt;
    &amp;quot;status&amp;quot; =&amp;gt; &amp;quot;success&amp;quot;,&lt;br /&gt;
    &amp;quot;transid&amp;quot; =&amp;gt; $results[&amp;quot;transid&amp;quot;],&lt;br /&gt;
    &amp;quot;rawdata&amp;quot; =&amp;gt; $results,&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# The status index ''must be'' '''success''' to tell WHMCS that the capture was successful.  &lt;br /&gt;
# The transid index should be passed the value of the transaction ID that came back from the gateway.&lt;br /&gt;
# The rawdata index should be passed an array of the data returned from the gateway to be stored in the WHMCS Gateway Log.&lt;br /&gt;
&lt;br /&gt;
If the transaction were to fail, use the following format:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
return array(&lt;br /&gt;
    &amp;quot;status&amp;quot; =&amp;gt; &amp;quot;declined&amp;quot;,&lt;br /&gt;
    &amp;quot;rawdata&amp;quot; =&amp;gt; $results,&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# The status index can be any value (''declined, error, invalid hash, etc'').  This value is displayed as the reason for failure, in the gateway log.&lt;br /&gt;
# The rawdata index should be passed an array of the data returned from the gateway to be stored in the WHMCS Gateway Log for debugging purposes.&lt;br /&gt;
&lt;br /&gt;
If the gateway supports 3D Secure (Verified by Visa or MasterCard Secure Code) then please refer to page 8.&lt;br /&gt;
&lt;br /&gt;
===Refunds===&lt;br /&gt;
&lt;br /&gt;
# If the gateway provider supports automated refunds, then code for processing a refund goes into the '''_refund''' function.  This is passed all of the same variables as the '''_capture''' function, but with an added transaction id:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['transid'] # the transaction ID of the original transaction to be refunded&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The return arrays for a success or failure should be done exactly the same as described above for the '''_capture''' function.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;docs-alert-danger&amp;quot;&amp;gt;&lt;br /&gt;
If the gateway provider does not support refunds, then the '''_refund''' function should be deleted from the module file.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Callbacks==&lt;br /&gt;
If the gateway provider supports notifying a script when a payment is successful, then a callback file can be created to detect and apply those calls as payments inside WHMCS.&lt;br /&gt;
&lt;br /&gt;
A sample callback file is included in the dev kit for this purpose named '''callback.php''':&lt;br /&gt;
&lt;br /&gt;
# Rename it to match the gateway module.&lt;br /&gt;
# Modify the variables within it, as per the comments in the code.&lt;br /&gt;
# Modify it to match the variables that the specific gateway returns.&lt;br /&gt;
&lt;br /&gt;
These are some helper functions within the sample:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$GATEWAY = getGatewayVariables(‘yourgatewayname’);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function can be used to retrieve the configuration data for the module as specified in&lt;br /&gt;
the '''_config''' array. For example, it might be needed to get a gateway username or secret key to&lt;br /&gt;
validate a callback.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$invoiceid = checkCbInvoiceID($invoiceid, $GATEWAY[‘name’]);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function can be used to check that the invoice ID received back is valid. Pass the $invoiceid and the gateway name into the function.  If the invoice number is valid, the script will continue executing.  Otherwise, the script will be halted and an appropriate gateway log entry will be created.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang =&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
checkCbTransID($transid);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function can be used to check for any existing transactions already recorded for a given transaction ID, which protects against duplicate callbacks.  If the transaction ID is already in the database, the callback script execution will be halted.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
logTransaction($GATEWAY[‘name’], $_POST, &amp;quot;Successful&amp;quot;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function can be used to create a gateway log entry. The first variable needs to be the name of the gateway module, the second should be an array of data, such as the '''$_POST''' or '''$_REQUEST''' super globals, and the last variable should be the result or status to show in the log.&lt;br /&gt;
&lt;br /&gt;
== 3D Secure Process ==&lt;br /&gt;
&lt;br /&gt;
If your merchant gateway supports 3D Secure (also known as Verified by Visa or MasterCard Secure Code) and you want to implement that then you can as WHMCS fully supports 3D Secured payments.&lt;br /&gt;
&lt;br /&gt;
To do this you need to add a function to your module named yourgatewayname_3dsecure and then similar to the _link function of a third party gateway module, you need to return the HTML for the form post to take the user to the 3D Secure process. An example of this is below.&lt;br /&gt;
&lt;br /&gt;
The _3dsecure function is passed all the same variables that the _capture function is (see page 6). Your return url should be a callback file to handle the response (see page 9)&lt;br /&gt;
&lt;br /&gt;
==Example==&lt;br /&gt;
&amp;lt;source lang = &amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
function yourgatewayname_3dsecure($params) {&lt;br /&gt;
$code = '&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;https://www.gateway.com/3dsecure/&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;gwlogin&amp;quot; value=&amp;quot;'.$params[&amp;quot;loginid&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;invoiceid&amp;quot; value=&amp;quot;'.$params[&amp;quot;invoiceid&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;amount&amp;quot; value=&amp;quot;'. $params[&amp;quot;amount&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;firstname&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;firstname&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;lastname&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;lastname&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;address&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;address1&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;city&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;city&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;state&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;state&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;postcode&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;postcode&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;country&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;country&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;phonenumber&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;phonenumber&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;email&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;email&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;ccnumber&amp;quot; value=&amp;quot;'. $params[&amp;quot;cardnum&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;expirymonth&amp;quot; value=&amp;quot;'.substr($params['cardexp'],0,2).'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;expiryyear&amp;quot; value=&amp;quot;'.substr($params['cardexp'],2,2).'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;cvv2&amp;quot; value=&amp;quot;'. $params[&amp;quot;cccvv&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;return_url&amp;quot; value=&amp;quot;'.&lt;br /&gt;
$params['systemurl'].'/modules/gateways/callback/yourgatewayname.php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;noscript&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;errorbox&amp;quot;&amp;gt;&amp;lt;b&amp;gt;JavaScript is currently disabled or is not supported by your&lt;br /&gt;
browser.&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Please click the continue button to proceed with the processing of your&lt;br /&gt;
transaction.&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Continue &amp;gt;&amp;gt;&amp;quot; /&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/noscript&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;';&lt;br /&gt;
      return $code;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Tokenised Remote Storage==&lt;br /&gt;
&lt;br /&gt;
These days, with the increasing rules &amp;amp; requirements surrounding the storing of credit card details, many merchant gateways are offering services where you can perform repeat rebills without needing to store credit card details locally on your own system. And with WHMCS, gateway modules can utilise this functionality when available.&lt;br /&gt;
&lt;br /&gt;
The basic logic behind token gateways in WHMCS is that clients must either have a credit card number or a token stored in order for recurring billing to be attempted. So if you create a function named _storeremote in your custom gateway module, this function will then override the default local storage when new credit card details are entered. And instead of&lt;br /&gt;
saving in the database, that function then needs to communicate with the gateways API, and return the token that gets assigned to WHMCS.&lt;br /&gt;
&lt;br /&gt;
The variables passed into the _storeremote function are as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang =&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['gatewayid'] # the token stored for the client&lt;br /&gt;
$params['cardtype'] #the Card Type (Visa, MasterCard, etc…)&lt;br /&gt;
$params['cardnum'] # the Card Number&lt;br /&gt;
$params['cardexp'] # the Card’s Expiry Date (Format: MMYY)&lt;br /&gt;
$params['cardstart'] # the Card’s Start Date (Format: MMYY)&lt;br /&gt;
$params['cardissuenum'] # the Card’s Issue Number (Switch/Solo Cards)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
On the first call, the gatewayid will be empty. So when empty you need to create a new profile at the gateway. On subsequent calls the gatewayid that was originally created and stored will be passed in and the existing profile simply needs to be updated. And if the cardnum variable is empty, this indicates that deleting/removal of the stored credit card&lt;br /&gt;
details has been requested.&lt;br /&gt;
&lt;br /&gt;
Once the card details have been updated or stored remotely, you need to return either a success or failure response to tell WHMCS if it worked, and if it did, the token that has been assigned:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang =&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
return array(&amp;quot;status&amp;quot;=&amp;gt;&amp;quot;success&amp;quot;,&amp;quot;gatewayid&amp;quot;=&amp;gt;$results[&amp;quot;token&amp;quot;],&amp;quot;rawdata&amp;quot;=&amp;gt;$results);&lt;br /&gt;
&lt;br /&gt;
return array(&amp;quot;status&amp;quot;=&amp;gt;&amp;quot;failed&amp;quot;,&amp;quot;rawdata&amp;quot;=&amp;gt;$results);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When this function exists in a gateway module, WHMCS will only store the card type, expiry date and the last 4 digits (only) locally in the WHMCS database. So you and your clients will still be able to see exactly what card is stored remotely from within WHMCS.&lt;br /&gt;
&lt;br /&gt;
Then within the capture function, instead of $params[‘cardnum’] you will be passed $params[‘gatewayid’] with which to perform the capture.&lt;br /&gt;
&lt;br /&gt;
==Installation &amp;amp; Activation==&lt;br /&gt;
&lt;br /&gt;
To install the module you’ve created, simply upload it to the /modules/gateways/ folder and then go to Setup &amp;gt; Payment Gateways to activate. If you have create a callback file as well then that should also be uploaded but to the /modules/gateways/callback/ folder.&lt;br /&gt;
&lt;br /&gt;
'''Important:''' It is important that you do not activate your gateway module until you have&lt;br /&gt;
completed step 1 of either the third party gateway or merchant gateway module&lt;br /&gt;
documentation steps to remove the appropriate functions as it’s at the time of activation&lt;br /&gt;
that the type of module you are setting up gets stored in the system.&lt;br /&gt;
&lt;br /&gt;
==Blank Screen/Errors==&lt;br /&gt;
&lt;br /&gt;
If you get a blank page or errors in the Setup &amp;gt; Payment Gateways page after uploading your new module file then this indicates there is a syntax error in your code. To debug that, you can add the following line to your WHMCS configuration.php file to turn on error reporting:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$display_errors = true;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That will enable PHP error reporting and should show you the cause of any issues. Once you are done testing you must remember to remove that line again.&lt;br /&gt;
&lt;br /&gt;
==App Store==&lt;br /&gt;
WHMCS offers an app store in which completed gateway modules can be submitted.  The listings are displayed under the Addons tab within the administration area and online at http://www.whmcs.com/appstore . This is a great way to make WHMCS users aware of your module.&lt;br /&gt;
&lt;br /&gt;
In order to submit a listing you'll need a login for whmcs.com/members, if you do not have one please [https://www.whmcs.com/members/submitticket.php?step=2&amp;amp;deptid=5 Contact Us]. Once logged in, visit the app store page at the above URL and click the &amp;quot;Submit your Addon&amp;quot; link. We aim to review submissions in 1-2 weeks.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Developer_Links}}&lt;/div&gt;</summary>
		<author><name>Nicolas</name></author>	</entry>

	<entry>
		<id>http://3.19.219.109/index.php?title=Gateway_Module_Developer_Docs&amp;diff=17547</id>
		<title>Gateway Module Developer Docs</title>
		<link rel="alternate" type="text/html" href="http://3.19.219.109/index.php?title=Gateway_Module_Developer_Docs&amp;diff=17547"/>
				<updated>2016-01-06T20:19:33Z</updated>
		
		<summary type="html">&lt;p&gt;Nicolas: /* Card Details */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Creating a gateway module allows you to connect WHMCS to third party payment and credit card processors that aren’t natively supported in WHMCS as standard.&lt;br /&gt;
&lt;br /&gt;
There are 2 core types of gateway module:&lt;br /&gt;
&lt;br /&gt;
#'''Third Party Gateways''' – this is where the customer leaves your site to pay and is returned once the payment process is completed&lt;br /&gt;
#'''Merchant Gateways''' – this is where the customer enters credit card details directly on your website and the payment is then processed in the background (can also include 3D Secure where the user leaves your site)&lt;br /&gt;
&lt;br /&gt;
{{Developer_Links}}&lt;br /&gt;
&lt;br /&gt;
So the first decision you need to make before starting your module for WHMCS is which type of gateway module you will be creating.  Once you have that, you're ready to begin.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Introduction==&lt;br /&gt;
&lt;br /&gt;
Gateway modules allow a connection between WHMCS and gateways or credit card processors that aren't natively supported in WHMCS.&lt;br /&gt;
&lt;br /&gt;
This documentation will explain the module's structure and contains everything needed in order to successfully create a gateway module for WHMCS.&lt;br /&gt;
&lt;br /&gt;
==Getting Started==&lt;br /&gt;
&lt;br /&gt;
To get started, begin by downloading the module development kit from our GitHub site. There are two sample modules available, depending upon the [[#Module Type|type of gateway]] being developed:&lt;br /&gt;
*Third Party Gateway: https://github.com/WHMCS/sample-gateway-module&lt;br /&gt;
*Merchant Gateway: https://github.com/WHMCS/sample-merchant-gateway&lt;br /&gt;
Take the gateway module template &amp;quot;template.php&amp;quot; from this download and rename it to &amp;quot;yourgatewayname.php&amp;quot;.  It should be all lowercase and must start with a letter.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;docs-alert-info&amp;quot;&amp;gt;&lt;br /&gt;
All functions within a gateway module must be prefixed with the filename.  Open the file and replace all occurrences of '''template_''' with '''yougatewayname_'''&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Config Array===&lt;br /&gt;
&lt;br /&gt;
'''Configure the yourgatewayname_config array'''. This function is the primary function required by all gateway modules and defines both the friendly display name for the module and any custom fields/options/settings that the gateway module requires.&lt;br /&gt;
&lt;br /&gt;
The available field types are &amp;quot;text&amp;quot;, &amp;quot;dropdown&amp;quot;, &amp;quot;textarea&amp;quot; and &amp;quot;yesno&amp;quot; (checkboxes).   The sample config array in &amp;quot;template.php&amp;quot; demonstrates how to use each of these types. &lt;br /&gt;
&lt;br /&gt;
The general formula:&lt;br /&gt;
#Specify a system name (''all in lowercase for the setting to be referenced by in the module code itself'')&lt;br /&gt;
#A FriendlyName&lt;br /&gt;
#Type&lt;br /&gt;
#Any settings specific to that field type.&lt;br /&gt;
&lt;br /&gt;
Any fields defined here will be available in all gateway module functions in the $params array, so avoid common names like currency, invoiceid, etc, as these will conflict with the standard variables.&lt;br /&gt;
&lt;br /&gt;
===Module Type===&lt;br /&gt;
&lt;br /&gt;
Determine which type of module needs to be created from the 2 core types:&lt;br /&gt;
&lt;br /&gt;
#'''Third Party Gateways''' – the customer leaves your site to pay and is returned once the payment process is completed.&lt;br /&gt;
#'''Merchant Gateways''' – where the customer enters credit card details directly on your website and the payment is then processed in the background (can also include 3D Secure where the user leaves your site).&lt;br /&gt;
&lt;br /&gt;
For a Third Party gateway go to [[#Third_Party_Gateway]], and for a merchant gateway go to [[#Merchant_Gateway]].&lt;br /&gt;
&lt;br /&gt;
==Third Party Gateway==&lt;br /&gt;
&lt;br /&gt;
Follow the steps below to create a third party gateway module (one where the customer leaves your site to make the payment on the gateway provider's website):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;docs-alert-warning&amp;quot;&amp;gt;The '''_capture''' function must be deleted before activating the new gateway module in WHMCS.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# Delete the '''_capture''' function from the module template.&lt;br /&gt;
# Enter the gateway-specific code for taking the user to the payment process within the _link function.  An example of this step is shown in the gateway module template supplied with the dev kit.  Normally, the code output by this function is the HTML for a '''&amp;lt;form&amp;gt;''' with a ''post'' method.&lt;br /&gt;
&lt;br /&gt;
The available variables are:&lt;br /&gt;
&lt;br /&gt;
===Invoice Variables===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['invoiceid'] # Invoice ID Number&lt;br /&gt;
$params['description'] # Description (eg. Company Name - Invoice #xxx)&lt;br /&gt;
$params['amount'] # Format: xxx.xx&lt;br /&gt;
$params['currency'] # Currency Code (eg. GBD, USD, etc...)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Client Variables===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['clientdetails']['firstname'] # Clients First Name&lt;br /&gt;
$params['clientdetails']['lastname'] # Clients Last Name&lt;br /&gt;
$params['clientdetails']['email'] # Clients Email Address&lt;br /&gt;
$params['clientdetails']['address1'] # Clients Address&lt;br /&gt;
$params['clientdetails']['address2'] &lt;br /&gt;
$params['clientdetails']['city']&lt;br /&gt;
$params['clientdetails']['state']&lt;br /&gt;
$params['clientdetails']['postcode']&lt;br /&gt;
$params['clientdetails']['country']&lt;br /&gt;
$params['clientdetails']['phonenumber']&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===System Variables===&lt;br /&gt;
&amp;lt;source lang = &amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['companyname'] # your Company Name setting in WHMCS&lt;br /&gt;
$params['systemurl'] # the url to the Client Area&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# The processing of a payment is handled by a callback file separate from the module (see page 9 for more information).&lt;br /&gt;
# If your gateway provider doesn't support automated refunds or you won't be including them in the module, then delete the '''_refund''' function.  Otherwise, refer to the Refund section on page 7.&lt;br /&gt;
&lt;br /&gt;
==Merchant Gateway==&lt;br /&gt;
&lt;br /&gt;
A merchant gateway module is a module where the customer enters their card details directly via the client area, without leaving the site.  To create one:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;docs-alert-warning&amp;quot;&amp;gt;&lt;br /&gt;
The '''_link''' function must be deleted before activating the new gateway module in WHMCS.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# Delete the '''_link''' function from the module template.&lt;br /&gt;
# Enter the gateway-specific code for processing the payment into the '''_capture''' function.  This normally takes the format of an HTTP/Curl request to the gateway provider's API.&lt;br /&gt;
&lt;br /&gt;
The variables available are:&lt;br /&gt;
&lt;br /&gt;
===Invoice Variables===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['invoiceid'] # Invoice ID Number&lt;br /&gt;
$params['description'] # Description (eg. Company Name - Invoice #xxx)&lt;br /&gt;
$params['amount'] # Format: xxx.xx&lt;br /&gt;
$params['currency'] # Currency Code (eg. GBP, USD, etc...)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Client Variables===&lt;br /&gt;
&amp;lt;source lang = &amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['clientdetails']['firstname'] # Clients First Name&lt;br /&gt;
$params['clientdetails']['lastname'] # Clients Last Name&lt;br /&gt;
$params['clientdetails']['email'] # Clients Email Address&lt;br /&gt;
$params['clientdetails']['address1'] # Clients Address&lt;br /&gt;
$params['clientdetails']['address2']&lt;br /&gt;
$params['clientdetails']['city']&lt;br /&gt;
$params['clientdetails']['state']&lt;br /&gt;
$params['clientdetails']['postcode']&lt;br /&gt;
$params['clientdetails']['country']&lt;br /&gt;
$params['clientdetails']['phonenumber']&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===System Variables===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['companyname'] # your Company Name setting in WHMCS&lt;br /&gt;
$params['systemurl'] # the url to the Client Area&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Card Details===&lt;br /&gt;
&amp;lt;source lang = &amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['cardtype'] # the Card Type (Visa, MasterCard, etc…)&lt;br /&gt;
$params['cardnum'] # the Card Number&lt;br /&gt;
$params['cardexp'] # the Card’s Expiry Date (Format: MMYY)&lt;br /&gt;
$params['cardstart'] # the Card’s Start Date (Format: MMYY)&lt;br /&gt;
$params['cardissuenum'] # the Card’s Issue Number (Switch/Solo Cards)&lt;br /&gt;
$params['cccvv'] # Not always present (recurring transactions)&lt;br /&gt;
# but would always be present for client initiated attempts&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# Once the transaction has been processed and a response has been received, an array with the results needs to be returned to WHMCS.   For a successful capture, use the following format:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
return array(&lt;br /&gt;
    &amp;quot;status&amp;quot; =&amp;gt; &amp;quot;success&amp;quot;,&lt;br /&gt;
    &amp;quot;transid&amp;quot; =&amp;gt; $results[&amp;quot;transid&amp;quot;],&lt;br /&gt;
    &amp;quot;rawdata&amp;quot; =&amp;gt; $results,&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# The status index ''must be'' '''success''' to tell WHMCS that the capture was successful.  &lt;br /&gt;
# The transid index should be passed the value of the transaction ID that came back from the gateway.&lt;br /&gt;
# The rawdata index should be passed an array of the data returned from the gateway to be stored in the WHMCS Gateway Log.&lt;br /&gt;
&lt;br /&gt;
If the transaction were to fail, use the following format:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
return array(&lt;br /&gt;
    &amp;quot;status&amp;quot; =&amp;gt; &amp;quot;declined&amp;quot;,&lt;br /&gt;
    &amp;quot;rawdata&amp;quot; =&amp;gt; $results,&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# The status index can be any value (''declined, error, invalid hash, etc'').  This value is displayed as the reason for failure, in the gateway log.&lt;br /&gt;
# The rawdata index should be passed an array of the data returned from the gateway to be stored in the WHMCS Gateway Log for debugging purposes.&lt;br /&gt;
&lt;br /&gt;
If the gateway supports 3D Secure (Verified by Visa or MasterCard Secure Code) then please refer to page 8.&lt;br /&gt;
&lt;br /&gt;
===Refunds===&lt;br /&gt;
&lt;br /&gt;
# If the gateway provider supports automated refunds, then code for processing a refund goes into the '''_refund''' function.  This is passed all of the same variables as the '''_capture''' function, but with an added transaction id:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['transid'] # the transaction ID of the original transaction to be refunded&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The return arrays for a success or failure should be done exactly the same as described above for the '''_capture''' function.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;docs-alert-danger&amp;quot;&amp;gt;&lt;br /&gt;
If the gateway provider does not support refunds, then the '''_refund''' function should be deleted from the module file.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Callbacks==&lt;br /&gt;
If your gateway provider supports notifying a script when a payment is successful, then you can create a callback file in WHMCS to detect and apply those calls as payments inside WHMCS.&lt;br /&gt;
&lt;br /&gt;
A sample callback file is included in the dev kit for this purpose named “callback.php”. To utilise this script, you simply need to rename it to match your gateway module, and modify the variables within it as per the comments in the code, and to match the variables your specific gateway returns.&lt;br /&gt;
&lt;br /&gt;
These are some helper functions within the sample that you might find useful:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$GATEWAY = getGatewayVariables(‘yourgatewayname’);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function can be used to retrieve the configuration data for your module as specified in&lt;br /&gt;
the _config array. For example you might need it to get a gateway username or secret key to&lt;br /&gt;
validate a callback.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$invoiceid = checkCbInvoiceID($invoiceid,$GATEWAY[‘name’]);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function can be used to check the invoice ID received back is valid. You should simply pass the $invoiceid into this function and your gateway name and if a valid invoice number the script will continue executing, otherwise the script will be halted and an appropriate gateway log entry created.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang =&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
checkCbTransID($transid);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function can be used to check for any existing transactions already recorded for a given transaction ID. This can be useful for protecting against duplicate callbacks as if the transaction ID is already found in the database, the callback script execution will be halted.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
logTransaction($GATEWAY[‘name’],$_POST,&amp;quot;Successful&amp;quot;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function can be used to create a gateway log entry. The first variable needs to be the name of the gateway module, the second should be an array of data, such as the $_POST or $_REQUEST super globals, and the last variable should be the result/status to show in the log.&lt;br /&gt;
&lt;br /&gt;
== 3D Secure Process ==&lt;br /&gt;
&lt;br /&gt;
If your merchant gateway supports 3D Secure (also known as Verified by Visa or MasterCard Secure Code) and you want to implement that then you can as WHMCS fully supports 3D Secured payments.&lt;br /&gt;
&lt;br /&gt;
To do this you need to add a function to your module named yourgatewayname_3dsecure and then similar to the _link function of a third party gateway module, you need to return the HTML for the form post to take the user to the 3D Secure process. An example of this is below.&lt;br /&gt;
&lt;br /&gt;
The _3dsecure function is passed all the same variables that the _capture function is (see page 6). Your return url should be a callback file to handle the response (see page 9)&lt;br /&gt;
&lt;br /&gt;
==Example==&lt;br /&gt;
&amp;lt;source lang = &amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
function yourgatewayname_3dsecure($params) {&lt;br /&gt;
$code = '&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;https://www.gateway.com/3dsecure/&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;gwlogin&amp;quot; value=&amp;quot;'.$params[&amp;quot;loginid&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;invoiceid&amp;quot; value=&amp;quot;'.$params[&amp;quot;invoiceid&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;amount&amp;quot; value=&amp;quot;'. $params[&amp;quot;amount&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;firstname&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;firstname&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;lastname&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;lastname&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;address&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;address1&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;city&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;city&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;state&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;state&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;postcode&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;postcode&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;country&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;country&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;phonenumber&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;phonenumber&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;email&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;email&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;ccnumber&amp;quot; value=&amp;quot;'. $params[&amp;quot;cardnum&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;expirymonth&amp;quot; value=&amp;quot;'.substr($params['cardexp'],0,2).'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;expiryyear&amp;quot; value=&amp;quot;'.substr($params['cardexp'],2,2).'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;cvv2&amp;quot; value=&amp;quot;'. $params[&amp;quot;cccvv&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;return_url&amp;quot; value=&amp;quot;'.&lt;br /&gt;
$params['systemurl'].'/modules/gateways/callback/yourgatewayname.php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;noscript&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;errorbox&amp;quot;&amp;gt;&amp;lt;b&amp;gt;JavaScript is currently disabled or is not supported by your&lt;br /&gt;
browser.&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Please click the continue button to proceed with the processing of your&lt;br /&gt;
transaction.&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Continue &amp;gt;&amp;gt;&amp;quot; /&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/noscript&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;';&lt;br /&gt;
      return $code;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Tokenised Remote Storage==&lt;br /&gt;
&lt;br /&gt;
These days, with the increasing rules &amp;amp; requirements surrounding the storing of credit card details, many merchant gateways are offering services where you can perform repeat rebills without needing to store credit card details locally on your own system. And with WHMCS, gateway modules can utilise this functionality when available.&lt;br /&gt;
&lt;br /&gt;
The basic logic behind token gateways in WHMCS is that clients must either have a credit card number or a token stored in order for recurring billing to be attempted. So if you create a function named _storeremote in your custom gateway module, this function will then override the default local storage when new credit card details are entered. And instead of&lt;br /&gt;
saving in the database, that function then needs to communicate with the gateways API, and return the token that gets assigned to WHMCS.&lt;br /&gt;
&lt;br /&gt;
The variables passed into the _storeremote function are as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang =&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['gatewayid'] # the token stored for the client&lt;br /&gt;
$params['cardtype'] #the Card Type (Visa, MasterCard, etc…)&lt;br /&gt;
$params['cardnum'] # the Card Number&lt;br /&gt;
$params['cardexp'] # the Card’s Expiry Date (Format: MMYY)&lt;br /&gt;
$params['cardstart'] # the Card’s Start Date (Format: MMYY)&lt;br /&gt;
$params['cardissuenum'] # the Card’s Issue Number (Switch/Solo Cards)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
On the first call, the gatewayid will be empty. So when empty you need to create a new profile at the gateway. On subsequent calls the gatewayid that was originally created and stored will be passed in and the existing profile simply needs to be updated. And if the cardnum variable is empty, this indicates that deleting/removal of the stored credit card&lt;br /&gt;
details has been requested.&lt;br /&gt;
&lt;br /&gt;
Once the card details have been updated or stored remotely, you need to return either a success or failure response to tell WHMCS if it worked, and if it did, the token that has been assigned:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang =&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
return array(&amp;quot;status&amp;quot;=&amp;gt;&amp;quot;success&amp;quot;,&amp;quot;gatewayid&amp;quot;=&amp;gt;$results[&amp;quot;token&amp;quot;],&amp;quot;rawdata&amp;quot;=&amp;gt;$results);&lt;br /&gt;
&lt;br /&gt;
return array(&amp;quot;status&amp;quot;=&amp;gt;&amp;quot;failed&amp;quot;,&amp;quot;rawdata&amp;quot;=&amp;gt;$results);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When this function exists in a gateway module, WHMCS will only store the card type, expiry date and the last 4 digits (only) locally in the WHMCS database. So you and your clients will still be able to see exactly what card is stored remotely from within WHMCS.&lt;br /&gt;
&lt;br /&gt;
Then within the capture function, instead of $params[‘cardnum’] you will be passed $params[‘gatewayid’] with which to perform the capture.&lt;br /&gt;
&lt;br /&gt;
==Installation &amp;amp; Activation==&lt;br /&gt;
&lt;br /&gt;
To install the module you’ve created, simply upload it to the /modules/gateways/ folder and then go to Setup &amp;gt; Payment Gateways to activate. If you have create a callback file as well then that should also be uploaded but to the /modules/gateways/callback/ folder.&lt;br /&gt;
&lt;br /&gt;
'''Important:''' It is important that you do not activate your gateway module until you have&lt;br /&gt;
completed step 1 of either the third party gateway or merchant gateway module&lt;br /&gt;
documentation steps to remove the appropriate functions as it’s at the time of activation&lt;br /&gt;
that the type of module you are setting up gets stored in the system.&lt;br /&gt;
&lt;br /&gt;
==Blank Screen/Errors==&lt;br /&gt;
&lt;br /&gt;
If you get a blank page or errors in the Setup &amp;gt; Payment Gateways page after uploading your new module file then this indicates there is a syntax error in your code. To debug that, you can add the following line to your WHMCS configuration.php file to turn on error reporting:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$display_errors = true;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That will enable PHP error reporting and should show you the cause of any issues. Once you are done testing you must remember to remove that line again.&lt;br /&gt;
&lt;br /&gt;
==App Store==&lt;br /&gt;
WHMCS offers an app store in which completed gateway modules can be submitted.  The listings are displayed under the Addons tab within the administration area and online at http://www.whmcs.com/appstore . This is a great way to make WHMCS users aware of your module.&lt;br /&gt;
&lt;br /&gt;
In order to submit a listing you'll need a login for whmcs.com/members, if you do not have one please [https://www.whmcs.com/members/submitticket.php?step=2&amp;amp;deptid=5 Contact Us]. Once logged in, visit the app store page at the above URL and click the &amp;quot;Submit your Addon&amp;quot; link. We aim to review submissions in 1-2 weeks.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Developer_Links}}&lt;/div&gt;</summary>
		<author><name>Nicolas</name></author>	</entry>

	<entry>
		<id>http://3.19.219.109/index.php?title=Gateway_Module_Developer_Docs&amp;diff=17546</id>
		<title>Gateway Module Developer Docs</title>
		<link rel="alternate" type="text/html" href="http://3.19.219.109/index.php?title=Gateway_Module_Developer_Docs&amp;diff=17546"/>
				<updated>2016-01-06T20:18:29Z</updated>
		
		<summary type="html">&lt;p&gt;Nicolas: /* Merchant Gateway */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Creating a gateway module allows you to connect WHMCS to third party payment and credit card processors that aren’t natively supported in WHMCS as standard.&lt;br /&gt;
&lt;br /&gt;
There are 2 core types of gateway module:&lt;br /&gt;
&lt;br /&gt;
#'''Third Party Gateways''' – this is where the customer leaves your site to pay and is returned once the payment process is completed&lt;br /&gt;
#'''Merchant Gateways''' – this is where the customer enters credit card details directly on your website and the payment is then processed in the background (can also include 3D Secure where the user leaves your site)&lt;br /&gt;
&lt;br /&gt;
{{Developer_Links}}&lt;br /&gt;
&lt;br /&gt;
So the first decision you need to make before starting your module for WHMCS is which type of gateway module you will be creating.  Once you have that, you're ready to begin.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Introduction==&lt;br /&gt;
&lt;br /&gt;
Gateway modules allow a connection between WHMCS and gateways or credit card processors that aren't natively supported in WHMCS.&lt;br /&gt;
&lt;br /&gt;
This documentation will explain the module's structure and contains everything needed in order to successfully create a gateway module for WHMCS.&lt;br /&gt;
&lt;br /&gt;
==Getting Started==&lt;br /&gt;
&lt;br /&gt;
To get started, begin by downloading the module development kit from our GitHub site. There are two sample modules available, depending upon the [[#Module Type|type of gateway]] being developed:&lt;br /&gt;
*Third Party Gateway: https://github.com/WHMCS/sample-gateway-module&lt;br /&gt;
*Merchant Gateway: https://github.com/WHMCS/sample-merchant-gateway&lt;br /&gt;
Take the gateway module template &amp;quot;template.php&amp;quot; from this download and rename it to &amp;quot;yourgatewayname.php&amp;quot;.  It should be all lowercase and must start with a letter.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;docs-alert-info&amp;quot;&amp;gt;&lt;br /&gt;
All functions within a gateway module must be prefixed with the filename.  Open the file and replace all occurrences of '''template_''' with '''yougatewayname_'''&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Config Array===&lt;br /&gt;
&lt;br /&gt;
'''Configure the yourgatewayname_config array'''. This function is the primary function required by all gateway modules and defines both the friendly display name for the module and any custom fields/options/settings that the gateway module requires.&lt;br /&gt;
&lt;br /&gt;
The available field types are &amp;quot;text&amp;quot;, &amp;quot;dropdown&amp;quot;, &amp;quot;textarea&amp;quot; and &amp;quot;yesno&amp;quot; (checkboxes).   The sample config array in &amp;quot;template.php&amp;quot; demonstrates how to use each of these types. &lt;br /&gt;
&lt;br /&gt;
The general formula:&lt;br /&gt;
#Specify a system name (''all in lowercase for the setting to be referenced by in the module code itself'')&lt;br /&gt;
#A FriendlyName&lt;br /&gt;
#Type&lt;br /&gt;
#Any settings specific to that field type.&lt;br /&gt;
&lt;br /&gt;
Any fields defined here will be available in all gateway module functions in the $params array, so avoid common names like currency, invoiceid, etc, as these will conflict with the standard variables.&lt;br /&gt;
&lt;br /&gt;
===Module Type===&lt;br /&gt;
&lt;br /&gt;
Determine which type of module needs to be created from the 2 core types:&lt;br /&gt;
&lt;br /&gt;
#'''Third Party Gateways''' – the customer leaves your site to pay and is returned once the payment process is completed.&lt;br /&gt;
#'''Merchant Gateways''' – where the customer enters credit card details directly on your website and the payment is then processed in the background (can also include 3D Secure where the user leaves your site).&lt;br /&gt;
&lt;br /&gt;
For a Third Party gateway go to [[#Third_Party_Gateway]], and for a merchant gateway go to [[#Merchant_Gateway]].&lt;br /&gt;
&lt;br /&gt;
==Third Party Gateway==&lt;br /&gt;
&lt;br /&gt;
Follow the steps below to create a third party gateway module (one where the customer leaves your site to make the payment on the gateway provider's website):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;docs-alert-warning&amp;quot;&amp;gt;The '''_capture''' function must be deleted before activating the new gateway module in WHMCS.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# Delete the '''_capture''' function from the module template.&lt;br /&gt;
# Enter the gateway-specific code for taking the user to the payment process within the _link function.  An example of this step is shown in the gateway module template supplied with the dev kit.  Normally, the code output by this function is the HTML for a '''&amp;lt;form&amp;gt;''' with a ''post'' method.&lt;br /&gt;
&lt;br /&gt;
The available variables are:&lt;br /&gt;
&lt;br /&gt;
===Invoice Variables===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['invoiceid'] # Invoice ID Number&lt;br /&gt;
$params['description'] # Description (eg. Company Name - Invoice #xxx)&lt;br /&gt;
$params['amount'] # Format: xxx.xx&lt;br /&gt;
$params['currency'] # Currency Code (eg. GBD, USD, etc...)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Client Variables===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['clientdetails']['firstname'] # Clients First Name&lt;br /&gt;
$params['clientdetails']['lastname'] # Clients Last Name&lt;br /&gt;
$params['clientdetails']['email'] # Clients Email Address&lt;br /&gt;
$params['clientdetails']['address1'] # Clients Address&lt;br /&gt;
$params['clientdetails']['address2'] &lt;br /&gt;
$params['clientdetails']['city']&lt;br /&gt;
$params['clientdetails']['state']&lt;br /&gt;
$params['clientdetails']['postcode']&lt;br /&gt;
$params['clientdetails']['country']&lt;br /&gt;
$params['clientdetails']['phonenumber']&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===System Variables===&lt;br /&gt;
&amp;lt;source lang = &amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['companyname'] # your Company Name setting in WHMCS&lt;br /&gt;
$params['systemurl'] # the url to the Client Area&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# The processing of a payment is handled by a callback file separate from the module (see page 9 for more information).&lt;br /&gt;
# If your gateway provider doesn't support automated refunds or you won't be including them in the module, then delete the '''_refund''' function.  Otherwise, refer to the Refund section on page 7.&lt;br /&gt;
&lt;br /&gt;
==Merchant Gateway==&lt;br /&gt;
&lt;br /&gt;
A merchant gateway module is a module where the customer enters their card details directly via the client area, without leaving the site.  To create one:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;docs-alert-warning&amp;quot;&amp;gt;&lt;br /&gt;
The '''_link''' function must be deleted before activating the new gateway module in WHMCS.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# Delete the '''_link''' function from the module template.&lt;br /&gt;
# Enter the gateway-specific code for processing the payment into the '''_capture''' function.  This normally takes the format of an HTTP/Curl request to the gateway provider's API.&lt;br /&gt;
&lt;br /&gt;
The variables available are:&lt;br /&gt;
&lt;br /&gt;
===Invoice Variables===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['invoiceid'] # Invoice ID Number&lt;br /&gt;
$params['description'] # Description (eg. Company Name - Invoice #xxx)&lt;br /&gt;
$params['amount'] # Format: xxx.xx&lt;br /&gt;
$params['currency'] # Currency Code (eg. GBP, USD, etc...)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Client Variables===&lt;br /&gt;
&amp;lt;source lang = &amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['clientdetails']['firstname'] # Clients First Name&lt;br /&gt;
$params['clientdetails']['lastname'] # Clients Last Name&lt;br /&gt;
$params['clientdetails']['email'] # Clients Email Address&lt;br /&gt;
$params['clientdetails']['address1'] # Clients Address&lt;br /&gt;
$params['clientdetails']['address2']&lt;br /&gt;
$params['clientdetails']['city']&lt;br /&gt;
$params['clientdetails']['state']&lt;br /&gt;
$params['clientdetails']['postcode']&lt;br /&gt;
$params['clientdetails']['country']&lt;br /&gt;
$params['clientdetails']['phonenumber']&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===System Variables===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['companyname'] # your Company Name setting in WHMCS&lt;br /&gt;
$params['systemurl'] # the url to the Client Area&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Card Details===&lt;br /&gt;
&amp;lt;source lang = &amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['cardtype'] # the Card Type (Visa, MasterCard, etc…)&lt;br /&gt;
$params['cardnum'] # the Card Number&lt;br /&gt;
$params['cardexp'] # the Card’s Expiry Date (Format: MMYY)&lt;br /&gt;
$params['cardstart'] # the Card’s Start Date (Format: MMYY)&lt;br /&gt;
$params['cardissuenum'] # the Card’s Issue Number (Switch/Solo Cards)&lt;br /&gt;
$params['cccvv'] # Not always present (recurring transactions)&lt;br /&gt;
# but would always be present for client initiated attempts&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# Once the transaction has been processed and a response has been received, an array with the results needs to be returned to WHMCS.   For a successful capture, use the following format:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
return array(&lt;br /&gt;
    &amp;quot;status&amp;quot; =&amp;gt; &amp;quot;success&amp;quot;,&lt;br /&gt;
    &amp;quot;transid&amp;quot; =&amp;gt; $results[&amp;quot;transid&amp;quot;],&lt;br /&gt;
    &amp;quot;rawdata&amp;quot; =&amp;gt; $results,&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# The status index ''must be'' '''success''' to tell WHMCS that the capture was successful.  &lt;br /&gt;
# The transid index should be passed the value of the transaction ID that came back from the gateway.&lt;br /&gt;
# The rawdata index should be passed an array of the data returned from the gateway to be stored in the WHMCS Gateway Log.&lt;br /&gt;
&lt;br /&gt;
If the transaction were to fail, use the following format:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
return array(&lt;br /&gt;
    &amp;quot;status&amp;quot; =&amp;gt; &amp;quot;declined&amp;quot;,&lt;br /&gt;
    &amp;quot;rawdata&amp;quot; =&amp;gt; $results,&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# The status index can be any value (''declined, error, invalid hash, etc'').  This value is displayed as the reason for failure, in the gateway log.&lt;br /&gt;
# The rawdata index should be passed an array of the data returned from the gateway to be stored in the WHMCS Gateway Log for debugging purposes.&lt;br /&gt;
&lt;br /&gt;
# If the gateway supports 3D Secure (Verified by Visa or MasterCard Secure Code) then please refer to page 8.&lt;br /&gt;
&lt;br /&gt;
===Refunds===&lt;br /&gt;
&lt;br /&gt;
# If the gateway provider supports automated refunds, then code for processing a refund goes into the '''_refund''' function.  This is passed all of the same variables as the '''_capture''' function, but with an added transaction id:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['transid'] # the transaction ID of the original transaction to be refunded&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The return arrays for a success or failure should be done exactly the same as described above for the '''_capture''' function.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;docs-alert-danger&amp;quot;&amp;gt;&lt;br /&gt;
If the gateway provider does not support refunds, then the '''_refund''' function should be deleted from the module file.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Callbacks==&lt;br /&gt;
If your gateway provider supports notifying a script when a payment is successful, then you can create a callback file in WHMCS to detect and apply those calls as payments inside WHMCS.&lt;br /&gt;
&lt;br /&gt;
A sample callback file is included in the dev kit for this purpose named “callback.php”. To utilise this script, you simply need to rename it to match your gateway module, and modify the variables within it as per the comments in the code, and to match the variables your specific gateway returns.&lt;br /&gt;
&lt;br /&gt;
These are some helper functions within the sample that you might find useful:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$GATEWAY = getGatewayVariables(‘yourgatewayname’);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function can be used to retrieve the configuration data for your module as specified in&lt;br /&gt;
the _config array. For example you might need it to get a gateway username or secret key to&lt;br /&gt;
validate a callback.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$invoiceid = checkCbInvoiceID($invoiceid,$GATEWAY[‘name’]);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function can be used to check the invoice ID received back is valid. You should simply pass the $invoiceid into this function and your gateway name and if a valid invoice number the script will continue executing, otherwise the script will be halted and an appropriate gateway log entry created.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang =&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
checkCbTransID($transid);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function can be used to check for any existing transactions already recorded for a given transaction ID. This can be useful for protecting against duplicate callbacks as if the transaction ID is already found in the database, the callback script execution will be halted.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
logTransaction($GATEWAY[‘name’],$_POST,&amp;quot;Successful&amp;quot;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function can be used to create a gateway log entry. The first variable needs to be the name of the gateway module, the second should be an array of data, such as the $_POST or $_REQUEST super globals, and the last variable should be the result/status to show in the log.&lt;br /&gt;
&lt;br /&gt;
== 3D Secure Process ==&lt;br /&gt;
&lt;br /&gt;
If your merchant gateway supports 3D Secure (also known as Verified by Visa or MasterCard Secure Code) and you want to implement that then you can as WHMCS fully supports 3D Secured payments.&lt;br /&gt;
&lt;br /&gt;
To do this you need to add a function to your module named yourgatewayname_3dsecure and then similar to the _link function of a third party gateway module, you need to return the HTML for the form post to take the user to the 3D Secure process. An example of this is below.&lt;br /&gt;
&lt;br /&gt;
The _3dsecure function is passed all the same variables that the _capture function is (see page 6). Your return url should be a callback file to handle the response (see page 9)&lt;br /&gt;
&lt;br /&gt;
==Example==&lt;br /&gt;
&amp;lt;source lang = &amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
function yourgatewayname_3dsecure($params) {&lt;br /&gt;
$code = '&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;https://www.gateway.com/3dsecure/&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;gwlogin&amp;quot; value=&amp;quot;'.$params[&amp;quot;loginid&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;invoiceid&amp;quot; value=&amp;quot;'.$params[&amp;quot;invoiceid&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;amount&amp;quot; value=&amp;quot;'. $params[&amp;quot;amount&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;firstname&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;firstname&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;lastname&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;lastname&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;address&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;address1&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;city&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;city&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;state&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;state&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;postcode&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;postcode&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;country&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;country&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;phonenumber&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;phonenumber&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;email&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;email&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;ccnumber&amp;quot; value=&amp;quot;'. $params[&amp;quot;cardnum&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;expirymonth&amp;quot; value=&amp;quot;'.substr($params['cardexp'],0,2).'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;expiryyear&amp;quot; value=&amp;quot;'.substr($params['cardexp'],2,2).'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;cvv2&amp;quot; value=&amp;quot;'. $params[&amp;quot;cccvv&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;return_url&amp;quot; value=&amp;quot;'.&lt;br /&gt;
$params['systemurl'].'/modules/gateways/callback/yourgatewayname.php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;noscript&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;errorbox&amp;quot;&amp;gt;&amp;lt;b&amp;gt;JavaScript is currently disabled or is not supported by your&lt;br /&gt;
browser.&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Please click the continue button to proceed with the processing of your&lt;br /&gt;
transaction.&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Continue &amp;gt;&amp;gt;&amp;quot; /&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/noscript&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;';&lt;br /&gt;
      return $code;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Tokenised Remote Storage==&lt;br /&gt;
&lt;br /&gt;
These days, with the increasing rules &amp;amp; requirements surrounding the storing of credit card details, many merchant gateways are offering services where you can perform repeat rebills without needing to store credit card details locally on your own system. And with WHMCS, gateway modules can utilise this functionality when available.&lt;br /&gt;
&lt;br /&gt;
The basic logic behind token gateways in WHMCS is that clients must either have a credit card number or a token stored in order for recurring billing to be attempted. So if you create a function named _storeremote in your custom gateway module, this function will then override the default local storage when new credit card details are entered. And instead of&lt;br /&gt;
saving in the database, that function then needs to communicate with the gateways API, and return the token that gets assigned to WHMCS.&lt;br /&gt;
&lt;br /&gt;
The variables passed into the _storeremote function are as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang =&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['gatewayid'] # the token stored for the client&lt;br /&gt;
$params['cardtype'] #the Card Type (Visa, MasterCard, etc…)&lt;br /&gt;
$params['cardnum'] # the Card Number&lt;br /&gt;
$params['cardexp'] # the Card’s Expiry Date (Format: MMYY)&lt;br /&gt;
$params['cardstart'] # the Card’s Start Date (Format: MMYY)&lt;br /&gt;
$params['cardissuenum'] # the Card’s Issue Number (Switch/Solo Cards)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
On the first call, the gatewayid will be empty. So when empty you need to create a new profile at the gateway. On subsequent calls the gatewayid that was originally created and stored will be passed in and the existing profile simply needs to be updated. And if the cardnum variable is empty, this indicates that deleting/removal of the stored credit card&lt;br /&gt;
details has been requested.&lt;br /&gt;
&lt;br /&gt;
Once the card details have been updated or stored remotely, you need to return either a success or failure response to tell WHMCS if it worked, and if it did, the token that has been assigned:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang =&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
return array(&amp;quot;status&amp;quot;=&amp;gt;&amp;quot;success&amp;quot;,&amp;quot;gatewayid&amp;quot;=&amp;gt;$results[&amp;quot;token&amp;quot;],&amp;quot;rawdata&amp;quot;=&amp;gt;$results);&lt;br /&gt;
&lt;br /&gt;
return array(&amp;quot;status&amp;quot;=&amp;gt;&amp;quot;failed&amp;quot;,&amp;quot;rawdata&amp;quot;=&amp;gt;$results);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When this function exists in a gateway module, WHMCS will only store the card type, expiry date and the last 4 digits (only) locally in the WHMCS database. So you and your clients will still be able to see exactly what card is stored remotely from within WHMCS.&lt;br /&gt;
&lt;br /&gt;
Then within the capture function, instead of $params[‘cardnum’] you will be passed $params[‘gatewayid’] with which to perform the capture.&lt;br /&gt;
&lt;br /&gt;
==Installation &amp;amp; Activation==&lt;br /&gt;
&lt;br /&gt;
To install the module you’ve created, simply upload it to the /modules/gateways/ folder and then go to Setup &amp;gt; Payment Gateways to activate. If you have create a callback file as well then that should also be uploaded but to the /modules/gateways/callback/ folder.&lt;br /&gt;
&lt;br /&gt;
'''Important:''' It is important that you do not activate your gateway module until you have&lt;br /&gt;
completed step 1 of either the third party gateway or merchant gateway module&lt;br /&gt;
documentation steps to remove the appropriate functions as it’s at the time of activation&lt;br /&gt;
that the type of module you are setting up gets stored in the system.&lt;br /&gt;
&lt;br /&gt;
==Blank Screen/Errors==&lt;br /&gt;
&lt;br /&gt;
If you get a blank page or errors in the Setup &amp;gt; Payment Gateways page after uploading your new module file then this indicates there is a syntax error in your code. To debug that, you can add the following line to your WHMCS configuration.php file to turn on error reporting:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$display_errors = true;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That will enable PHP error reporting and should show you the cause of any issues. Once you are done testing you must remember to remove that line again.&lt;br /&gt;
&lt;br /&gt;
==App Store==&lt;br /&gt;
WHMCS offers an app store in which completed gateway modules can be submitted.  The listings are displayed under the Addons tab within the administration area and online at http://www.whmcs.com/appstore . This is a great way to make WHMCS users aware of your module.&lt;br /&gt;
&lt;br /&gt;
In order to submit a listing you'll need a login for whmcs.com/members, if you do not have one please [https://www.whmcs.com/members/submitticket.php?step=2&amp;amp;deptid=5 Contact Us]. Once logged in, visit the app store page at the above URL and click the &amp;quot;Submit your Addon&amp;quot; link. We aim to review submissions in 1-2 weeks.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Developer_Links}}&lt;/div&gt;</summary>
		<author><name>Nicolas</name></author>	</entry>

	<entry>
		<id>http://3.19.219.109/index.php?title=Gateway_Module_Developer_Docs&amp;diff=17543</id>
		<title>Gateway Module Developer Docs</title>
		<link rel="alternate" type="text/html" href="http://3.19.219.109/index.php?title=Gateway_Module_Developer_Docs&amp;diff=17543"/>
				<updated>2016-01-06T20:09:23Z</updated>
		
		<summary type="html">&lt;p&gt;Nicolas: /* Third Party Gateway */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Creating a gateway module allows you to connect WHMCS to third party payment and credit card processors that aren’t natively supported in WHMCS as standard.&lt;br /&gt;
&lt;br /&gt;
There are 2 core types of gateway module:&lt;br /&gt;
&lt;br /&gt;
#'''Third Party Gateways''' – this is where the customer leaves your site to pay and is returned once the payment process is completed&lt;br /&gt;
#'''Merchant Gateways''' – this is where the customer enters credit card details directly on your website and the payment is then processed in the background (can also include 3D Secure where the user leaves your site)&lt;br /&gt;
&lt;br /&gt;
{{Developer_Links}}&lt;br /&gt;
&lt;br /&gt;
So the first decision you need to make before starting your module for WHMCS is which type of gateway module you will be creating.  Once you have that, you're ready to begin.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Introduction==&lt;br /&gt;
&lt;br /&gt;
Gateway modules allow a connection between WHMCS and gateways or credit card processors that aren't natively supported in WHMCS.&lt;br /&gt;
&lt;br /&gt;
This documentation will explain the module's structure and contains everything needed in order to successfully create a gateway module for WHMCS.&lt;br /&gt;
&lt;br /&gt;
==Getting Started==&lt;br /&gt;
&lt;br /&gt;
To get started, begin by downloading the module development kit from our GitHub site. There are two sample modules available, depending upon the [[#Module Type|type of gateway]] being developed:&lt;br /&gt;
*Third Party Gateway: https://github.com/WHMCS/sample-gateway-module&lt;br /&gt;
*Merchant Gateway: https://github.com/WHMCS/sample-merchant-gateway&lt;br /&gt;
Take the gateway module template &amp;quot;template.php&amp;quot; from this download and rename it to &amp;quot;yourgatewayname.php&amp;quot;.  It should be all lowercase and must start with a letter.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;docs-alert-info&amp;quot;&amp;gt;&lt;br /&gt;
All functions within a gateway module must be prefixed with the filename.  Open the file and replace all occurrences of '''template_''' with '''yougatewayname_'''&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Config Array===&lt;br /&gt;
&lt;br /&gt;
'''Configure the yourgatewayname_config array'''. This function is the primary function required by all gateway modules and defines both the friendly display name for the module and any custom fields/options/settings that the gateway module requires.&lt;br /&gt;
&lt;br /&gt;
The available field types are &amp;quot;text&amp;quot;, &amp;quot;dropdown&amp;quot;, &amp;quot;textarea&amp;quot; and &amp;quot;yesno&amp;quot; (checkboxes).   The sample config array in &amp;quot;template.php&amp;quot; demonstrates how to use each of these types. &lt;br /&gt;
&lt;br /&gt;
The general formula:&lt;br /&gt;
#Specify a system name (''all in lowercase for the setting to be referenced by in the module code itself'')&lt;br /&gt;
#A FriendlyName&lt;br /&gt;
#Type&lt;br /&gt;
#Any settings specific to that field type.&lt;br /&gt;
&lt;br /&gt;
Any fields defined here will be available in all gateway module functions in the $params array, so avoid common names like currency, invoiceid, etc, as these will conflict with the standard variables.&lt;br /&gt;
&lt;br /&gt;
===Module Type===&lt;br /&gt;
&lt;br /&gt;
Determine which type of module needs to be created from the 2 core types:&lt;br /&gt;
&lt;br /&gt;
#'''Third Party Gateways''' – the customer leaves your site to pay and is returned once the payment process is completed.&lt;br /&gt;
#'''Merchant Gateways''' – where the customer enters credit card details directly on your website and the payment is then processed in the background (can also include 3D Secure where the user leaves your site).&lt;br /&gt;
&lt;br /&gt;
For a Third Party gateway go to [[#Third_Party_Gateway]], and for a merchant gateway go to [[#Merchant_Gateway]].&lt;br /&gt;
&lt;br /&gt;
==Third Party Gateway==&lt;br /&gt;
&lt;br /&gt;
Follow the steps below to create a third party gateway module (one where the customer leaves your site to make the payment on the gateway provider's website):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;docs-alert-warning&amp;quot;&amp;gt;The '''_capture''' function must be deleted before activating the new gateway module in WHMCS.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# Delete the '''_capture''' function from the module template.&lt;br /&gt;
# Enter the gateway-specific code for taking the user to the payment process within the _link function.  An example of this step is shown in the gateway module template supplied with the dev kit.  Normally, the code output by this function is the HTML for a '''&amp;lt;form&amp;gt;''' with a ''post'' method.&lt;br /&gt;
&lt;br /&gt;
The available variables are:&lt;br /&gt;
&lt;br /&gt;
===Invoice Variables===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['invoiceid'] # Invoice ID Number&lt;br /&gt;
$params['description'] # Description (eg. Company Name - Invoice #xxx)&lt;br /&gt;
$params['amount'] # Format: xxx.xx&lt;br /&gt;
$params['currency'] # Currency Code (eg. GBD, USD, etc...)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Client Variables===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['clientdetails']['firstname'] # Clients First Name&lt;br /&gt;
$params['clientdetails']['lastname'] # Clients Last Name&lt;br /&gt;
$params['clientdetails']['email'] # Clients Email Address&lt;br /&gt;
$params['clientdetails']['address1'] # Clients Address&lt;br /&gt;
$params['clientdetails']['address2'] &lt;br /&gt;
$params['clientdetails']['city']&lt;br /&gt;
$params['clientdetails']['state']&lt;br /&gt;
$params['clientdetails']['postcode']&lt;br /&gt;
$params['clientdetails']['country']&lt;br /&gt;
$params['clientdetails']['phonenumber']&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===System Variables===&lt;br /&gt;
&amp;lt;source lang = &amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['companyname'] # your Company Name setting in WHMCS&lt;br /&gt;
$params['systemurl'] # the url to the Client Area&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# The processing of a payment is handled by a callback file separate from the module (see page 9 for more information).&lt;br /&gt;
# If your gateway provider doesn't support automated refunds or you won't be including them in the module, then delete the '''_refund''' function.  Otherwise, refer to the Refund section on page 7.&lt;br /&gt;
&lt;br /&gt;
==Merchant Gateway==&lt;br /&gt;
&lt;br /&gt;
A merchant gateway module is a module where the customer enters their card details directly via the client area, without leaving the site.  To create one:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;docs-alert-warning&amp;quot;&amp;gt;&lt;br /&gt;
The '''_link''' function must be deleted before activating the new gateway module in WHMCS.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# Delete the '''_link''' function from the module template.&lt;br /&gt;
# Enter the gateway-specific code for processing the payment into the '''_capture''' function.  This normally takes the format of an HTTP/Curl request to the gateway provider's API.&lt;br /&gt;
&lt;br /&gt;
The variables available are:&lt;br /&gt;
&lt;br /&gt;
===Invoice Variables===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['invoiceid'] # Invoice ID Number&lt;br /&gt;
$params['description'] # Description (eg. Company Name - Invoice #xxx)&lt;br /&gt;
$params['amount'] # Format: xxx.xx&lt;br /&gt;
$params['currency'] # Currency Code (eg. GBP, USD, etc...)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Client Variables===&lt;br /&gt;
&amp;lt;source lang = &amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['clientdetails']['firstname'] # Clients First Name&lt;br /&gt;
$params['clientdetails']['lastname'] # Clients Last Name&lt;br /&gt;
$params['clientdetails']['email'] # Clients Email Address&lt;br /&gt;
$params['clientdetails']['address1'] # Clients Address&lt;br /&gt;
$params['clientdetails']['address2']&lt;br /&gt;
$params['clientdetails']['city']&lt;br /&gt;
$params['clientdetails']['state']&lt;br /&gt;
$params['clientdetails']['postcode']&lt;br /&gt;
$params['clientdetails']['country']&lt;br /&gt;
$params['clientdetails']['phonenumber']&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===System Variables===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['companyname'] # your Company Name setting in WHMCS&lt;br /&gt;
$params['systemurl'] # the url to the Client Area&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Card Details===&lt;br /&gt;
&amp;lt;source lang = &amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['cardtype'] # the Card Type (Visa, MasterCard, etc…)&lt;br /&gt;
$params['cardnum'] # the Card Number&lt;br /&gt;
$params['cardexp'] # the Card’s Expiry Date (Format: MMYY)&lt;br /&gt;
$params['cardstart'] # the Card’s Start Date (Format: MMYY)&lt;br /&gt;
$params['cardissuenum'] # the Card’s Issue Number (Switch/Solo Cards)&lt;br /&gt;
$params['cccvv'] #Not always present (recurring transactions)&lt;br /&gt;
#but would always be present for client initiated attempts&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# Once the transaction has been processed and a response has been received, an array with the results needs to be returned to WHMCS.   For a successful capture, use the following format:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
return array(&amp;quot;status&amp;quot;=&amp;gt;&amp;quot;success&amp;quot;,&amp;quot;transid&amp;quot;=&amp;gt;$results[&amp;quot;transid&amp;quot;],&amp;quot;rawdata&amp;quot;=&amp;gt;$results);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Within this array, the status must be success to tell WHMCS the capture was successful, transid should be passed the value of the transaction ID that came back from the gateway, and the rawdata variable should be passed an array of the data returned from the gateway to be stored in the WHMCS Gateway Log.&lt;br /&gt;
&lt;br /&gt;
If the transaction were to fail then the response should instead be as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
return array(&amp;quot;status&amp;quot;=&amp;gt;&amp;quot;declined&amp;quot;,&amp;quot;rawdata&amp;quot;=&amp;gt;$results);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this response, the status can be any value you want, declined, error, invalid hash, etc… and will be what staff get to see as the failure reason within the gateway log. The rawdata variable should again be passed an array of the data returned from the gateway to be stored in the WHMCS Gateway Log for debugging purposes.&lt;br /&gt;
&lt;br /&gt;
# If your gateway supports 3D Secure (Verified by Visa or MasterCard Secure Code) then please refer to page 8 for information on how to do handle that.&lt;br /&gt;
&lt;br /&gt;
===Refunds===&lt;br /&gt;
&lt;br /&gt;
# If your gateway provider supports automated refunds then you should add your code for processing a refund into the _refund function which is passed all the same variables as capture but with one additional variable:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['transid'] # the transaction ID of the original transaction to be refunded&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The return arrays for a success or failure should be done exactly the same as described above for the capture function.&lt;br /&gt;
&lt;br /&gt;
If your gateway provider does not support refunds, then the _refund function should be deleted from the module file.&lt;br /&gt;
&lt;br /&gt;
==Callbacks==&lt;br /&gt;
If your gateway provider supports notifying a script when a payment is successful, then you can create a callback file in WHMCS to detect and apply those calls as payments inside WHMCS.&lt;br /&gt;
&lt;br /&gt;
A sample callback file is included in the dev kit for this purpose named “callback.php”. To utilise this script, you simply need to rename it to match your gateway module, and modify the variables within it as per the comments in the code, and to match the variables your specific gateway returns.&lt;br /&gt;
&lt;br /&gt;
These are some helper functions within the sample that you might find useful:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$GATEWAY = getGatewayVariables(‘yourgatewayname’);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function can be used to retrieve the configuration data for your module as specified in&lt;br /&gt;
the _config array. For example you might need it to get a gateway username or secret key to&lt;br /&gt;
validate a callback.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$invoiceid = checkCbInvoiceID($invoiceid,$GATEWAY[‘name’]);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function can be used to check the invoice ID received back is valid. You should simply pass the $invoiceid into this function and your gateway name and if a valid invoice number the script will continue executing, otherwise the script will be halted and an appropriate gateway log entry created.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang =&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
checkCbTransID($transid);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function can be used to check for any existing transactions already recorded for a given transaction ID. This can be useful for protecting against duplicate callbacks as if the transaction ID is already found in the database, the callback script execution will be halted.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
logTransaction($GATEWAY[‘name’],$_POST,&amp;quot;Successful&amp;quot;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function can be used to create a gateway log entry. The first variable needs to be the name of the gateway module, the second should be an array of data, such as the $_POST or $_REQUEST super globals, and the last variable should be the result/status to show in the log.&lt;br /&gt;
&lt;br /&gt;
== 3D Secure Process ==&lt;br /&gt;
&lt;br /&gt;
If your merchant gateway supports 3D Secure (also known as Verified by Visa or MasterCard Secure Code) and you want to implement that then you can as WHMCS fully supports 3D Secured payments.&lt;br /&gt;
&lt;br /&gt;
To do this you need to add a function to your module named yourgatewayname_3dsecure and then similar to the _link function of a third party gateway module, you need to return the HTML for the form post to take the user to the 3D Secure process. An example of this is below.&lt;br /&gt;
&lt;br /&gt;
The _3dsecure function is passed all the same variables that the _capture function is (see page 6). Your return url should be a callback file to handle the response (see page 9)&lt;br /&gt;
&lt;br /&gt;
==Example==&lt;br /&gt;
&amp;lt;source lang = &amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
function yourgatewayname_3dsecure($params) {&lt;br /&gt;
$code = '&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;https://www.gateway.com/3dsecure/&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;gwlogin&amp;quot; value=&amp;quot;'.$params[&amp;quot;loginid&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;invoiceid&amp;quot; value=&amp;quot;'.$params[&amp;quot;invoiceid&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;amount&amp;quot; value=&amp;quot;'. $params[&amp;quot;amount&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;firstname&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;firstname&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;lastname&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;lastname&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;address&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;address1&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;city&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;city&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;state&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;state&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;postcode&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;postcode&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;country&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;country&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;phonenumber&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;phonenumber&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;email&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;email&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;ccnumber&amp;quot; value=&amp;quot;'. $params[&amp;quot;cardnum&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;expirymonth&amp;quot; value=&amp;quot;'.substr($params['cardexp'],0,2).'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;expiryyear&amp;quot; value=&amp;quot;'.substr($params['cardexp'],2,2).'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;cvv2&amp;quot; value=&amp;quot;'. $params[&amp;quot;cccvv&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;return_url&amp;quot; value=&amp;quot;'.&lt;br /&gt;
$params['systemurl'].'/modules/gateways/callback/yourgatewayname.php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;noscript&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;errorbox&amp;quot;&amp;gt;&amp;lt;b&amp;gt;JavaScript is currently disabled or is not supported by your&lt;br /&gt;
browser.&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Please click the continue button to proceed with the processing of your&lt;br /&gt;
transaction.&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Continue &amp;gt;&amp;gt;&amp;quot; /&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/noscript&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;';&lt;br /&gt;
      return $code;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Tokenised Remote Storage==&lt;br /&gt;
&lt;br /&gt;
These days, with the increasing rules &amp;amp; requirements surrounding the storing of credit card details, many merchant gateways are offering services where you can perform repeat rebills without needing to store credit card details locally on your own system. And with WHMCS, gateway modules can utilise this functionality when available.&lt;br /&gt;
&lt;br /&gt;
The basic logic behind token gateways in WHMCS is that clients must either have a credit card number or a token stored in order for recurring billing to be attempted. So if you create a function named _storeremote in your custom gateway module, this function will then override the default local storage when new credit card details are entered. And instead of&lt;br /&gt;
saving in the database, that function then needs to communicate with the gateways API, and return the token that gets assigned to WHMCS.&lt;br /&gt;
&lt;br /&gt;
The variables passed into the _storeremote function are as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang =&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['gatewayid'] # the token stored for the client&lt;br /&gt;
$params['cardtype'] #the Card Type (Visa, MasterCard, etc…)&lt;br /&gt;
$params['cardnum'] # the Card Number&lt;br /&gt;
$params['cardexp'] # the Card’s Expiry Date (Format: MMYY)&lt;br /&gt;
$params['cardstart'] # the Card’s Start Date (Format: MMYY)&lt;br /&gt;
$params['cardissuenum'] # the Card’s Issue Number (Switch/Solo Cards)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
On the first call, the gatewayid will be empty. So when empty you need to create a new profile at the gateway. On subsequent calls the gatewayid that was originally created and stored will be passed in and the existing profile simply needs to be updated. And if the cardnum variable is empty, this indicates that deleting/removal of the stored credit card&lt;br /&gt;
details has been requested.&lt;br /&gt;
&lt;br /&gt;
Once the card details have been updated or stored remotely, you need to return either a success or failure response to tell WHMCS if it worked, and if it did, the token that has been assigned:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang =&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
return array(&amp;quot;status&amp;quot;=&amp;gt;&amp;quot;success&amp;quot;,&amp;quot;gatewayid&amp;quot;=&amp;gt;$results[&amp;quot;token&amp;quot;],&amp;quot;rawdata&amp;quot;=&amp;gt;$results);&lt;br /&gt;
&lt;br /&gt;
return array(&amp;quot;status&amp;quot;=&amp;gt;&amp;quot;failed&amp;quot;,&amp;quot;rawdata&amp;quot;=&amp;gt;$results);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When this function exists in a gateway module, WHMCS will only store the card type, expiry date and the last 4 digits (only) locally in the WHMCS database. So you and your clients will still be able to see exactly what card is stored remotely from within WHMCS.&lt;br /&gt;
&lt;br /&gt;
Then within the capture function, instead of $params[‘cardnum’] you will be passed $params[‘gatewayid’] with which to perform the capture.&lt;br /&gt;
&lt;br /&gt;
==Installation &amp;amp; Activation==&lt;br /&gt;
&lt;br /&gt;
To install the module you’ve created, simply upload it to the /modules/gateways/ folder and then go to Setup &amp;gt; Payment Gateways to activate. If you have create a callback file as well then that should also be uploaded but to the /modules/gateways/callback/ folder.&lt;br /&gt;
&lt;br /&gt;
'''Important:''' It is important that you do not activate your gateway module until you have&lt;br /&gt;
completed step 1 of either the third party gateway or merchant gateway module&lt;br /&gt;
documentation steps to remove the appropriate functions as it’s at the time of activation&lt;br /&gt;
that the type of module you are setting up gets stored in the system.&lt;br /&gt;
&lt;br /&gt;
==Blank Screen/Errors==&lt;br /&gt;
&lt;br /&gt;
If you get a blank page or errors in the Setup &amp;gt; Payment Gateways page after uploading your new module file then this indicates there is a syntax error in your code. To debug that, you can add the following line to your WHMCS configuration.php file to turn on error reporting:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$display_errors = true;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That will enable PHP error reporting and should show you the cause of any issues. Once you are done testing you must remember to remove that line again.&lt;br /&gt;
&lt;br /&gt;
==App Store==&lt;br /&gt;
WHMCS offers an app store in which completed gateway modules can be submitted.  The listings are displayed under the Addons tab within the administration area and online at http://www.whmcs.com/appstore . This is a great way to make WHMCS users aware of your module.&lt;br /&gt;
&lt;br /&gt;
In order to submit a listing you'll need a login for whmcs.com/members, if you do not have one please [https://www.whmcs.com/members/submitticket.php?step=2&amp;amp;deptid=5 Contact Us]. Once logged in, visit the app store page at the above URL and click the &amp;quot;Submit your Addon&amp;quot; link. We aim to review submissions in 1-2 weeks.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Developer_Links}}&lt;/div&gt;</summary>
		<author><name>Nicolas</name></author>	</entry>

	<entry>
		<id>http://3.19.219.109/index.php?title=Gateway_Module_Developer_Docs&amp;diff=17539</id>
		<title>Gateway Module Developer Docs</title>
		<link rel="alternate" type="text/html" href="http://3.19.219.109/index.php?title=Gateway_Module_Developer_Docs&amp;diff=17539"/>
				<updated>2016-01-06T20:08:56Z</updated>
		
		<summary type="html">&lt;p&gt;Nicolas: /* Merchant Gateway */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Creating a gateway module allows you to connect WHMCS to third party payment and credit card processors that aren’t natively supported in WHMCS as standard.&lt;br /&gt;
&lt;br /&gt;
There are 2 core types of gateway module:&lt;br /&gt;
&lt;br /&gt;
#'''Third Party Gateways''' – this is where the customer leaves your site to pay and is returned once the payment process is completed&lt;br /&gt;
#'''Merchant Gateways''' – this is where the customer enters credit card details directly on your website and the payment is then processed in the background (can also include 3D Secure where the user leaves your site)&lt;br /&gt;
&lt;br /&gt;
{{Developer_Links}}&lt;br /&gt;
&lt;br /&gt;
So the first decision you need to make before starting your module for WHMCS is which type of gateway module you will be creating.  Once you have that, you're ready to begin.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Introduction==&lt;br /&gt;
&lt;br /&gt;
Gateway modules allow a connection between WHMCS and gateways or credit card processors that aren't natively supported in WHMCS.&lt;br /&gt;
&lt;br /&gt;
This documentation will explain the module's structure and contains everything needed in order to successfully create a gateway module for WHMCS.&lt;br /&gt;
&lt;br /&gt;
==Getting Started==&lt;br /&gt;
&lt;br /&gt;
To get started, begin by downloading the module development kit from our GitHub site. There are two sample modules available, depending upon the [[#Module Type|type of gateway]] being developed:&lt;br /&gt;
*Third Party Gateway: https://github.com/WHMCS/sample-gateway-module&lt;br /&gt;
*Merchant Gateway: https://github.com/WHMCS/sample-merchant-gateway&lt;br /&gt;
Take the gateway module template &amp;quot;template.php&amp;quot; from this download and rename it to &amp;quot;yourgatewayname.php&amp;quot;.  It should be all lowercase and must start with a letter.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;docs-alert-info&amp;quot;&amp;gt;&lt;br /&gt;
All functions within a gateway module must be prefixed with the filename.  Open the file and replace all occurrences of '''template_''' with '''yougatewayname_'''&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Config Array===&lt;br /&gt;
&lt;br /&gt;
'''Configure the yourgatewayname_config array'''. This function is the primary function required by all gateway modules and defines both the friendly display name for the module and any custom fields/options/settings that the gateway module requires.&lt;br /&gt;
&lt;br /&gt;
The available field types are &amp;quot;text&amp;quot;, &amp;quot;dropdown&amp;quot;, &amp;quot;textarea&amp;quot; and &amp;quot;yesno&amp;quot; (checkboxes).   The sample config array in &amp;quot;template.php&amp;quot; demonstrates how to use each of these types. &lt;br /&gt;
&lt;br /&gt;
The general formula:&lt;br /&gt;
#Specify a system name (''all in lowercase for the setting to be referenced by in the module code itself'')&lt;br /&gt;
#A FriendlyName&lt;br /&gt;
#Type&lt;br /&gt;
#Any settings specific to that field type.&lt;br /&gt;
&lt;br /&gt;
Any fields defined here will be available in all gateway module functions in the $params array, so avoid common names like currency, invoiceid, etc, as these will conflict with the standard variables.&lt;br /&gt;
&lt;br /&gt;
===Module Type===&lt;br /&gt;
&lt;br /&gt;
Determine which type of module needs to be created from the 2 core types:&lt;br /&gt;
&lt;br /&gt;
#'''Third Party Gateways''' – the customer leaves your site to pay and is returned once the payment process is completed.&lt;br /&gt;
#'''Merchant Gateways''' – where the customer enters credit card details directly on your website and the payment is then processed in the background (can also include 3D Secure where the user leaves your site).&lt;br /&gt;
&lt;br /&gt;
For a Third Party gateway go to [[#Third_Party_Gateway]], and for a merchant gateway go to [[#Merchant_Gateway]].&lt;br /&gt;
&lt;br /&gt;
==Third Party Gateway==&lt;br /&gt;
&lt;br /&gt;
Follow the steps below to create a third party gateway module (one where the customer leaves your site to make the payment on the gateway provider's website):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;docs-alert-warning&amp;quot;&amp;gt;The '''_capture''' function must be deleted before activating the gateway module in WHMCS.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# Delete the '''_capture''' function from the module template.&lt;br /&gt;
# Enter the gateway-specific code for taking the user to the payment process within the _link function.  An example of this step is shown in the gateway module template supplied with the dev kit.  Normally, the code output by this function is the HTML for a '''&amp;lt;form&amp;gt;''' with a ''post'' method.&lt;br /&gt;
&lt;br /&gt;
The available variables are:&lt;br /&gt;
&lt;br /&gt;
===Invoice Variables===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['invoiceid'] # Invoice ID Number&lt;br /&gt;
$params['description'] # Description (eg. Company Name - Invoice #xxx)&lt;br /&gt;
$params['amount'] # Format: xxx.xx&lt;br /&gt;
$params['currency'] # Currency Code (eg. GBD, USD, etc...)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Client Variables===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['clientdetails']['firstname'] # Clients First Name&lt;br /&gt;
$params['clientdetails']['lastname'] # Clients Last Name&lt;br /&gt;
$params['clientdetails']['email'] # Clients Email Address&lt;br /&gt;
$params['clientdetails']['address1'] # Clients Address&lt;br /&gt;
$params['clientdetails']['address2'] &lt;br /&gt;
$params['clientdetails']['city']&lt;br /&gt;
$params['clientdetails']['state']&lt;br /&gt;
$params['clientdetails']['postcode']&lt;br /&gt;
$params['clientdetails']['country']&lt;br /&gt;
$params['clientdetails']['phonenumber']&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===System Variables===&lt;br /&gt;
&amp;lt;source lang = &amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['companyname'] # your Company Name setting in WHMCS&lt;br /&gt;
$params['systemurl'] # the url to the Client Area&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# The processing of a payment is handled by a callback file separate from the module (see page 9 for more information).&lt;br /&gt;
# If your gateway provider doesn't support automated refunds or you won't be including them in the module, then delete the '''_refund''' function.  Otherwise, refer to the Refund section on page 7.&lt;br /&gt;
&lt;br /&gt;
==Merchant Gateway==&lt;br /&gt;
&lt;br /&gt;
A merchant gateway module is a module where the customer enters their card details directly via the client area, without leaving the site.  To create one:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;docs-alert-warning&amp;quot;&amp;gt;&lt;br /&gt;
The '''_link''' function must be deleted before activating the new gateway module in WHMCS.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# Delete the '''_link''' function from the module template.&lt;br /&gt;
# Enter the gateway-specific code for processing the payment into the '''_capture''' function.  This normally takes the format of an HTTP/Curl request to the gateway provider's API.&lt;br /&gt;
&lt;br /&gt;
The variables available are:&lt;br /&gt;
&lt;br /&gt;
===Invoice Variables===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['invoiceid'] # Invoice ID Number&lt;br /&gt;
$params['description'] # Description (eg. Company Name - Invoice #xxx)&lt;br /&gt;
$params['amount'] # Format: xxx.xx&lt;br /&gt;
$params['currency'] # Currency Code (eg. GBP, USD, etc...)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Client Variables===&lt;br /&gt;
&amp;lt;source lang = &amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['clientdetails']['firstname'] # Clients First Name&lt;br /&gt;
$params['clientdetails']['lastname'] # Clients Last Name&lt;br /&gt;
$params['clientdetails']['email'] # Clients Email Address&lt;br /&gt;
$params['clientdetails']['address1'] # Clients Address&lt;br /&gt;
$params['clientdetails']['address2']&lt;br /&gt;
$params['clientdetails']['city']&lt;br /&gt;
$params['clientdetails']['state']&lt;br /&gt;
$params['clientdetails']['postcode']&lt;br /&gt;
$params['clientdetails']['country']&lt;br /&gt;
$params['clientdetails']['phonenumber']&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===System Variables===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['companyname'] # your Company Name setting in WHMCS&lt;br /&gt;
$params['systemurl'] # the url to the Client Area&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Card Details===&lt;br /&gt;
&amp;lt;source lang = &amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['cardtype'] # the Card Type (Visa, MasterCard, etc…)&lt;br /&gt;
$params['cardnum'] # the Card Number&lt;br /&gt;
$params['cardexp'] # the Card’s Expiry Date (Format: MMYY)&lt;br /&gt;
$params['cardstart'] # the Card’s Start Date (Format: MMYY)&lt;br /&gt;
$params['cardissuenum'] # the Card’s Issue Number (Switch/Solo Cards)&lt;br /&gt;
$params['cccvv'] #Not always present (recurring transactions)&lt;br /&gt;
#but would always be present for client initiated attempts&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# Once the transaction has been processed and a response has been received, an array with the results needs to be returned to WHMCS.   For a successful capture, use the following format:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
return array(&amp;quot;status&amp;quot;=&amp;gt;&amp;quot;success&amp;quot;,&amp;quot;transid&amp;quot;=&amp;gt;$results[&amp;quot;transid&amp;quot;],&amp;quot;rawdata&amp;quot;=&amp;gt;$results);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Within this array, the status must be success to tell WHMCS the capture was successful, transid should be passed the value of the transaction ID that came back from the gateway, and the rawdata variable should be passed an array of the data returned from the gateway to be stored in the WHMCS Gateway Log.&lt;br /&gt;
&lt;br /&gt;
If the transaction were to fail then the response should instead be as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
return array(&amp;quot;status&amp;quot;=&amp;gt;&amp;quot;declined&amp;quot;,&amp;quot;rawdata&amp;quot;=&amp;gt;$results);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this response, the status can be any value you want, declined, error, invalid hash, etc… and will be what staff get to see as the failure reason within the gateway log. The rawdata variable should again be passed an array of the data returned from the gateway to be stored in the WHMCS Gateway Log for debugging purposes.&lt;br /&gt;
&lt;br /&gt;
# If your gateway supports 3D Secure (Verified by Visa or MasterCard Secure Code) then please refer to page 8 for information on how to do handle that.&lt;br /&gt;
&lt;br /&gt;
===Refunds===&lt;br /&gt;
&lt;br /&gt;
# If your gateway provider supports automated refunds then you should add your code for processing a refund into the _refund function which is passed all the same variables as capture but with one additional variable:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['transid'] # the transaction ID of the original transaction to be refunded&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The return arrays for a success or failure should be done exactly the same as described above for the capture function.&lt;br /&gt;
&lt;br /&gt;
If your gateway provider does not support refunds, then the _refund function should be deleted from the module file.&lt;br /&gt;
&lt;br /&gt;
==Callbacks==&lt;br /&gt;
If your gateway provider supports notifying a script when a payment is successful, then you can create a callback file in WHMCS to detect and apply those calls as payments inside WHMCS.&lt;br /&gt;
&lt;br /&gt;
A sample callback file is included in the dev kit for this purpose named “callback.php”. To utilise this script, you simply need to rename it to match your gateway module, and modify the variables within it as per the comments in the code, and to match the variables your specific gateway returns.&lt;br /&gt;
&lt;br /&gt;
These are some helper functions within the sample that you might find useful:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$GATEWAY = getGatewayVariables(‘yourgatewayname’);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function can be used to retrieve the configuration data for your module as specified in&lt;br /&gt;
the _config array. For example you might need it to get a gateway username or secret key to&lt;br /&gt;
validate a callback.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$invoiceid = checkCbInvoiceID($invoiceid,$GATEWAY[‘name’]);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function can be used to check the invoice ID received back is valid. You should simply pass the $invoiceid into this function and your gateway name and if a valid invoice number the script will continue executing, otherwise the script will be halted and an appropriate gateway log entry created.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang =&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
checkCbTransID($transid);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function can be used to check for any existing transactions already recorded for a given transaction ID. This can be useful for protecting against duplicate callbacks as if the transaction ID is already found in the database, the callback script execution will be halted.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
logTransaction($GATEWAY[‘name’],$_POST,&amp;quot;Successful&amp;quot;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function can be used to create a gateway log entry. The first variable needs to be the name of the gateway module, the second should be an array of data, such as the $_POST or $_REQUEST super globals, and the last variable should be the result/status to show in the log.&lt;br /&gt;
&lt;br /&gt;
== 3D Secure Process ==&lt;br /&gt;
&lt;br /&gt;
If your merchant gateway supports 3D Secure (also known as Verified by Visa or MasterCard Secure Code) and you want to implement that then you can as WHMCS fully supports 3D Secured payments.&lt;br /&gt;
&lt;br /&gt;
To do this you need to add a function to your module named yourgatewayname_3dsecure and then similar to the _link function of a third party gateway module, you need to return the HTML for the form post to take the user to the 3D Secure process. An example of this is below.&lt;br /&gt;
&lt;br /&gt;
The _3dsecure function is passed all the same variables that the _capture function is (see page 6). Your return url should be a callback file to handle the response (see page 9)&lt;br /&gt;
&lt;br /&gt;
==Example==&lt;br /&gt;
&amp;lt;source lang = &amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
function yourgatewayname_3dsecure($params) {&lt;br /&gt;
$code = '&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;https://www.gateway.com/3dsecure/&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;gwlogin&amp;quot; value=&amp;quot;'.$params[&amp;quot;loginid&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;invoiceid&amp;quot; value=&amp;quot;'.$params[&amp;quot;invoiceid&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;amount&amp;quot; value=&amp;quot;'. $params[&amp;quot;amount&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;firstname&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;firstname&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;lastname&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;lastname&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;address&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;address1&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;city&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;city&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;state&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;state&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;postcode&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;postcode&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;country&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;country&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;phonenumber&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;phonenumber&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;email&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;email&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;ccnumber&amp;quot; value=&amp;quot;'. $params[&amp;quot;cardnum&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;expirymonth&amp;quot; value=&amp;quot;'.substr($params['cardexp'],0,2).'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;expiryyear&amp;quot; value=&amp;quot;'.substr($params['cardexp'],2,2).'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;cvv2&amp;quot; value=&amp;quot;'. $params[&amp;quot;cccvv&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;return_url&amp;quot; value=&amp;quot;'.&lt;br /&gt;
$params['systemurl'].'/modules/gateways/callback/yourgatewayname.php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;noscript&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;errorbox&amp;quot;&amp;gt;&amp;lt;b&amp;gt;JavaScript is currently disabled or is not supported by your&lt;br /&gt;
browser.&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Please click the continue button to proceed with the processing of your&lt;br /&gt;
transaction.&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Continue &amp;gt;&amp;gt;&amp;quot; /&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/noscript&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;';&lt;br /&gt;
      return $code;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Tokenised Remote Storage==&lt;br /&gt;
&lt;br /&gt;
These days, with the increasing rules &amp;amp; requirements surrounding the storing of credit card details, many merchant gateways are offering services where you can perform repeat rebills without needing to store credit card details locally on your own system. And with WHMCS, gateway modules can utilise this functionality when available.&lt;br /&gt;
&lt;br /&gt;
The basic logic behind token gateways in WHMCS is that clients must either have a credit card number or a token stored in order for recurring billing to be attempted. So if you create a function named _storeremote in your custom gateway module, this function will then override the default local storage when new credit card details are entered. And instead of&lt;br /&gt;
saving in the database, that function then needs to communicate with the gateways API, and return the token that gets assigned to WHMCS.&lt;br /&gt;
&lt;br /&gt;
The variables passed into the _storeremote function are as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang =&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['gatewayid'] # the token stored for the client&lt;br /&gt;
$params['cardtype'] #the Card Type (Visa, MasterCard, etc…)&lt;br /&gt;
$params['cardnum'] # the Card Number&lt;br /&gt;
$params['cardexp'] # the Card’s Expiry Date (Format: MMYY)&lt;br /&gt;
$params['cardstart'] # the Card’s Start Date (Format: MMYY)&lt;br /&gt;
$params['cardissuenum'] # the Card’s Issue Number (Switch/Solo Cards)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
On the first call, the gatewayid will be empty. So when empty you need to create a new profile at the gateway. On subsequent calls the gatewayid that was originally created and stored will be passed in and the existing profile simply needs to be updated. And if the cardnum variable is empty, this indicates that deleting/removal of the stored credit card&lt;br /&gt;
details has been requested.&lt;br /&gt;
&lt;br /&gt;
Once the card details have been updated or stored remotely, you need to return either a success or failure response to tell WHMCS if it worked, and if it did, the token that has been assigned:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang =&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
return array(&amp;quot;status&amp;quot;=&amp;gt;&amp;quot;success&amp;quot;,&amp;quot;gatewayid&amp;quot;=&amp;gt;$results[&amp;quot;token&amp;quot;],&amp;quot;rawdata&amp;quot;=&amp;gt;$results);&lt;br /&gt;
&lt;br /&gt;
return array(&amp;quot;status&amp;quot;=&amp;gt;&amp;quot;failed&amp;quot;,&amp;quot;rawdata&amp;quot;=&amp;gt;$results);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When this function exists in a gateway module, WHMCS will only store the card type, expiry date and the last 4 digits (only) locally in the WHMCS database. So you and your clients will still be able to see exactly what card is stored remotely from within WHMCS.&lt;br /&gt;
&lt;br /&gt;
Then within the capture function, instead of $params[‘cardnum’] you will be passed $params[‘gatewayid’] with which to perform the capture.&lt;br /&gt;
&lt;br /&gt;
==Installation &amp;amp; Activation==&lt;br /&gt;
&lt;br /&gt;
To install the module you’ve created, simply upload it to the /modules/gateways/ folder and then go to Setup &amp;gt; Payment Gateways to activate. If you have create a callback file as well then that should also be uploaded but to the /modules/gateways/callback/ folder.&lt;br /&gt;
&lt;br /&gt;
'''Important:''' It is important that you do not activate your gateway module until you have&lt;br /&gt;
completed step 1 of either the third party gateway or merchant gateway module&lt;br /&gt;
documentation steps to remove the appropriate functions as it’s at the time of activation&lt;br /&gt;
that the type of module you are setting up gets stored in the system.&lt;br /&gt;
&lt;br /&gt;
==Blank Screen/Errors==&lt;br /&gt;
&lt;br /&gt;
If you get a blank page or errors in the Setup &amp;gt; Payment Gateways page after uploading your new module file then this indicates there is a syntax error in your code. To debug that, you can add the following line to your WHMCS configuration.php file to turn on error reporting:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$display_errors = true;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That will enable PHP error reporting and should show you the cause of any issues. Once you are done testing you must remember to remove that line again.&lt;br /&gt;
&lt;br /&gt;
==App Store==&lt;br /&gt;
WHMCS offers an app store in which completed gateway modules can be submitted.  The listings are displayed under the Addons tab within the administration area and online at http://www.whmcs.com/appstore . This is a great way to make WHMCS users aware of your module.&lt;br /&gt;
&lt;br /&gt;
In order to submit a listing you'll need a login for whmcs.com/members, if you do not have one please [https://www.whmcs.com/members/submitticket.php?step=2&amp;amp;deptid=5 Contact Us]. Once logged in, visit the app store page at the above URL and click the &amp;quot;Submit your Addon&amp;quot; link. We aim to review submissions in 1-2 weeks.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Developer_Links}}&lt;/div&gt;</summary>
		<author><name>Nicolas</name></author>	</entry>

	<entry>
		<id>http://3.19.219.109/index.php?title=Gateway_Module_Developer_Docs&amp;diff=17535</id>
		<title>Gateway Module Developer Docs</title>
		<link rel="alternate" type="text/html" href="http://3.19.219.109/index.php?title=Gateway_Module_Developer_Docs&amp;diff=17535"/>
				<updated>2016-01-06T20:01:40Z</updated>
		
		<summary type="html">&lt;p&gt;Nicolas: /* App Store */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Creating a gateway module allows you to connect WHMCS to third party payment and credit card processors that aren’t natively supported in WHMCS as standard.&lt;br /&gt;
&lt;br /&gt;
There are 2 core types of gateway module:&lt;br /&gt;
&lt;br /&gt;
#'''Third Party Gateways''' – this is where the customer leaves your site to pay and is returned once the payment process is completed&lt;br /&gt;
#'''Merchant Gateways''' – this is where the customer enters credit card details directly on your website and the payment is then processed in the background (can also include 3D Secure where the user leaves your site)&lt;br /&gt;
&lt;br /&gt;
{{Developer_Links}}&lt;br /&gt;
&lt;br /&gt;
So the first decision you need to make before starting your module for WHMCS is which type of gateway module you will be creating.  Once you have that, you're ready to begin.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Introduction==&lt;br /&gt;
&lt;br /&gt;
Gateway modules allow a connection between WHMCS and gateways or credit card processors that aren't natively supported in WHMCS.&lt;br /&gt;
&lt;br /&gt;
This documentation will explain the module's structure and contains everything needed in order to successfully create a gateway module for WHMCS.&lt;br /&gt;
&lt;br /&gt;
==Getting Started==&lt;br /&gt;
&lt;br /&gt;
To get started, begin by downloading the module development kit from our GitHub site. There are two sample modules available, depending upon the [[#Module Type|type of gateway]] being developed:&lt;br /&gt;
*Third Party Gateway: https://github.com/WHMCS/sample-gateway-module&lt;br /&gt;
*Merchant Gateway: https://github.com/WHMCS/sample-merchant-gateway&lt;br /&gt;
Take the gateway module template &amp;quot;template.php&amp;quot; from this download and rename it to &amp;quot;yourgatewayname.php&amp;quot;.  It should be all lowercase and must start with a letter.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;docs-alert-info&amp;quot;&amp;gt;&lt;br /&gt;
All functions within a gateway module must be prefixed with the filename.  Open the file and replace all occurrences of '''template_''' with '''yougatewayname_'''&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Config Array===&lt;br /&gt;
&lt;br /&gt;
'''Configure the yourgatewayname_config array'''. This function is the primary function required by all gateway modules and defines both the friendly display name for the module and any custom fields/options/settings that the gateway module requires.&lt;br /&gt;
&lt;br /&gt;
The available field types are &amp;quot;text&amp;quot;, &amp;quot;dropdown&amp;quot;, &amp;quot;textarea&amp;quot; and &amp;quot;yesno&amp;quot; (checkboxes).   The sample config array in &amp;quot;template.php&amp;quot; demonstrates how to use each of these types. &lt;br /&gt;
&lt;br /&gt;
The general formula:&lt;br /&gt;
#Specify a system name (''all in lowercase for the setting to be referenced by in the module code itself'')&lt;br /&gt;
#A FriendlyName&lt;br /&gt;
#Type&lt;br /&gt;
#Any settings specific to that field type.&lt;br /&gt;
&lt;br /&gt;
Any fields defined here will be available in all gateway module functions in the $params array, so avoid common names like currency, invoiceid, etc, as these will conflict with the standard variables.&lt;br /&gt;
&lt;br /&gt;
===Module Type===&lt;br /&gt;
&lt;br /&gt;
Determine which type of module needs to be created from the 2 core types:&lt;br /&gt;
&lt;br /&gt;
#'''Third Party Gateways''' – the customer leaves your site to pay and is returned once the payment process is completed.&lt;br /&gt;
#'''Merchant Gateways''' – where the customer enters credit card details directly on your website and the payment is then processed in the background (can also include 3D Secure where the user leaves your site).&lt;br /&gt;
&lt;br /&gt;
For a Third Party gateway go to [[#Third_Party_Gateway]], and for a merchant gateway go to [[#Merchant_Gateway]].&lt;br /&gt;
&lt;br /&gt;
==Third Party Gateway==&lt;br /&gt;
&lt;br /&gt;
Follow the steps below to create a third party gateway module (one where the customer leaves your site to make the payment on the gateway provider's website):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;docs-alert-warning&amp;quot;&amp;gt;The '''_capture''' function must be deleted before activating the gateway module in WHMCS.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# Delete the '''_capture''' function from the module template.&lt;br /&gt;
# Enter the gateway-specific code for taking the user to the payment process within the _link function.  An example of this step is shown in the gateway module template supplied with the dev kit.  Normally, the code output by this function is the HTML for a '''&amp;lt;form&amp;gt;''' with a ''post'' method.&lt;br /&gt;
&lt;br /&gt;
The available variables are:&lt;br /&gt;
&lt;br /&gt;
===Invoice Variables===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['invoiceid'] # Invoice ID Number&lt;br /&gt;
$params['description'] # Description (eg. Company Name - Invoice #xxx)&lt;br /&gt;
$params['amount'] # Format: xxx.xx&lt;br /&gt;
$params['currency'] # Currency Code (eg. GBD, USD, etc...)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Client Variables===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['clientdetails']['firstname'] # Clients First Name&lt;br /&gt;
$params['clientdetails']['lastname'] # Clients Last Name&lt;br /&gt;
$params['clientdetails']['email'] # Clients Email Address&lt;br /&gt;
$params['clientdetails']['address1'] # Clients Address&lt;br /&gt;
$params['clientdetails']['address2'] &lt;br /&gt;
$params['clientdetails']['city']&lt;br /&gt;
$params['clientdetails']['state']&lt;br /&gt;
$params['clientdetails']['postcode']&lt;br /&gt;
$params['clientdetails']['country']&lt;br /&gt;
$params['clientdetails']['phonenumber']&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===System Variables===&lt;br /&gt;
&amp;lt;source lang = &amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['companyname'] # your Company Name setting in WHMCS&lt;br /&gt;
$params['systemurl'] # the url to the Client Area&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# The processing of a payment is handled by a callback file separate from the module (see page 9 for more information).&lt;br /&gt;
# If your gateway provider doesn't support automated refunds or you won't be including them in the module, then delete the '''_refund''' function.  Otherwise, refer to the Refund section on page 7.&lt;br /&gt;
&lt;br /&gt;
==Merchant Gateway==&lt;br /&gt;
&lt;br /&gt;
To create a merchant gateway module, where the customer enters their card details directly via the client area without leaving the site, simply follow the steps below.&lt;br /&gt;
&lt;br /&gt;
# Begin by deleting the _link function from the module template (important: you must do this before activating your new gateway module in WHMCS)&lt;br /&gt;
# Next, enter your gateway specific code for processing the payment into the _capture function. This normally takes the format of an HTTP/Curl request to the gateway providers API.&lt;br /&gt;
&lt;br /&gt;
The variables available to you are:&lt;br /&gt;
&lt;br /&gt;
===Invoice Variables===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['invoiceid'] # Invoice ID Number&lt;br /&gt;
$params['description'] # Description (eg. Company Name - Invoice #xxx)&lt;br /&gt;
$params['amount'] # Format: xxx.xx&lt;br /&gt;
$params['currency'] # Currency Code (eg. GBP, USD, etc...)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Client Variables===&lt;br /&gt;
&amp;lt;source lang = &amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['clientdetails']['firstname'] # Clients First Name&lt;br /&gt;
$params['clientdetails']['lastname'] # Clients Last Name&lt;br /&gt;
$params['clientdetails']['email'] # Clients Email Address&lt;br /&gt;
$params['clientdetails']['address1'] # Clients Address&lt;br /&gt;
$params['clientdetails']['address2']&lt;br /&gt;
$params['clientdetails']['city']&lt;br /&gt;
$params['clientdetails']['state']&lt;br /&gt;
$params['clientdetails']['postcode']&lt;br /&gt;
$params['clientdetails']['country']&lt;br /&gt;
$params['clientdetails']['phonenumber']&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===# System Variables===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['companyname'] # your Company Name setting in WHMCS&lt;br /&gt;
$params['systemurl'] – the url to the Client Area&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Card Details===&lt;br /&gt;
&amp;lt;source lang = &amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['cardtype'] # the Card Type (Visa, MasterCard, etc…)&lt;br /&gt;
$params['cardnum'] # the Card Number&lt;br /&gt;
$params['cardexp'] # the Card’s Expiry Date (Format: MMYY)&lt;br /&gt;
$params['cardstart'] # the Card’s Start Date (Format: MMYY)&lt;br /&gt;
$params['cardissuenum'] # the Card’s Issue Number (Switch/Solo Cards)&lt;br /&gt;
$params['cccvv'] #Not always present (recurring transactions)&lt;br /&gt;
#but would always be present for client initiated attempts&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# Once you have processed the transaction and got a response, you need to return an array to WHMCS with the results. The return for a successful capture should be as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
return array(&amp;quot;status&amp;quot;=&amp;gt;&amp;quot;success&amp;quot;,&amp;quot;transid&amp;quot;=&amp;gt;$results[&amp;quot;transid&amp;quot;],&amp;quot;rawdata&amp;quot;=&amp;gt;$results);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Within this array, the status must be success to tell WHMCS the capture was successful, transid should be passed the value of the transaction ID that came back from the gateway, and the rawdata variable should be passed an array of the data returned from the gateway to be stored in the WHMCS Gateway Log.&lt;br /&gt;
&lt;br /&gt;
If the transaction were to fail then the response should instead be as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
return array(&amp;quot;status&amp;quot;=&amp;gt;&amp;quot;declined&amp;quot;,&amp;quot;rawdata&amp;quot;=&amp;gt;$results);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this response, the status can be any value you want, declined, error, invalid hash, etc… and will be what staff get to see as the failure reason within the gateway log. The rawdata variable should again be passed an array of the data returned from the gateway to be stored in the WHMCS Gateway Log for debugging purposes.&lt;br /&gt;
&lt;br /&gt;
# If your gateway supports 3D Secure (Verified by Visa or MasterCard Secure Code) then please refer to page 8 for information on how to do handle that.&lt;br /&gt;
&lt;br /&gt;
===Refunds===&lt;br /&gt;
&lt;br /&gt;
# If your gateway provider supports automated refunds then you should add your code for processing a refund into the _refund function which is passed all the same variables as capture but with one additional variable:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['transid'] # the transaction ID of the original transaction to be refunded&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The return arrays for a success or failure should be done exactly the same as described above for the capture function.&lt;br /&gt;
&lt;br /&gt;
If your gateway provider does not support refunds, then the _refund function should be deleted from the module file.&lt;br /&gt;
&lt;br /&gt;
==Callbacks==&lt;br /&gt;
If your gateway provider supports notifying a script when a payment is successful, then you can create a callback file in WHMCS to detect and apply those calls as payments inside WHMCS.&lt;br /&gt;
&lt;br /&gt;
A sample callback file is included in the dev kit for this purpose named “callback.php”. To utilise this script, you simply need to rename it to match your gateway module, and modify the variables within it as per the comments in the code, and to match the variables your specific gateway returns.&lt;br /&gt;
&lt;br /&gt;
These are some helper functions within the sample that you might find useful:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$GATEWAY = getGatewayVariables(‘yourgatewayname’);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function can be used to retrieve the configuration data for your module as specified in&lt;br /&gt;
the _config array. For example you might need it to get a gateway username or secret key to&lt;br /&gt;
validate a callback.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$invoiceid = checkCbInvoiceID($invoiceid,$GATEWAY[‘name’]);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function can be used to check the invoice ID received back is valid. You should simply pass the $invoiceid into this function and your gateway name and if a valid invoice number the script will continue executing, otherwise the script will be halted and an appropriate gateway log entry created.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang =&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
checkCbTransID($transid);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function can be used to check for any existing transactions already recorded for a given transaction ID. This can be useful for protecting against duplicate callbacks as if the transaction ID is already found in the database, the callback script execution will be halted.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
logTransaction($GATEWAY[‘name’],$_POST,&amp;quot;Successful&amp;quot;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function can be used to create a gateway log entry. The first variable needs to be the name of the gateway module, the second should be an array of data, such as the $_POST or $_REQUEST super globals, and the last variable should be the result/status to show in the log.&lt;br /&gt;
&lt;br /&gt;
== 3D Secure Process ==&lt;br /&gt;
&lt;br /&gt;
If your merchant gateway supports 3D Secure (also known as Verified by Visa or MasterCard Secure Code) and you want to implement that then you can as WHMCS fully supports 3D Secured payments.&lt;br /&gt;
&lt;br /&gt;
To do this you need to add a function to your module named yourgatewayname_3dsecure and then similar to the _link function of a third party gateway module, you need to return the HTML for the form post to take the user to the 3D Secure process. An example of this is below.&lt;br /&gt;
&lt;br /&gt;
The _3dsecure function is passed all the same variables that the _capture function is (see page 6). Your return url should be a callback file to handle the response (see page 9)&lt;br /&gt;
&lt;br /&gt;
==Example==&lt;br /&gt;
&amp;lt;source lang = &amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
function yourgatewayname_3dsecure($params) {&lt;br /&gt;
$code = '&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;https://www.gateway.com/3dsecure/&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;gwlogin&amp;quot; value=&amp;quot;'.$params[&amp;quot;loginid&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;invoiceid&amp;quot; value=&amp;quot;'.$params[&amp;quot;invoiceid&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;amount&amp;quot; value=&amp;quot;'. $params[&amp;quot;amount&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;firstname&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;firstname&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;lastname&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;lastname&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;address&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;address1&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;city&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;city&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;state&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;state&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;postcode&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;postcode&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;country&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;country&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;phonenumber&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;phonenumber&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;email&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;email&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;ccnumber&amp;quot; value=&amp;quot;'. $params[&amp;quot;cardnum&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;expirymonth&amp;quot; value=&amp;quot;'.substr($params['cardexp'],0,2).'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;expiryyear&amp;quot; value=&amp;quot;'.substr($params['cardexp'],2,2).'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;cvv2&amp;quot; value=&amp;quot;'. $params[&amp;quot;cccvv&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;return_url&amp;quot; value=&amp;quot;'.&lt;br /&gt;
$params['systemurl'].'/modules/gateways/callback/yourgatewayname.php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;noscript&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;errorbox&amp;quot;&amp;gt;&amp;lt;b&amp;gt;JavaScript is currently disabled or is not supported by your&lt;br /&gt;
browser.&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Please click the continue button to proceed with the processing of your&lt;br /&gt;
transaction.&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Continue &amp;gt;&amp;gt;&amp;quot; /&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/noscript&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;';&lt;br /&gt;
      return $code;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Tokenised Remote Storage==&lt;br /&gt;
&lt;br /&gt;
These days, with the increasing rules &amp;amp; requirements surrounding the storing of credit card details, many merchant gateways are offering services where you can perform repeat rebills without needing to store credit card details locally on your own system. And with WHMCS, gateway modules can utilise this functionality when available.&lt;br /&gt;
&lt;br /&gt;
The basic logic behind token gateways in WHMCS is that clients must either have a credit card number or a token stored in order for recurring billing to be attempted. So if you create a function named _storeremote in your custom gateway module, this function will then override the default local storage when new credit card details are entered. And instead of&lt;br /&gt;
saving in the database, that function then needs to communicate with the gateways API, and return the token that gets assigned to WHMCS.&lt;br /&gt;
&lt;br /&gt;
The variables passed into the _storeremote function are as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang =&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['gatewayid'] # the token stored for the client&lt;br /&gt;
$params['cardtype'] #the Card Type (Visa, MasterCard, etc…)&lt;br /&gt;
$params['cardnum'] # the Card Number&lt;br /&gt;
$params['cardexp'] # the Card’s Expiry Date (Format: MMYY)&lt;br /&gt;
$params['cardstart'] # the Card’s Start Date (Format: MMYY)&lt;br /&gt;
$params['cardissuenum'] # the Card’s Issue Number (Switch/Solo Cards)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
On the first call, the gatewayid will be empty. So when empty you need to create a new profile at the gateway. On subsequent calls the gatewayid that was originally created and stored will be passed in and the existing profile simply needs to be updated. And if the cardnum variable is empty, this indicates that deleting/removal of the stored credit card&lt;br /&gt;
details has been requested.&lt;br /&gt;
&lt;br /&gt;
Once the card details have been updated or stored remotely, you need to return either a success or failure response to tell WHMCS if it worked, and if it did, the token that has been assigned:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang =&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
return array(&amp;quot;status&amp;quot;=&amp;gt;&amp;quot;success&amp;quot;,&amp;quot;gatewayid&amp;quot;=&amp;gt;$results[&amp;quot;token&amp;quot;],&amp;quot;rawdata&amp;quot;=&amp;gt;$results);&lt;br /&gt;
&lt;br /&gt;
return array(&amp;quot;status&amp;quot;=&amp;gt;&amp;quot;failed&amp;quot;,&amp;quot;rawdata&amp;quot;=&amp;gt;$results);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When this function exists in a gateway module, WHMCS will only store the card type, expiry date and the last 4 digits (only) locally in the WHMCS database. So you and your clients will still be able to see exactly what card is stored remotely from within WHMCS.&lt;br /&gt;
&lt;br /&gt;
Then within the capture function, instead of $params[‘cardnum’] you will be passed $params[‘gatewayid’] with which to perform the capture.&lt;br /&gt;
&lt;br /&gt;
==Installation &amp;amp; Activation==&lt;br /&gt;
&lt;br /&gt;
To install the module you’ve created, simply upload it to the /modules/gateways/ folder and then go to Setup &amp;gt; Payment Gateways to activate. If you have create a callback file as well then that should also be uploaded but to the /modules/gateways/callback/ folder.&lt;br /&gt;
&lt;br /&gt;
'''Important:''' It is important that you do not activate your gateway module until you have&lt;br /&gt;
completed step 1 of either the third party gateway or merchant gateway module&lt;br /&gt;
documentation steps to remove the appropriate functions as it’s at the time of activation&lt;br /&gt;
that the type of module you are setting up gets stored in the system.&lt;br /&gt;
&lt;br /&gt;
==Blank Screen/Errors==&lt;br /&gt;
&lt;br /&gt;
If you get a blank page or errors in the Setup &amp;gt; Payment Gateways page after uploading your new module file then this indicates there is a syntax error in your code. To debug that, you can add the following line to your WHMCS configuration.php file to turn on error reporting:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$display_errors = true;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That will enable PHP error reporting and should show you the cause of any issues. Once you are done testing you must remember to remove that line again.&lt;br /&gt;
&lt;br /&gt;
==App Store==&lt;br /&gt;
WHMCS offers an app store in which completed gateway modules can be submitted.  The listings are displayed under the Addons tab within the administration area and online at http://www.whmcs.com/appstore . This is a great way to make WHMCS users aware of your module.&lt;br /&gt;
&lt;br /&gt;
In order to submit a listing you'll need a login for whmcs.com/members, if you do not have one please [https://www.whmcs.com/members/submitticket.php?step=2&amp;amp;deptid=5 Contact Us]. Once logged in, visit the app store page at the above URL and click the &amp;quot;Submit your Addon&amp;quot; link. We aim to review submissions in 1-2 weeks.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Developer_Links}}&lt;/div&gt;</summary>
		<author><name>Nicolas</name></author>	</entry>

	<entry>
		<id>http://3.19.219.109/index.php?title=Gateway_Module_Developer_Docs&amp;diff=17534</id>
		<title>Gateway Module Developer Docs</title>
		<link rel="alternate" type="text/html" href="http://3.19.219.109/index.php?title=Gateway_Module_Developer_Docs&amp;diff=17534"/>
				<updated>2016-01-06T19:59:20Z</updated>
		
		<summary type="html">&lt;p&gt;Nicolas: /* Third Party Gateway */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Creating a gateway module allows you to connect WHMCS to third party payment and credit card processors that aren’t natively supported in WHMCS as standard.&lt;br /&gt;
&lt;br /&gt;
There are 2 core types of gateway module:&lt;br /&gt;
&lt;br /&gt;
#'''Third Party Gateways''' – this is where the customer leaves your site to pay and is returned once the payment process is completed&lt;br /&gt;
#'''Merchant Gateways''' – this is where the customer enters credit card details directly on your website and the payment is then processed in the background (can also include 3D Secure where the user leaves your site)&lt;br /&gt;
&lt;br /&gt;
{{Developer_Links}}&lt;br /&gt;
&lt;br /&gt;
So the first decision you need to make before starting your module for WHMCS is which type of gateway module you will be creating.  Once you have that, you're ready to begin.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Introduction==&lt;br /&gt;
&lt;br /&gt;
Gateway modules allow a connection between WHMCS and gateways or credit card processors that aren't natively supported in WHMCS.&lt;br /&gt;
&lt;br /&gt;
This documentation will explain the module's structure and contains everything needed in order to successfully create a gateway module for WHMCS.&lt;br /&gt;
&lt;br /&gt;
==Getting Started==&lt;br /&gt;
&lt;br /&gt;
To get started, begin by downloading the module development kit from our GitHub site. There are two sample modules available, depending upon the [[#Module Type|type of gateway]] being developed:&lt;br /&gt;
*Third Party Gateway: https://github.com/WHMCS/sample-gateway-module&lt;br /&gt;
*Merchant Gateway: https://github.com/WHMCS/sample-merchant-gateway&lt;br /&gt;
Take the gateway module template &amp;quot;template.php&amp;quot; from this download and rename it to &amp;quot;yourgatewayname.php&amp;quot;.  It should be all lowercase and must start with a letter.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;docs-alert-info&amp;quot;&amp;gt;&lt;br /&gt;
All functions within a gateway module must be prefixed with the filename.  Open the file and replace all occurrences of '''template_''' with '''yougatewayname_'''&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Config Array===&lt;br /&gt;
&lt;br /&gt;
'''Configure the yourgatewayname_config array'''. This function is the primary function required by all gateway modules and defines both the friendly display name for the module and any custom fields/options/settings that the gateway module requires.&lt;br /&gt;
&lt;br /&gt;
The available field types are &amp;quot;text&amp;quot;, &amp;quot;dropdown&amp;quot;, &amp;quot;textarea&amp;quot; and &amp;quot;yesno&amp;quot; (checkboxes).   The sample config array in &amp;quot;template.php&amp;quot; demonstrates how to use each of these types. &lt;br /&gt;
&lt;br /&gt;
The general formula:&lt;br /&gt;
#Specify a system name (''all in lowercase for the setting to be referenced by in the module code itself'')&lt;br /&gt;
#A FriendlyName&lt;br /&gt;
#Type&lt;br /&gt;
#Any settings specific to that field type.&lt;br /&gt;
&lt;br /&gt;
Any fields defined here will be available in all gateway module functions in the $params array, so avoid common names like currency, invoiceid, etc, as these will conflict with the standard variables.&lt;br /&gt;
&lt;br /&gt;
===Module Type===&lt;br /&gt;
&lt;br /&gt;
Determine which type of module needs to be created from the 2 core types:&lt;br /&gt;
&lt;br /&gt;
#'''Third Party Gateways''' – the customer leaves your site to pay and is returned once the payment process is completed.&lt;br /&gt;
#'''Merchant Gateways''' – where the customer enters credit card details directly on your website and the payment is then processed in the background (can also include 3D Secure where the user leaves your site).&lt;br /&gt;
&lt;br /&gt;
For a Third Party gateway go to [[#Third_Party_Gateway]], and for a merchant gateway go to [[#Merchant_Gateway]].&lt;br /&gt;
&lt;br /&gt;
==Third Party Gateway==&lt;br /&gt;
&lt;br /&gt;
Follow the steps below to create a third party gateway module (one where the customer leaves your site to make the payment on the gateway provider's website):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;docs-alert-warning&amp;quot;&amp;gt;The '''_capture''' function must be deleted before activating the gateway module in WHMCS.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# Delete the '''_capture''' function from the module template.&lt;br /&gt;
# Enter the gateway-specific code for taking the user to the payment process within the _link function.  An example of this step is shown in the gateway module template supplied with the dev kit.  Normally, the code output by this function is the HTML for a '''&amp;lt;form&amp;gt;''' with a ''post'' method.&lt;br /&gt;
&lt;br /&gt;
The available variables are:&lt;br /&gt;
&lt;br /&gt;
===Invoice Variables===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['invoiceid'] # Invoice ID Number&lt;br /&gt;
$params['description'] # Description (eg. Company Name - Invoice #xxx)&lt;br /&gt;
$params['amount'] # Format: xxx.xx&lt;br /&gt;
$params['currency'] # Currency Code (eg. GBD, USD, etc...)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Client Variables===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['clientdetails']['firstname'] # Clients First Name&lt;br /&gt;
$params['clientdetails']['lastname'] # Clients Last Name&lt;br /&gt;
$params['clientdetails']['email'] # Clients Email Address&lt;br /&gt;
$params['clientdetails']['address1'] # Clients Address&lt;br /&gt;
$params['clientdetails']['address2'] &lt;br /&gt;
$params['clientdetails']['city']&lt;br /&gt;
$params['clientdetails']['state']&lt;br /&gt;
$params['clientdetails']['postcode']&lt;br /&gt;
$params['clientdetails']['country']&lt;br /&gt;
$params['clientdetails']['phonenumber']&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===System Variables===&lt;br /&gt;
&amp;lt;source lang = &amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['companyname'] # your Company Name setting in WHMCS&lt;br /&gt;
$params['systemurl'] # the url to the Client Area&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# The processing of a payment is handled by a callback file separate from the module (see page 9 for more information).&lt;br /&gt;
# If your gateway provider doesn't support automated refunds or you won't be including them in the module, then delete the '''_refund''' function.  Otherwise, refer to the Refund section on page 7.&lt;br /&gt;
&lt;br /&gt;
==Merchant Gateway==&lt;br /&gt;
&lt;br /&gt;
To create a merchant gateway module, where the customer enters their card details directly via the client area without leaving the site, simply follow the steps below.&lt;br /&gt;
&lt;br /&gt;
# Begin by deleting the _link function from the module template (important: you must do this before activating your new gateway module in WHMCS)&lt;br /&gt;
# Next, enter your gateway specific code for processing the payment into the _capture function. This normally takes the format of an HTTP/Curl request to the gateway providers API.&lt;br /&gt;
&lt;br /&gt;
The variables available to you are:&lt;br /&gt;
&lt;br /&gt;
===Invoice Variables===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['invoiceid'] # Invoice ID Number&lt;br /&gt;
$params['description'] # Description (eg. Company Name - Invoice #xxx)&lt;br /&gt;
$params['amount'] # Format: xxx.xx&lt;br /&gt;
$params['currency'] # Currency Code (eg. GBP, USD, etc...)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Client Variables===&lt;br /&gt;
&amp;lt;source lang = &amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['clientdetails']['firstname'] # Clients First Name&lt;br /&gt;
$params['clientdetails']['lastname'] # Clients Last Name&lt;br /&gt;
$params['clientdetails']['email'] # Clients Email Address&lt;br /&gt;
$params['clientdetails']['address1'] # Clients Address&lt;br /&gt;
$params['clientdetails']['address2']&lt;br /&gt;
$params['clientdetails']['city']&lt;br /&gt;
$params['clientdetails']['state']&lt;br /&gt;
$params['clientdetails']['postcode']&lt;br /&gt;
$params['clientdetails']['country']&lt;br /&gt;
$params['clientdetails']['phonenumber']&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===# System Variables===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['companyname'] # your Company Name setting in WHMCS&lt;br /&gt;
$params['systemurl'] – the url to the Client Area&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Card Details===&lt;br /&gt;
&amp;lt;source lang = &amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['cardtype'] # the Card Type (Visa, MasterCard, etc…)&lt;br /&gt;
$params['cardnum'] # the Card Number&lt;br /&gt;
$params['cardexp'] # the Card’s Expiry Date (Format: MMYY)&lt;br /&gt;
$params['cardstart'] # the Card’s Start Date (Format: MMYY)&lt;br /&gt;
$params['cardissuenum'] # the Card’s Issue Number (Switch/Solo Cards)&lt;br /&gt;
$params['cccvv'] #Not always present (recurring transactions)&lt;br /&gt;
#but would always be present for client initiated attempts&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# Once you have processed the transaction and got a response, you need to return an array to WHMCS with the results. The return for a successful capture should be as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
return array(&amp;quot;status&amp;quot;=&amp;gt;&amp;quot;success&amp;quot;,&amp;quot;transid&amp;quot;=&amp;gt;$results[&amp;quot;transid&amp;quot;],&amp;quot;rawdata&amp;quot;=&amp;gt;$results);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Within this array, the status must be success to tell WHMCS the capture was successful, transid should be passed the value of the transaction ID that came back from the gateway, and the rawdata variable should be passed an array of the data returned from the gateway to be stored in the WHMCS Gateway Log.&lt;br /&gt;
&lt;br /&gt;
If the transaction were to fail then the response should instead be as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
return array(&amp;quot;status&amp;quot;=&amp;gt;&amp;quot;declined&amp;quot;,&amp;quot;rawdata&amp;quot;=&amp;gt;$results);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this response, the status can be any value you want, declined, error, invalid hash, etc… and will be what staff get to see as the failure reason within the gateway log. The rawdata variable should again be passed an array of the data returned from the gateway to be stored in the WHMCS Gateway Log for debugging purposes.&lt;br /&gt;
&lt;br /&gt;
# If your gateway supports 3D Secure (Verified by Visa or MasterCard Secure Code) then please refer to page 8 for information on how to do handle that.&lt;br /&gt;
&lt;br /&gt;
===Refunds===&lt;br /&gt;
&lt;br /&gt;
# If your gateway provider supports automated refunds then you should add your code for processing a refund into the _refund function which is passed all the same variables as capture but with one additional variable:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['transid'] # the transaction ID of the original transaction to be refunded&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The return arrays for a success or failure should be done exactly the same as described above for the capture function.&lt;br /&gt;
&lt;br /&gt;
If your gateway provider does not support refunds, then the _refund function should be deleted from the module file.&lt;br /&gt;
&lt;br /&gt;
==Callbacks==&lt;br /&gt;
If your gateway provider supports notifying a script when a payment is successful, then you can create a callback file in WHMCS to detect and apply those calls as payments inside WHMCS.&lt;br /&gt;
&lt;br /&gt;
A sample callback file is included in the dev kit for this purpose named “callback.php”. To utilise this script, you simply need to rename it to match your gateway module, and modify the variables within it as per the comments in the code, and to match the variables your specific gateway returns.&lt;br /&gt;
&lt;br /&gt;
These are some helper functions within the sample that you might find useful:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$GATEWAY = getGatewayVariables(‘yourgatewayname’);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function can be used to retrieve the configuration data for your module as specified in&lt;br /&gt;
the _config array. For example you might need it to get a gateway username or secret key to&lt;br /&gt;
validate a callback.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$invoiceid = checkCbInvoiceID($invoiceid,$GATEWAY[‘name’]);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function can be used to check the invoice ID received back is valid. You should simply pass the $invoiceid into this function and your gateway name and if a valid invoice number the script will continue executing, otherwise the script will be halted and an appropriate gateway log entry created.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang =&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
checkCbTransID($transid);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function can be used to check for any existing transactions already recorded for a given transaction ID. This can be useful for protecting against duplicate callbacks as if the transaction ID is already found in the database, the callback script execution will be halted.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
logTransaction($GATEWAY[‘name’],$_POST,&amp;quot;Successful&amp;quot;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function can be used to create a gateway log entry. The first variable needs to be the name of the gateway module, the second should be an array of data, such as the $_POST or $_REQUEST super globals, and the last variable should be the result/status to show in the log.&lt;br /&gt;
&lt;br /&gt;
== 3D Secure Process ==&lt;br /&gt;
&lt;br /&gt;
If your merchant gateway supports 3D Secure (also known as Verified by Visa or MasterCard Secure Code) and you want to implement that then you can as WHMCS fully supports 3D Secured payments.&lt;br /&gt;
&lt;br /&gt;
To do this you need to add a function to your module named yourgatewayname_3dsecure and then similar to the _link function of a third party gateway module, you need to return the HTML for the form post to take the user to the 3D Secure process. An example of this is below.&lt;br /&gt;
&lt;br /&gt;
The _3dsecure function is passed all the same variables that the _capture function is (see page 6). Your return url should be a callback file to handle the response (see page 9)&lt;br /&gt;
&lt;br /&gt;
==Example==&lt;br /&gt;
&amp;lt;source lang = &amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
function yourgatewayname_3dsecure($params) {&lt;br /&gt;
$code = '&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;https://www.gateway.com/3dsecure/&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;gwlogin&amp;quot; value=&amp;quot;'.$params[&amp;quot;loginid&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;invoiceid&amp;quot; value=&amp;quot;'.$params[&amp;quot;invoiceid&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;amount&amp;quot; value=&amp;quot;'. $params[&amp;quot;amount&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;firstname&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;firstname&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;lastname&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;lastname&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;address&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;address1&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;city&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;city&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;state&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;state&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;postcode&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;postcode&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;country&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;country&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;phonenumber&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;phonenumber&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;email&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;email&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;ccnumber&amp;quot; value=&amp;quot;'. $params[&amp;quot;cardnum&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;expirymonth&amp;quot; value=&amp;quot;'.substr($params['cardexp'],0,2).'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;expiryyear&amp;quot; value=&amp;quot;'.substr($params['cardexp'],2,2).'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;cvv2&amp;quot; value=&amp;quot;'. $params[&amp;quot;cccvv&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;return_url&amp;quot; value=&amp;quot;'.&lt;br /&gt;
$params['systemurl'].'/modules/gateways/callback/yourgatewayname.php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;noscript&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;errorbox&amp;quot;&amp;gt;&amp;lt;b&amp;gt;JavaScript is currently disabled or is not supported by your&lt;br /&gt;
browser.&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Please click the continue button to proceed with the processing of your&lt;br /&gt;
transaction.&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Continue &amp;gt;&amp;gt;&amp;quot; /&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/noscript&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;';&lt;br /&gt;
      return $code;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Tokenised Remote Storage==&lt;br /&gt;
&lt;br /&gt;
These days, with the increasing rules &amp;amp; requirements surrounding the storing of credit card details, many merchant gateways are offering services where you can perform repeat rebills without needing to store credit card details locally on your own system. And with WHMCS, gateway modules can utilise this functionality when available.&lt;br /&gt;
&lt;br /&gt;
The basic logic behind token gateways in WHMCS is that clients must either have a credit card number or a token stored in order for recurring billing to be attempted. So if you create a function named _storeremote in your custom gateway module, this function will then override the default local storage when new credit card details are entered. And instead of&lt;br /&gt;
saving in the database, that function then needs to communicate with the gateways API, and return the token that gets assigned to WHMCS.&lt;br /&gt;
&lt;br /&gt;
The variables passed into the _storeremote function are as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang =&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['gatewayid'] # the token stored for the client&lt;br /&gt;
$params['cardtype'] #the Card Type (Visa, MasterCard, etc…)&lt;br /&gt;
$params['cardnum'] # the Card Number&lt;br /&gt;
$params['cardexp'] # the Card’s Expiry Date (Format: MMYY)&lt;br /&gt;
$params['cardstart'] # the Card’s Start Date (Format: MMYY)&lt;br /&gt;
$params['cardissuenum'] # the Card’s Issue Number (Switch/Solo Cards)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
On the first call, the gatewayid will be empty. So when empty you need to create a new profile at the gateway. On subsequent calls the gatewayid that was originally created and stored will be passed in and the existing profile simply needs to be updated. And if the cardnum variable is empty, this indicates that deleting/removal of the stored credit card&lt;br /&gt;
details has been requested.&lt;br /&gt;
&lt;br /&gt;
Once the card details have been updated or stored remotely, you need to return either a success or failure response to tell WHMCS if it worked, and if it did, the token that has been assigned:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang =&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
return array(&amp;quot;status&amp;quot;=&amp;gt;&amp;quot;success&amp;quot;,&amp;quot;gatewayid&amp;quot;=&amp;gt;$results[&amp;quot;token&amp;quot;],&amp;quot;rawdata&amp;quot;=&amp;gt;$results);&lt;br /&gt;
&lt;br /&gt;
return array(&amp;quot;status&amp;quot;=&amp;gt;&amp;quot;failed&amp;quot;,&amp;quot;rawdata&amp;quot;=&amp;gt;$results);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When this function exists in a gateway module, WHMCS will only store the card type, expiry date and the last 4 digits (only) locally in the WHMCS database. So you and your clients will still be able to see exactly what card is stored remotely from within WHMCS.&lt;br /&gt;
&lt;br /&gt;
Then within the capture function, instead of $params[‘cardnum’] you will be passed $params[‘gatewayid’] with which to perform the capture.&lt;br /&gt;
&lt;br /&gt;
==Installation &amp;amp; Activation==&lt;br /&gt;
&lt;br /&gt;
To install the module you’ve created, simply upload it to the /modules/gateways/ folder and then go to Setup &amp;gt; Payment Gateways to activate. If you have create a callback file as well then that should also be uploaded but to the /modules/gateways/callback/ folder.&lt;br /&gt;
&lt;br /&gt;
'''Important:''' It is important that you do not activate your gateway module until you have&lt;br /&gt;
completed step 1 of either the third party gateway or merchant gateway module&lt;br /&gt;
documentation steps to remove the appropriate functions as it’s at the time of activation&lt;br /&gt;
that the type of module you are setting up gets stored in the system.&lt;br /&gt;
&lt;br /&gt;
==Blank Screen/Errors==&lt;br /&gt;
&lt;br /&gt;
If you get a blank page or errors in the Setup &amp;gt; Payment Gateways page after uploading your new module file then this indicates there is a syntax error in your code. To debug that, you can add the following line to your WHMCS configuration.php file to turn on error reporting:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$display_errors = true;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That will enable PHP error reporting and should show you the cause of any issues. Once you are done testing you must remember to remove that line again.&lt;br /&gt;
&lt;br /&gt;
==App Store==&lt;br /&gt;
WHMCS offers an app store to which your completed module can be submitted. The listings are displayed under the Addons tab within the administration area and online at http://www.whmcs.com/appstore . This is a great way to make WHMCS users aware of your module.&lt;br /&gt;
&lt;br /&gt;
In order to submit a listing you'll need a login for whmcs.com/members, if you do not have one please [https://www.whmcs.com/members/submitticket.php?step=2&amp;amp;deptid=5 Contact Us]. Once logged in, visit the app store page at the above URL and click the &amp;quot;Submit your Addon&amp;quot; link. We aim to review submissions in 1-2 weeks.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Developer_Links}}&lt;/div&gt;</summary>
		<author><name>Nicolas</name></author>	</entry>

	<entry>
		<id>http://3.19.219.109/index.php?title=Gateway_Module_Developer_Docs&amp;diff=17531</id>
		<title>Gateway Module Developer Docs</title>
		<link rel="alternate" type="text/html" href="http://3.19.219.109/index.php?title=Gateway_Module_Developer_Docs&amp;diff=17531"/>
				<updated>2016-01-06T19:58:07Z</updated>
		
		<summary type="html">&lt;p&gt;Nicolas: /* Getting Started */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Creating a gateway module allows you to connect WHMCS to third party payment and credit card processors that aren’t natively supported in WHMCS as standard.&lt;br /&gt;
&lt;br /&gt;
There are 2 core types of gateway module:&lt;br /&gt;
&lt;br /&gt;
#'''Third Party Gateways''' – this is where the customer leaves your site to pay and is returned once the payment process is completed&lt;br /&gt;
#'''Merchant Gateways''' – this is where the customer enters credit card details directly on your website and the payment is then processed in the background (can also include 3D Secure where the user leaves your site)&lt;br /&gt;
&lt;br /&gt;
{{Developer_Links}}&lt;br /&gt;
&lt;br /&gt;
So the first decision you need to make before starting your module for WHMCS is which type of gateway module you will be creating.  Once you have that, you're ready to begin.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Introduction==&lt;br /&gt;
&lt;br /&gt;
Gateway modules allow a connection between WHMCS and gateways or credit card processors that aren't natively supported in WHMCS.&lt;br /&gt;
&lt;br /&gt;
This documentation will explain the module's structure and contains everything needed in order to successfully create a gateway module for WHMCS.&lt;br /&gt;
&lt;br /&gt;
==Getting Started==&lt;br /&gt;
&lt;br /&gt;
To get started, begin by downloading the module development kit from our GitHub site. There are two sample modules available, depending upon the [[#Module Type|type of gateway]] being developed:&lt;br /&gt;
*Third Party Gateway: https://github.com/WHMCS/sample-gateway-module&lt;br /&gt;
*Merchant Gateway: https://github.com/WHMCS/sample-merchant-gateway&lt;br /&gt;
Take the gateway module template &amp;quot;template.php&amp;quot; from this download and rename it to &amp;quot;yourgatewayname.php&amp;quot;.  It should be all lowercase and must start with a letter.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;docs-alert-info&amp;quot;&amp;gt;&lt;br /&gt;
All functions within a gateway module must be prefixed with the filename.  Open the file and replace all occurrences of '''template_''' with '''yougatewayname_'''&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Config Array===&lt;br /&gt;
&lt;br /&gt;
'''Configure the yourgatewayname_config array'''. This function is the primary function required by all gateway modules and defines both the friendly display name for the module and any custom fields/options/settings that the gateway module requires.&lt;br /&gt;
&lt;br /&gt;
The available field types are &amp;quot;text&amp;quot;, &amp;quot;dropdown&amp;quot;, &amp;quot;textarea&amp;quot; and &amp;quot;yesno&amp;quot; (checkboxes).   The sample config array in &amp;quot;template.php&amp;quot; demonstrates how to use each of these types. &lt;br /&gt;
&lt;br /&gt;
The general formula:&lt;br /&gt;
#Specify a system name (''all in lowercase for the setting to be referenced by in the module code itself'')&lt;br /&gt;
#A FriendlyName&lt;br /&gt;
#Type&lt;br /&gt;
#Any settings specific to that field type.&lt;br /&gt;
&lt;br /&gt;
Any fields defined here will be available in all gateway module functions in the $params array, so avoid common names like currency, invoiceid, etc, as these will conflict with the standard variables.&lt;br /&gt;
&lt;br /&gt;
===Module Type===&lt;br /&gt;
&lt;br /&gt;
Determine which type of module needs to be created from the 2 core types:&lt;br /&gt;
&lt;br /&gt;
#'''Third Party Gateways''' – the customer leaves your site to pay and is returned once the payment process is completed.&lt;br /&gt;
#'''Merchant Gateways''' – where the customer enters credit card details directly on your website and the payment is then processed in the background (can also include 3D Secure where the user leaves your site).&lt;br /&gt;
&lt;br /&gt;
For a Third Party gateway go to [[#Third_Party_Gateway]], and for a merchant gateway go to [[#Merchant_Gateway]].&lt;br /&gt;
&lt;br /&gt;
==Third Party Gateway==&lt;br /&gt;
&lt;br /&gt;
Follow the steps below to create a third party gateway module (one where the customer leaves your site to make the payment on the gateway provider's website):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;docs-alert-warning&amp;quot;&amp;gt;'''Important:''' The '''_capture''' method must be deleted before activating the gateway module in WHMCS.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# Delete the '''_capture''' function from the module template.&lt;br /&gt;
# Enter the gateway-specific code for taking the user to the payment process within the _link function.  An example of this step is shown in the gateway module template supplied with the dev kit.  Normally, the code output by this function is the HTML for a '''&amp;lt;form&amp;gt;''' with a ''post'' method.&lt;br /&gt;
&lt;br /&gt;
The available variables are:&lt;br /&gt;
&lt;br /&gt;
===Invoice Variables===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['invoiceid'] # Invoice ID Number&lt;br /&gt;
$params['description'] # Description (eg. Company Name - Invoice #xxx)&lt;br /&gt;
$params['amount'] # Format: xxx.xx&lt;br /&gt;
$params['currency'] # Currency Code (eg. GBD, USD, etc...)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Client Variables===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['clientdetails']['firstname'] # Clients First Name&lt;br /&gt;
$params['clientdetails']['lastname'] # Clients Last Name&lt;br /&gt;
$params['clientdetails']['email'] # Clients Email Address&lt;br /&gt;
$params['clientdetails']['address1'] # Clients Address&lt;br /&gt;
$params['clientdetails']['address2'] &lt;br /&gt;
$params['clientdetails']['city']&lt;br /&gt;
$params['clientdetails']['state']&lt;br /&gt;
$params['clientdetails']['postcode']&lt;br /&gt;
$params['clientdetails']['country']&lt;br /&gt;
$params['clientdetails']['phonenumber']&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===System Variables===&lt;br /&gt;
&amp;lt;source lang = &amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['companyname'] # your Company Name setting in WHMCS&lt;br /&gt;
$params['systemurl'] # the url to the Client Area&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# The processing of a payment is handled by a callback file separate from the module (see page 9 for more information).&lt;br /&gt;
# If your gateway provider doesn't support automated refunds or you won't be including them in the module, then delete the '''_refund''' function.  Otherwise, refer to the Refund section on page 7.&lt;br /&gt;
&lt;br /&gt;
==Merchant Gateway==&lt;br /&gt;
&lt;br /&gt;
To create a merchant gateway module, where the customer enters their card details directly via the client area without leaving the site, simply follow the steps below.&lt;br /&gt;
&lt;br /&gt;
# Begin by deleting the _link function from the module template (important: you must do this before activating your new gateway module in WHMCS)&lt;br /&gt;
# Next, enter your gateway specific code for processing the payment into the _capture function. This normally takes the format of an HTTP/Curl request to the gateway providers API.&lt;br /&gt;
&lt;br /&gt;
The variables available to you are:&lt;br /&gt;
&lt;br /&gt;
===Invoice Variables===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['invoiceid'] # Invoice ID Number&lt;br /&gt;
$params['description'] # Description (eg. Company Name - Invoice #xxx)&lt;br /&gt;
$params['amount'] # Format: xxx.xx&lt;br /&gt;
$params['currency'] # Currency Code (eg. GBP, USD, etc...)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Client Variables===&lt;br /&gt;
&amp;lt;source lang = &amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['clientdetails']['firstname'] # Clients First Name&lt;br /&gt;
$params['clientdetails']['lastname'] # Clients Last Name&lt;br /&gt;
$params['clientdetails']['email'] # Clients Email Address&lt;br /&gt;
$params['clientdetails']['address1'] # Clients Address&lt;br /&gt;
$params['clientdetails']['address2']&lt;br /&gt;
$params['clientdetails']['city']&lt;br /&gt;
$params['clientdetails']['state']&lt;br /&gt;
$params['clientdetails']['postcode']&lt;br /&gt;
$params['clientdetails']['country']&lt;br /&gt;
$params['clientdetails']['phonenumber']&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===# System Variables===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['companyname'] # your Company Name setting in WHMCS&lt;br /&gt;
$params['systemurl'] – the url to the Client Area&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Card Details===&lt;br /&gt;
&amp;lt;source lang = &amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['cardtype'] # the Card Type (Visa, MasterCard, etc…)&lt;br /&gt;
$params['cardnum'] # the Card Number&lt;br /&gt;
$params['cardexp'] # the Card’s Expiry Date (Format: MMYY)&lt;br /&gt;
$params['cardstart'] # the Card’s Start Date (Format: MMYY)&lt;br /&gt;
$params['cardissuenum'] # the Card’s Issue Number (Switch/Solo Cards)&lt;br /&gt;
$params['cccvv'] #Not always present (recurring transactions)&lt;br /&gt;
#but would always be present for client initiated attempts&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# Once you have processed the transaction and got a response, you need to return an array to WHMCS with the results. The return for a successful capture should be as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
return array(&amp;quot;status&amp;quot;=&amp;gt;&amp;quot;success&amp;quot;,&amp;quot;transid&amp;quot;=&amp;gt;$results[&amp;quot;transid&amp;quot;],&amp;quot;rawdata&amp;quot;=&amp;gt;$results);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Within this array, the status must be success to tell WHMCS the capture was successful, transid should be passed the value of the transaction ID that came back from the gateway, and the rawdata variable should be passed an array of the data returned from the gateway to be stored in the WHMCS Gateway Log.&lt;br /&gt;
&lt;br /&gt;
If the transaction were to fail then the response should instead be as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
return array(&amp;quot;status&amp;quot;=&amp;gt;&amp;quot;declined&amp;quot;,&amp;quot;rawdata&amp;quot;=&amp;gt;$results);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this response, the status can be any value you want, declined, error, invalid hash, etc… and will be what staff get to see as the failure reason within the gateway log. The rawdata variable should again be passed an array of the data returned from the gateway to be stored in the WHMCS Gateway Log for debugging purposes.&lt;br /&gt;
&lt;br /&gt;
# If your gateway supports 3D Secure (Verified by Visa or MasterCard Secure Code) then please refer to page 8 for information on how to do handle that.&lt;br /&gt;
&lt;br /&gt;
===Refunds===&lt;br /&gt;
&lt;br /&gt;
# If your gateway provider supports automated refunds then you should add your code for processing a refund into the _refund function which is passed all the same variables as capture but with one additional variable:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['transid'] # the transaction ID of the original transaction to be refunded&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The return arrays for a success or failure should be done exactly the same as described above for the capture function.&lt;br /&gt;
&lt;br /&gt;
If your gateway provider does not support refunds, then the _refund function should be deleted from the module file.&lt;br /&gt;
&lt;br /&gt;
==Callbacks==&lt;br /&gt;
If your gateway provider supports notifying a script when a payment is successful, then you can create a callback file in WHMCS to detect and apply those calls as payments inside WHMCS.&lt;br /&gt;
&lt;br /&gt;
A sample callback file is included in the dev kit for this purpose named “callback.php”. To utilise this script, you simply need to rename it to match your gateway module, and modify the variables within it as per the comments in the code, and to match the variables your specific gateway returns.&lt;br /&gt;
&lt;br /&gt;
These are some helper functions within the sample that you might find useful:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$GATEWAY = getGatewayVariables(‘yourgatewayname’);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function can be used to retrieve the configuration data for your module as specified in&lt;br /&gt;
the _config array. For example you might need it to get a gateway username or secret key to&lt;br /&gt;
validate a callback.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$invoiceid = checkCbInvoiceID($invoiceid,$GATEWAY[‘name’]);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function can be used to check the invoice ID received back is valid. You should simply pass the $invoiceid into this function and your gateway name and if a valid invoice number the script will continue executing, otherwise the script will be halted and an appropriate gateway log entry created.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang =&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
checkCbTransID($transid);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function can be used to check for any existing transactions already recorded for a given transaction ID. This can be useful for protecting against duplicate callbacks as if the transaction ID is already found in the database, the callback script execution will be halted.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
logTransaction($GATEWAY[‘name’],$_POST,&amp;quot;Successful&amp;quot;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function can be used to create a gateway log entry. The first variable needs to be the name of the gateway module, the second should be an array of data, such as the $_POST or $_REQUEST super globals, and the last variable should be the result/status to show in the log.&lt;br /&gt;
&lt;br /&gt;
== 3D Secure Process ==&lt;br /&gt;
&lt;br /&gt;
If your merchant gateway supports 3D Secure (also known as Verified by Visa or MasterCard Secure Code) and you want to implement that then you can as WHMCS fully supports 3D Secured payments.&lt;br /&gt;
&lt;br /&gt;
To do this you need to add a function to your module named yourgatewayname_3dsecure and then similar to the _link function of a third party gateway module, you need to return the HTML for the form post to take the user to the 3D Secure process. An example of this is below.&lt;br /&gt;
&lt;br /&gt;
The _3dsecure function is passed all the same variables that the _capture function is (see page 6). Your return url should be a callback file to handle the response (see page 9)&lt;br /&gt;
&lt;br /&gt;
==Example==&lt;br /&gt;
&amp;lt;source lang = &amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
function yourgatewayname_3dsecure($params) {&lt;br /&gt;
$code = '&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;https://www.gateway.com/3dsecure/&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;gwlogin&amp;quot; value=&amp;quot;'.$params[&amp;quot;loginid&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;invoiceid&amp;quot; value=&amp;quot;'.$params[&amp;quot;invoiceid&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;amount&amp;quot; value=&amp;quot;'. $params[&amp;quot;amount&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;firstname&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;firstname&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;lastname&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;lastname&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;address&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;address1&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;city&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;city&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;state&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;state&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;postcode&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;postcode&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;country&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;country&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;phonenumber&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;phonenumber&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;email&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;email&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;ccnumber&amp;quot; value=&amp;quot;'. $params[&amp;quot;cardnum&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;expirymonth&amp;quot; value=&amp;quot;'.substr($params['cardexp'],0,2).'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;expiryyear&amp;quot; value=&amp;quot;'.substr($params['cardexp'],2,2).'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;cvv2&amp;quot; value=&amp;quot;'. $params[&amp;quot;cccvv&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;return_url&amp;quot; value=&amp;quot;'.&lt;br /&gt;
$params['systemurl'].'/modules/gateways/callback/yourgatewayname.php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;noscript&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;errorbox&amp;quot;&amp;gt;&amp;lt;b&amp;gt;JavaScript is currently disabled or is not supported by your&lt;br /&gt;
browser.&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Please click the continue button to proceed with the processing of your&lt;br /&gt;
transaction.&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Continue &amp;gt;&amp;gt;&amp;quot; /&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/noscript&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;';&lt;br /&gt;
      return $code;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Tokenised Remote Storage==&lt;br /&gt;
&lt;br /&gt;
These days, with the increasing rules &amp;amp; requirements surrounding the storing of credit card details, many merchant gateways are offering services where you can perform repeat rebills without needing to store credit card details locally on your own system. And with WHMCS, gateway modules can utilise this functionality when available.&lt;br /&gt;
&lt;br /&gt;
The basic logic behind token gateways in WHMCS is that clients must either have a credit card number or a token stored in order for recurring billing to be attempted. So if you create a function named _storeremote in your custom gateway module, this function will then override the default local storage when new credit card details are entered. And instead of&lt;br /&gt;
saving in the database, that function then needs to communicate with the gateways API, and return the token that gets assigned to WHMCS.&lt;br /&gt;
&lt;br /&gt;
The variables passed into the _storeremote function are as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang =&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['gatewayid'] # the token stored for the client&lt;br /&gt;
$params['cardtype'] #the Card Type (Visa, MasterCard, etc…)&lt;br /&gt;
$params['cardnum'] # the Card Number&lt;br /&gt;
$params['cardexp'] # the Card’s Expiry Date (Format: MMYY)&lt;br /&gt;
$params['cardstart'] # the Card’s Start Date (Format: MMYY)&lt;br /&gt;
$params['cardissuenum'] # the Card’s Issue Number (Switch/Solo Cards)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
On the first call, the gatewayid will be empty. So when empty you need to create a new profile at the gateway. On subsequent calls the gatewayid that was originally created and stored will be passed in and the existing profile simply needs to be updated. And if the cardnum variable is empty, this indicates that deleting/removal of the stored credit card&lt;br /&gt;
details has been requested.&lt;br /&gt;
&lt;br /&gt;
Once the card details have been updated or stored remotely, you need to return either a success or failure response to tell WHMCS if it worked, and if it did, the token that has been assigned:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang =&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
return array(&amp;quot;status&amp;quot;=&amp;gt;&amp;quot;success&amp;quot;,&amp;quot;gatewayid&amp;quot;=&amp;gt;$results[&amp;quot;token&amp;quot;],&amp;quot;rawdata&amp;quot;=&amp;gt;$results);&lt;br /&gt;
&lt;br /&gt;
return array(&amp;quot;status&amp;quot;=&amp;gt;&amp;quot;failed&amp;quot;,&amp;quot;rawdata&amp;quot;=&amp;gt;$results);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When this function exists in a gateway module, WHMCS will only store the card type, expiry date and the last 4 digits (only) locally in the WHMCS database. So you and your clients will still be able to see exactly what card is stored remotely from within WHMCS.&lt;br /&gt;
&lt;br /&gt;
Then within the capture function, instead of $params[‘cardnum’] you will be passed $params[‘gatewayid’] with which to perform the capture.&lt;br /&gt;
&lt;br /&gt;
==Installation &amp;amp; Activation==&lt;br /&gt;
&lt;br /&gt;
To install the module you’ve created, simply upload it to the /modules/gateways/ folder and then go to Setup &amp;gt; Payment Gateways to activate. If you have create a callback file as well then that should also be uploaded but to the /modules/gateways/callback/ folder.&lt;br /&gt;
&lt;br /&gt;
'''Important:''' It is important that you do not activate your gateway module until you have&lt;br /&gt;
completed step 1 of either the third party gateway or merchant gateway module&lt;br /&gt;
documentation steps to remove the appropriate functions as it’s at the time of activation&lt;br /&gt;
that the type of module you are setting up gets stored in the system.&lt;br /&gt;
&lt;br /&gt;
==Blank Screen/Errors==&lt;br /&gt;
&lt;br /&gt;
If you get a blank page or errors in the Setup &amp;gt; Payment Gateways page after uploading your new module file then this indicates there is a syntax error in your code. To debug that, you can add the following line to your WHMCS configuration.php file to turn on error reporting:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$display_errors = true;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That will enable PHP error reporting and should show you the cause of any issues. Once you are done testing you must remember to remove that line again.&lt;br /&gt;
&lt;br /&gt;
==App Store==&lt;br /&gt;
WHMCS offers an app store to which your completed module can be submitted. The listings are displayed under the Addons tab within the administration area and online at http://www.whmcs.com/appstore . This is a great way to make WHMCS users aware of your module.&lt;br /&gt;
&lt;br /&gt;
In order to submit a listing you'll need a login for whmcs.com/members, if you do not have one please [https://www.whmcs.com/members/submitticket.php?step=2&amp;amp;deptid=5 Contact Us]. Once logged in, visit the app store page at the above URL and click the &amp;quot;Submit your Addon&amp;quot; link. We aim to review submissions in 1-2 weeks.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Developer_Links}}&lt;/div&gt;</summary>
		<author><name>Nicolas</name></author>	</entry>

	<entry>
		<id>http://3.19.219.109/index.php?title=Gateway_Module_Developer_Docs&amp;diff=17527</id>
		<title>Gateway Module Developer Docs</title>
		<link rel="alternate" type="text/html" href="http://3.19.219.109/index.php?title=Gateway_Module_Developer_Docs&amp;diff=17527"/>
				<updated>2016-01-06T19:57:35Z</updated>
		
		<summary type="html">&lt;p&gt;Nicolas: /* Getting Started */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Creating a gateway module allows you to connect WHMCS to third party payment and credit card processors that aren’t natively supported in WHMCS as standard.&lt;br /&gt;
&lt;br /&gt;
There are 2 core types of gateway module:&lt;br /&gt;
&lt;br /&gt;
#'''Third Party Gateways''' – this is where the customer leaves your site to pay and is returned once the payment process is completed&lt;br /&gt;
#'''Merchant Gateways''' – this is where the customer enters credit card details directly on your website and the payment is then processed in the background (can also include 3D Secure where the user leaves your site)&lt;br /&gt;
&lt;br /&gt;
{{Developer_Links}}&lt;br /&gt;
&lt;br /&gt;
So the first decision you need to make before starting your module for WHMCS is which type of gateway module you will be creating.  Once you have that, you're ready to begin.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Introduction==&lt;br /&gt;
&lt;br /&gt;
Gateway modules allow a connection between WHMCS and gateways or credit card processors that aren't natively supported in WHMCS.&lt;br /&gt;
&lt;br /&gt;
This documentation will explain the module's structure and contains everything needed in order to successfully create a gateway module for WHMCS.&lt;br /&gt;
&lt;br /&gt;
==Getting Started==&lt;br /&gt;
&lt;br /&gt;
To get started, begin by downloading the module development kit from our GitHub site. There are two sample modules available, depending upon the [[#Module Type|type of gateway]] being developed:&lt;br /&gt;
*Third Party Gateway: https://github.com/WHMCS/sample-gateway-module&lt;br /&gt;
*Merchant Gateway: https://github.com/WHMCS/sample-merchant-gateway&lt;br /&gt;
Take the gateway module template &amp;quot;template.php&amp;quot; from this download and rename it to &amp;quot;yourgatewayname.php&amp;quot;.  It should be all lowercase and must start with a letter.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;docs-alert-warning&amp;quot;&amp;gt;&lt;br /&gt;
All functions within a gateway module must be prefixed with the filename.  Open the file and replace all occurrences of '''template_''' with '''yougatewayname_'''.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Config Array===&lt;br /&gt;
&lt;br /&gt;
'''Configure the yourgatewayname_config array'''. This function is the primary function required by all gateway modules and defines both the friendly display name for the module and any custom fields/options/settings that the gateway module requires.&lt;br /&gt;
&lt;br /&gt;
The available field types are &amp;quot;text&amp;quot;, &amp;quot;dropdown&amp;quot;, &amp;quot;textarea&amp;quot; and &amp;quot;yesno&amp;quot; (checkboxes).   The sample config array in &amp;quot;template.php&amp;quot; demonstrates how to use each of these types. &lt;br /&gt;
&lt;br /&gt;
The general formula:&lt;br /&gt;
#Specify a system name (''all in lowercase for the setting to be referenced by in the module code itself'')&lt;br /&gt;
#A FriendlyName&lt;br /&gt;
#Type&lt;br /&gt;
#Any settings specific to that field type.&lt;br /&gt;
&lt;br /&gt;
Any fields defined here will be available in all gateway module functions in the $params array, so avoid common names like currency, invoiceid, etc, as these will conflict with the standard variables.&lt;br /&gt;
&lt;br /&gt;
===Module Type===&lt;br /&gt;
&lt;br /&gt;
Determine which type of module needs to be created from the 2 core types:&lt;br /&gt;
&lt;br /&gt;
#'''Third Party Gateways''' – the customer leaves your site to pay and is returned once the payment process is completed.&lt;br /&gt;
#'''Merchant Gateways''' – where the customer enters credit card details directly on your website and the payment is then processed in the background (can also include 3D Secure where the user leaves your site).&lt;br /&gt;
&lt;br /&gt;
For a Third Party gateway go to [[#Third_Party_Gateway]], and for a merchant gateway go to [[#Merchant_Gateway]].&lt;br /&gt;
&lt;br /&gt;
==Third Party Gateway==&lt;br /&gt;
&lt;br /&gt;
Follow the steps below to create a third party gateway module (one where the customer leaves your site to make the payment on the gateway provider's website):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;docs-alert-warning&amp;quot;&amp;gt;'''Important:''' The '''_capture''' method must be deleted before activating the gateway module in WHMCS.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# Delete the '''_capture''' function from the module template.&lt;br /&gt;
# Enter the gateway-specific code for taking the user to the payment process within the _link function.  An example of this step is shown in the gateway module template supplied with the dev kit.  Normally, the code output by this function is the HTML for a '''&amp;lt;form&amp;gt;''' with a ''post'' method.&lt;br /&gt;
&lt;br /&gt;
The available variables are:&lt;br /&gt;
&lt;br /&gt;
===Invoice Variables===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['invoiceid'] # Invoice ID Number&lt;br /&gt;
$params['description'] # Description (eg. Company Name - Invoice #xxx)&lt;br /&gt;
$params['amount'] # Format: xxx.xx&lt;br /&gt;
$params['currency'] # Currency Code (eg. GBD, USD, etc...)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Client Variables===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['clientdetails']['firstname'] # Clients First Name&lt;br /&gt;
$params['clientdetails']['lastname'] # Clients Last Name&lt;br /&gt;
$params['clientdetails']['email'] # Clients Email Address&lt;br /&gt;
$params['clientdetails']['address1'] # Clients Address&lt;br /&gt;
$params['clientdetails']['address2'] &lt;br /&gt;
$params['clientdetails']['city']&lt;br /&gt;
$params['clientdetails']['state']&lt;br /&gt;
$params['clientdetails']['postcode']&lt;br /&gt;
$params['clientdetails']['country']&lt;br /&gt;
$params['clientdetails']['phonenumber']&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===System Variables===&lt;br /&gt;
&amp;lt;source lang = &amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['companyname'] # your Company Name setting in WHMCS&lt;br /&gt;
$params['systemurl'] # the url to the Client Area&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# The processing of a payment is handled by a callback file separate from the module (see page 9 for more information).&lt;br /&gt;
# If your gateway provider doesn't support automated refunds or you won't be including them in the module, then delete the '''_refund''' function.  Otherwise, refer to the Refund section on page 7.&lt;br /&gt;
&lt;br /&gt;
==Merchant Gateway==&lt;br /&gt;
&lt;br /&gt;
To create a merchant gateway module, where the customer enters their card details directly via the client area without leaving the site, simply follow the steps below.&lt;br /&gt;
&lt;br /&gt;
# Begin by deleting the _link function from the module template (important: you must do this before activating your new gateway module in WHMCS)&lt;br /&gt;
# Next, enter your gateway specific code for processing the payment into the _capture function. This normally takes the format of an HTTP/Curl request to the gateway providers API.&lt;br /&gt;
&lt;br /&gt;
The variables available to you are:&lt;br /&gt;
&lt;br /&gt;
===Invoice Variables===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['invoiceid'] # Invoice ID Number&lt;br /&gt;
$params['description'] # Description (eg. Company Name - Invoice #xxx)&lt;br /&gt;
$params['amount'] # Format: xxx.xx&lt;br /&gt;
$params['currency'] # Currency Code (eg. GBP, USD, etc...)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Client Variables===&lt;br /&gt;
&amp;lt;source lang = &amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['clientdetails']['firstname'] # Clients First Name&lt;br /&gt;
$params['clientdetails']['lastname'] # Clients Last Name&lt;br /&gt;
$params['clientdetails']['email'] # Clients Email Address&lt;br /&gt;
$params['clientdetails']['address1'] # Clients Address&lt;br /&gt;
$params['clientdetails']['address2']&lt;br /&gt;
$params['clientdetails']['city']&lt;br /&gt;
$params['clientdetails']['state']&lt;br /&gt;
$params['clientdetails']['postcode']&lt;br /&gt;
$params['clientdetails']['country']&lt;br /&gt;
$params['clientdetails']['phonenumber']&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===# System Variables===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['companyname'] # your Company Name setting in WHMCS&lt;br /&gt;
$params['systemurl'] – the url to the Client Area&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Card Details===&lt;br /&gt;
&amp;lt;source lang = &amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['cardtype'] # the Card Type (Visa, MasterCard, etc…)&lt;br /&gt;
$params['cardnum'] # the Card Number&lt;br /&gt;
$params['cardexp'] # the Card’s Expiry Date (Format: MMYY)&lt;br /&gt;
$params['cardstart'] # the Card’s Start Date (Format: MMYY)&lt;br /&gt;
$params['cardissuenum'] # the Card’s Issue Number (Switch/Solo Cards)&lt;br /&gt;
$params['cccvv'] #Not always present (recurring transactions)&lt;br /&gt;
#but would always be present for client initiated attempts&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# Once you have processed the transaction and got a response, you need to return an array to WHMCS with the results. The return for a successful capture should be as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
return array(&amp;quot;status&amp;quot;=&amp;gt;&amp;quot;success&amp;quot;,&amp;quot;transid&amp;quot;=&amp;gt;$results[&amp;quot;transid&amp;quot;],&amp;quot;rawdata&amp;quot;=&amp;gt;$results);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Within this array, the status must be success to tell WHMCS the capture was successful, transid should be passed the value of the transaction ID that came back from the gateway, and the rawdata variable should be passed an array of the data returned from the gateway to be stored in the WHMCS Gateway Log.&lt;br /&gt;
&lt;br /&gt;
If the transaction were to fail then the response should instead be as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
return array(&amp;quot;status&amp;quot;=&amp;gt;&amp;quot;declined&amp;quot;,&amp;quot;rawdata&amp;quot;=&amp;gt;$results);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this response, the status can be any value you want, declined, error, invalid hash, etc… and will be what staff get to see as the failure reason within the gateway log. The rawdata variable should again be passed an array of the data returned from the gateway to be stored in the WHMCS Gateway Log for debugging purposes.&lt;br /&gt;
&lt;br /&gt;
# If your gateway supports 3D Secure (Verified by Visa or MasterCard Secure Code) then please refer to page 8 for information on how to do handle that.&lt;br /&gt;
&lt;br /&gt;
===Refunds===&lt;br /&gt;
&lt;br /&gt;
# If your gateway provider supports automated refunds then you should add your code for processing a refund into the _refund function which is passed all the same variables as capture but with one additional variable:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['transid'] # the transaction ID of the original transaction to be refunded&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The return arrays for a success or failure should be done exactly the same as described above for the capture function.&lt;br /&gt;
&lt;br /&gt;
If your gateway provider does not support refunds, then the _refund function should be deleted from the module file.&lt;br /&gt;
&lt;br /&gt;
==Callbacks==&lt;br /&gt;
If your gateway provider supports notifying a script when a payment is successful, then you can create a callback file in WHMCS to detect and apply those calls as payments inside WHMCS.&lt;br /&gt;
&lt;br /&gt;
A sample callback file is included in the dev kit for this purpose named “callback.php”. To utilise this script, you simply need to rename it to match your gateway module, and modify the variables within it as per the comments in the code, and to match the variables your specific gateway returns.&lt;br /&gt;
&lt;br /&gt;
These are some helper functions within the sample that you might find useful:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$GATEWAY = getGatewayVariables(‘yourgatewayname’);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function can be used to retrieve the configuration data for your module as specified in&lt;br /&gt;
the _config array. For example you might need it to get a gateway username or secret key to&lt;br /&gt;
validate a callback.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$invoiceid = checkCbInvoiceID($invoiceid,$GATEWAY[‘name’]);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function can be used to check the invoice ID received back is valid. You should simply pass the $invoiceid into this function and your gateway name and if a valid invoice number the script will continue executing, otherwise the script will be halted and an appropriate gateway log entry created.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang =&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
checkCbTransID($transid);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function can be used to check for any existing transactions already recorded for a given transaction ID. This can be useful for protecting against duplicate callbacks as if the transaction ID is already found in the database, the callback script execution will be halted.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
logTransaction($GATEWAY[‘name’],$_POST,&amp;quot;Successful&amp;quot;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function can be used to create a gateway log entry. The first variable needs to be the name of the gateway module, the second should be an array of data, such as the $_POST or $_REQUEST super globals, and the last variable should be the result/status to show in the log.&lt;br /&gt;
&lt;br /&gt;
== 3D Secure Process ==&lt;br /&gt;
&lt;br /&gt;
If your merchant gateway supports 3D Secure (also known as Verified by Visa or MasterCard Secure Code) and you want to implement that then you can as WHMCS fully supports 3D Secured payments.&lt;br /&gt;
&lt;br /&gt;
To do this you need to add a function to your module named yourgatewayname_3dsecure and then similar to the _link function of a third party gateway module, you need to return the HTML for the form post to take the user to the 3D Secure process. An example of this is below.&lt;br /&gt;
&lt;br /&gt;
The _3dsecure function is passed all the same variables that the _capture function is (see page 6). Your return url should be a callback file to handle the response (see page 9)&lt;br /&gt;
&lt;br /&gt;
==Example==&lt;br /&gt;
&amp;lt;source lang = &amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
function yourgatewayname_3dsecure($params) {&lt;br /&gt;
$code = '&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;https://www.gateway.com/3dsecure/&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;gwlogin&amp;quot; value=&amp;quot;'.$params[&amp;quot;loginid&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;invoiceid&amp;quot; value=&amp;quot;'.$params[&amp;quot;invoiceid&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;amount&amp;quot; value=&amp;quot;'. $params[&amp;quot;amount&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;firstname&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;firstname&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;lastname&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;lastname&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;address&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;address1&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;city&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;city&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;state&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;state&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;postcode&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;postcode&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;country&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;country&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;phonenumber&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;phonenumber&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;email&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;email&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;ccnumber&amp;quot; value=&amp;quot;'. $params[&amp;quot;cardnum&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;expirymonth&amp;quot; value=&amp;quot;'.substr($params['cardexp'],0,2).'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;expiryyear&amp;quot; value=&amp;quot;'.substr($params['cardexp'],2,2).'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;cvv2&amp;quot; value=&amp;quot;'. $params[&amp;quot;cccvv&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;return_url&amp;quot; value=&amp;quot;'.&lt;br /&gt;
$params['systemurl'].'/modules/gateways/callback/yourgatewayname.php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;noscript&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;errorbox&amp;quot;&amp;gt;&amp;lt;b&amp;gt;JavaScript is currently disabled or is not supported by your&lt;br /&gt;
browser.&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Please click the continue button to proceed with the processing of your&lt;br /&gt;
transaction.&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Continue &amp;gt;&amp;gt;&amp;quot; /&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/noscript&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;';&lt;br /&gt;
      return $code;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Tokenised Remote Storage==&lt;br /&gt;
&lt;br /&gt;
These days, with the increasing rules &amp;amp; requirements surrounding the storing of credit card details, many merchant gateways are offering services where you can perform repeat rebills without needing to store credit card details locally on your own system. And with WHMCS, gateway modules can utilise this functionality when available.&lt;br /&gt;
&lt;br /&gt;
The basic logic behind token gateways in WHMCS is that clients must either have a credit card number or a token stored in order for recurring billing to be attempted. So if you create a function named _storeremote in your custom gateway module, this function will then override the default local storage when new credit card details are entered. And instead of&lt;br /&gt;
saving in the database, that function then needs to communicate with the gateways API, and return the token that gets assigned to WHMCS.&lt;br /&gt;
&lt;br /&gt;
The variables passed into the _storeremote function are as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang =&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['gatewayid'] # the token stored for the client&lt;br /&gt;
$params['cardtype'] #the Card Type (Visa, MasterCard, etc…)&lt;br /&gt;
$params['cardnum'] # the Card Number&lt;br /&gt;
$params['cardexp'] # the Card’s Expiry Date (Format: MMYY)&lt;br /&gt;
$params['cardstart'] # the Card’s Start Date (Format: MMYY)&lt;br /&gt;
$params['cardissuenum'] # the Card’s Issue Number (Switch/Solo Cards)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
On the first call, the gatewayid will be empty. So when empty you need to create a new profile at the gateway. On subsequent calls the gatewayid that was originally created and stored will be passed in and the existing profile simply needs to be updated. And if the cardnum variable is empty, this indicates that deleting/removal of the stored credit card&lt;br /&gt;
details has been requested.&lt;br /&gt;
&lt;br /&gt;
Once the card details have been updated or stored remotely, you need to return either a success or failure response to tell WHMCS if it worked, and if it did, the token that has been assigned:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang =&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
return array(&amp;quot;status&amp;quot;=&amp;gt;&amp;quot;success&amp;quot;,&amp;quot;gatewayid&amp;quot;=&amp;gt;$results[&amp;quot;token&amp;quot;],&amp;quot;rawdata&amp;quot;=&amp;gt;$results);&lt;br /&gt;
&lt;br /&gt;
return array(&amp;quot;status&amp;quot;=&amp;gt;&amp;quot;failed&amp;quot;,&amp;quot;rawdata&amp;quot;=&amp;gt;$results);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When this function exists in a gateway module, WHMCS will only store the card type, expiry date and the last 4 digits (only) locally in the WHMCS database. So you and your clients will still be able to see exactly what card is stored remotely from within WHMCS.&lt;br /&gt;
&lt;br /&gt;
Then within the capture function, instead of $params[‘cardnum’] you will be passed $params[‘gatewayid’] with which to perform the capture.&lt;br /&gt;
&lt;br /&gt;
==Installation &amp;amp; Activation==&lt;br /&gt;
&lt;br /&gt;
To install the module you’ve created, simply upload it to the /modules/gateways/ folder and then go to Setup &amp;gt; Payment Gateways to activate. If you have create a callback file as well then that should also be uploaded but to the /modules/gateways/callback/ folder.&lt;br /&gt;
&lt;br /&gt;
'''Important:''' It is important that you do not activate your gateway module until you have&lt;br /&gt;
completed step 1 of either the third party gateway or merchant gateway module&lt;br /&gt;
documentation steps to remove the appropriate functions as it’s at the time of activation&lt;br /&gt;
that the type of module you are setting up gets stored in the system.&lt;br /&gt;
&lt;br /&gt;
==Blank Screen/Errors==&lt;br /&gt;
&lt;br /&gt;
If you get a blank page or errors in the Setup &amp;gt; Payment Gateways page after uploading your new module file then this indicates there is a syntax error in your code. To debug that, you can add the following line to your WHMCS configuration.php file to turn on error reporting:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$display_errors = true;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That will enable PHP error reporting and should show you the cause of any issues. Once you are done testing you must remember to remove that line again.&lt;br /&gt;
&lt;br /&gt;
==App Store==&lt;br /&gt;
WHMCS offers an app store to which your completed module can be submitted. The listings are displayed under the Addons tab within the administration area and online at http://www.whmcs.com/appstore . This is a great way to make WHMCS users aware of your module.&lt;br /&gt;
&lt;br /&gt;
In order to submit a listing you'll need a login for whmcs.com/members, if you do not have one please [https://www.whmcs.com/members/submitticket.php?step=2&amp;amp;deptid=5 Contact Us]. Once logged in, visit the app store page at the above URL and click the &amp;quot;Submit your Addon&amp;quot; link. We aim to review submissions in 1-2 weeks.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Developer_Links}}&lt;/div&gt;</summary>
		<author><name>Nicolas</name></author>	</entry>

	<entry>
		<id>http://3.19.219.109/index.php?title=Gateway_Module_Developer_Docs&amp;diff=17523</id>
		<title>Gateway Module Developer Docs</title>
		<link rel="alternate" type="text/html" href="http://3.19.219.109/index.php?title=Gateway_Module_Developer_Docs&amp;diff=17523"/>
				<updated>2016-01-06T19:56:08Z</updated>
		
		<summary type="html">&lt;p&gt;Nicolas: /* Third Party Gateway */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Creating a gateway module allows you to connect WHMCS to third party payment and credit card processors that aren’t natively supported in WHMCS as standard.&lt;br /&gt;
&lt;br /&gt;
There are 2 core types of gateway module:&lt;br /&gt;
&lt;br /&gt;
#'''Third Party Gateways''' – this is where the customer leaves your site to pay and is returned once the payment process is completed&lt;br /&gt;
#'''Merchant Gateways''' – this is where the customer enters credit card details directly on your website and the payment is then processed in the background (can also include 3D Secure where the user leaves your site)&lt;br /&gt;
&lt;br /&gt;
{{Developer_Links}}&lt;br /&gt;
&lt;br /&gt;
So the first decision you need to make before starting your module for WHMCS is which type of gateway module you will be creating.  Once you have that, you're ready to begin.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Introduction==&lt;br /&gt;
&lt;br /&gt;
Gateway modules allow a connection between WHMCS and gateways or credit card processors that aren't natively supported in WHMCS.&lt;br /&gt;
&lt;br /&gt;
This documentation will explain the module's structure and contains everything needed in order to successfully create a gateway module for WHMCS.&lt;br /&gt;
&lt;br /&gt;
==Getting Started==&lt;br /&gt;
&lt;br /&gt;
To get started, begin by downloading the module development kit from our GitHub site. There are two sample modules available, depending upon the [[#Module Type|type of gateway]] being developed:&lt;br /&gt;
*Third Party Gateway: https://github.com/WHMCS/sample-gateway-module&lt;br /&gt;
*Merchant Gateway: https://github.com/WHMCS/sample-merchant-gateway&lt;br /&gt;
Take the gateway module template &amp;quot;template.php&amp;quot; from this download and rename it to &amp;quot;yourgatewayname.php&amp;quot;.  It should be all lowercase and must start with a letter.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;docs-alert-warning&amp;quot;&amp;gt;&lt;br /&gt;
All functions within a gateway module must be prefixed with the filename.  Open the file and replace all occurrences of &amp;quot;template_&amp;quot; with &amp;quot;yougatewayname_&amp;quot;.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Config Array===&lt;br /&gt;
&lt;br /&gt;
'''Configure the yourgatewayname_config array'''. This function is the primary function required by all gateway modules and defines both the friendly display name for the module and any custom fields/options/settings that the gateway module requires.&lt;br /&gt;
&lt;br /&gt;
The available field types are &amp;quot;text&amp;quot;, &amp;quot;dropdown&amp;quot;, &amp;quot;textarea&amp;quot; and &amp;quot;yesno&amp;quot; (checkboxes).   The sample config array in &amp;quot;template.php&amp;quot; demonstrates how to use each of these types. &lt;br /&gt;
&lt;br /&gt;
The general formula is to:&lt;br /&gt;
#Specify a system name (''all in lowercase for the setting to be referenced by in the module code itself'')&lt;br /&gt;
#A FriendlyName&lt;br /&gt;
#Type&lt;br /&gt;
#Any settings specific to that field type.&lt;br /&gt;
&lt;br /&gt;
Any fields defined here will be available in all gateway module functions in the $params array, so avoid common names like currency, invoiceid, etc, as these will conflict with the standard variables.&lt;br /&gt;
&lt;br /&gt;
===Module Type===&lt;br /&gt;
&lt;br /&gt;
Determine which type of module needs to be created from the 2 core types:&lt;br /&gt;
&lt;br /&gt;
#'''Third Party Gateways''' – the customer leaves your site to pay and is returned once the payment process is completed.&lt;br /&gt;
#'''Merchant Gateways''' – where the customer enters credit card details directly on your website and the payment is then processed in the background (can also include 3D Secure where the user leaves your site).&lt;br /&gt;
&lt;br /&gt;
For a Third Party gateway go to [[#Third_Party_Gateway]], and for a merchant gateway go to [[#Merchant_Gateway]].&lt;br /&gt;
&lt;br /&gt;
==Third Party Gateway==&lt;br /&gt;
&lt;br /&gt;
Follow the steps below to create a third party gateway module (one where the customer leaves your site to make the payment on the gateway provider's website):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;docs-alert-warning&amp;quot;&amp;gt;'''Important:''' The '''_capture''' method must be deleted before activating the gateway module in WHMCS.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# Delete the '''_capture''' function from the module template.&lt;br /&gt;
# Enter the gateway-specific code for taking the user to the payment process within the _link function.  An example of this step is shown in the gateway module template supplied with the dev kit.  Normally, the code output by this function is the HTML for a '''&amp;lt;form&amp;gt;''' with a ''post'' method.&lt;br /&gt;
&lt;br /&gt;
The available variables are:&lt;br /&gt;
&lt;br /&gt;
===Invoice Variables===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['invoiceid'] # Invoice ID Number&lt;br /&gt;
$params['description'] # Description (eg. Company Name - Invoice #xxx)&lt;br /&gt;
$params['amount'] # Format: xxx.xx&lt;br /&gt;
$params['currency'] # Currency Code (eg. GBD, USD, etc...)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Client Variables===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['clientdetails']['firstname'] # Clients First Name&lt;br /&gt;
$params['clientdetails']['lastname'] # Clients Last Name&lt;br /&gt;
$params['clientdetails']['email'] # Clients Email Address&lt;br /&gt;
$params['clientdetails']['address1'] # Clients Address&lt;br /&gt;
$params['clientdetails']['address2'] &lt;br /&gt;
$params['clientdetails']['city']&lt;br /&gt;
$params['clientdetails']['state']&lt;br /&gt;
$params['clientdetails']['postcode']&lt;br /&gt;
$params['clientdetails']['country']&lt;br /&gt;
$params['clientdetails']['phonenumber']&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===System Variables===&lt;br /&gt;
&amp;lt;source lang = &amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['companyname'] # your Company Name setting in WHMCS&lt;br /&gt;
$params['systemurl'] # the url to the Client Area&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# The processing of a payment is handled by a callback file separate from the module (see page 9 for more information).&lt;br /&gt;
# If your gateway provider doesn't support automated refunds or you won't be including them in the module, then delete the '''_refund''' function.  Otherwise, refer to the Refund section on page 7.&lt;br /&gt;
&lt;br /&gt;
==Merchant Gateway==&lt;br /&gt;
&lt;br /&gt;
To create a merchant gateway module, where the customer enters their card details directly via the client area without leaving the site, simply follow the steps below.&lt;br /&gt;
&lt;br /&gt;
# Begin by deleting the _link function from the module template (important: you must do this before activating your new gateway module in WHMCS)&lt;br /&gt;
# Next, enter your gateway specific code for processing the payment into the _capture function. This normally takes the format of an HTTP/Curl request to the gateway providers API.&lt;br /&gt;
&lt;br /&gt;
The variables available to you are:&lt;br /&gt;
&lt;br /&gt;
===Invoice Variables===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['invoiceid'] # Invoice ID Number&lt;br /&gt;
$params['description'] # Description (eg. Company Name - Invoice #xxx)&lt;br /&gt;
$params['amount'] # Format: xxx.xx&lt;br /&gt;
$params['currency'] # Currency Code (eg. GBP, USD, etc...)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Client Variables===&lt;br /&gt;
&amp;lt;source lang = &amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['clientdetails']['firstname'] # Clients First Name&lt;br /&gt;
$params['clientdetails']['lastname'] # Clients Last Name&lt;br /&gt;
$params['clientdetails']['email'] # Clients Email Address&lt;br /&gt;
$params['clientdetails']['address1'] # Clients Address&lt;br /&gt;
$params['clientdetails']['address2']&lt;br /&gt;
$params['clientdetails']['city']&lt;br /&gt;
$params['clientdetails']['state']&lt;br /&gt;
$params['clientdetails']['postcode']&lt;br /&gt;
$params['clientdetails']['country']&lt;br /&gt;
$params['clientdetails']['phonenumber']&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===# System Variables===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['companyname'] # your Company Name setting in WHMCS&lt;br /&gt;
$params['systemurl'] – the url to the Client Area&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Card Details===&lt;br /&gt;
&amp;lt;source lang = &amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['cardtype'] # the Card Type (Visa, MasterCard, etc…)&lt;br /&gt;
$params['cardnum'] # the Card Number&lt;br /&gt;
$params['cardexp'] # the Card’s Expiry Date (Format: MMYY)&lt;br /&gt;
$params['cardstart'] # the Card’s Start Date (Format: MMYY)&lt;br /&gt;
$params['cardissuenum'] # the Card’s Issue Number (Switch/Solo Cards)&lt;br /&gt;
$params['cccvv'] #Not always present (recurring transactions)&lt;br /&gt;
#but would always be present for client initiated attempts&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# Once you have processed the transaction and got a response, you need to return an array to WHMCS with the results. The return for a successful capture should be as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
return array(&amp;quot;status&amp;quot;=&amp;gt;&amp;quot;success&amp;quot;,&amp;quot;transid&amp;quot;=&amp;gt;$results[&amp;quot;transid&amp;quot;],&amp;quot;rawdata&amp;quot;=&amp;gt;$results);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Within this array, the status must be success to tell WHMCS the capture was successful, transid should be passed the value of the transaction ID that came back from the gateway, and the rawdata variable should be passed an array of the data returned from the gateway to be stored in the WHMCS Gateway Log.&lt;br /&gt;
&lt;br /&gt;
If the transaction were to fail then the response should instead be as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
return array(&amp;quot;status&amp;quot;=&amp;gt;&amp;quot;declined&amp;quot;,&amp;quot;rawdata&amp;quot;=&amp;gt;$results);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this response, the status can be any value you want, declined, error, invalid hash, etc… and will be what staff get to see as the failure reason within the gateway log. The rawdata variable should again be passed an array of the data returned from the gateway to be stored in the WHMCS Gateway Log for debugging purposes.&lt;br /&gt;
&lt;br /&gt;
# If your gateway supports 3D Secure (Verified by Visa or MasterCard Secure Code) then please refer to page 8 for information on how to do handle that.&lt;br /&gt;
&lt;br /&gt;
===Refunds===&lt;br /&gt;
&lt;br /&gt;
# If your gateway provider supports automated refunds then you should add your code for processing a refund into the _refund function which is passed all the same variables as capture but with one additional variable:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['transid'] # the transaction ID of the original transaction to be refunded&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The return arrays for a success or failure should be done exactly the same as described above for the capture function.&lt;br /&gt;
&lt;br /&gt;
If your gateway provider does not support refunds, then the _refund function should be deleted from the module file.&lt;br /&gt;
&lt;br /&gt;
==Callbacks==&lt;br /&gt;
If your gateway provider supports notifying a script when a payment is successful, then you can create a callback file in WHMCS to detect and apply those calls as payments inside WHMCS.&lt;br /&gt;
&lt;br /&gt;
A sample callback file is included in the dev kit for this purpose named “callback.php”. To utilise this script, you simply need to rename it to match your gateway module, and modify the variables within it as per the comments in the code, and to match the variables your specific gateway returns.&lt;br /&gt;
&lt;br /&gt;
These are some helper functions within the sample that you might find useful:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$GATEWAY = getGatewayVariables(‘yourgatewayname’);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function can be used to retrieve the configuration data for your module as specified in&lt;br /&gt;
the _config array. For example you might need it to get a gateway username or secret key to&lt;br /&gt;
validate a callback.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$invoiceid = checkCbInvoiceID($invoiceid,$GATEWAY[‘name’]);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function can be used to check the invoice ID received back is valid. You should simply pass the $invoiceid into this function and your gateway name and if a valid invoice number the script will continue executing, otherwise the script will be halted and an appropriate gateway log entry created.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang =&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
checkCbTransID($transid);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function can be used to check for any existing transactions already recorded for a given transaction ID. This can be useful for protecting against duplicate callbacks as if the transaction ID is already found in the database, the callback script execution will be halted.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
logTransaction($GATEWAY[‘name’],$_POST,&amp;quot;Successful&amp;quot;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function can be used to create a gateway log entry. The first variable needs to be the name of the gateway module, the second should be an array of data, such as the $_POST or $_REQUEST super globals, and the last variable should be the result/status to show in the log.&lt;br /&gt;
&lt;br /&gt;
== 3D Secure Process ==&lt;br /&gt;
&lt;br /&gt;
If your merchant gateway supports 3D Secure (also known as Verified by Visa or MasterCard Secure Code) and you want to implement that then you can as WHMCS fully supports 3D Secured payments.&lt;br /&gt;
&lt;br /&gt;
To do this you need to add a function to your module named yourgatewayname_3dsecure and then similar to the _link function of a third party gateway module, you need to return the HTML for the form post to take the user to the 3D Secure process. An example of this is below.&lt;br /&gt;
&lt;br /&gt;
The _3dsecure function is passed all the same variables that the _capture function is (see page 6). Your return url should be a callback file to handle the response (see page 9)&lt;br /&gt;
&lt;br /&gt;
==Example==&lt;br /&gt;
&amp;lt;source lang = &amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
function yourgatewayname_3dsecure($params) {&lt;br /&gt;
$code = '&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;https://www.gateway.com/3dsecure/&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;gwlogin&amp;quot; value=&amp;quot;'.$params[&amp;quot;loginid&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;invoiceid&amp;quot; value=&amp;quot;'.$params[&amp;quot;invoiceid&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;amount&amp;quot; value=&amp;quot;'. $params[&amp;quot;amount&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;firstname&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;firstname&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;lastname&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;lastname&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;address&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;address1&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;city&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;city&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;state&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;state&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;postcode&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;postcode&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;country&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;country&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;phonenumber&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;phonenumber&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;email&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;email&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;ccnumber&amp;quot; value=&amp;quot;'. $params[&amp;quot;cardnum&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;expirymonth&amp;quot; value=&amp;quot;'.substr($params['cardexp'],0,2).'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;expiryyear&amp;quot; value=&amp;quot;'.substr($params['cardexp'],2,2).'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;cvv2&amp;quot; value=&amp;quot;'. $params[&amp;quot;cccvv&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;return_url&amp;quot; value=&amp;quot;'.&lt;br /&gt;
$params['systemurl'].'/modules/gateways/callback/yourgatewayname.php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;noscript&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;errorbox&amp;quot;&amp;gt;&amp;lt;b&amp;gt;JavaScript is currently disabled or is not supported by your&lt;br /&gt;
browser.&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Please click the continue button to proceed with the processing of your&lt;br /&gt;
transaction.&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Continue &amp;gt;&amp;gt;&amp;quot; /&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/noscript&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;';&lt;br /&gt;
      return $code;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Tokenised Remote Storage==&lt;br /&gt;
&lt;br /&gt;
These days, with the increasing rules &amp;amp; requirements surrounding the storing of credit card details, many merchant gateways are offering services where you can perform repeat rebills without needing to store credit card details locally on your own system. And with WHMCS, gateway modules can utilise this functionality when available.&lt;br /&gt;
&lt;br /&gt;
The basic logic behind token gateways in WHMCS is that clients must either have a credit card number or a token stored in order for recurring billing to be attempted. So if you create a function named _storeremote in your custom gateway module, this function will then override the default local storage when new credit card details are entered. And instead of&lt;br /&gt;
saving in the database, that function then needs to communicate with the gateways API, and return the token that gets assigned to WHMCS.&lt;br /&gt;
&lt;br /&gt;
The variables passed into the _storeremote function are as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang =&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['gatewayid'] # the token stored for the client&lt;br /&gt;
$params['cardtype'] #the Card Type (Visa, MasterCard, etc…)&lt;br /&gt;
$params['cardnum'] # the Card Number&lt;br /&gt;
$params['cardexp'] # the Card’s Expiry Date (Format: MMYY)&lt;br /&gt;
$params['cardstart'] # the Card’s Start Date (Format: MMYY)&lt;br /&gt;
$params['cardissuenum'] # the Card’s Issue Number (Switch/Solo Cards)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
On the first call, the gatewayid will be empty. So when empty you need to create a new profile at the gateway. On subsequent calls the gatewayid that was originally created and stored will be passed in and the existing profile simply needs to be updated. And if the cardnum variable is empty, this indicates that deleting/removal of the stored credit card&lt;br /&gt;
details has been requested.&lt;br /&gt;
&lt;br /&gt;
Once the card details have been updated or stored remotely, you need to return either a success or failure response to tell WHMCS if it worked, and if it did, the token that has been assigned:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang =&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
return array(&amp;quot;status&amp;quot;=&amp;gt;&amp;quot;success&amp;quot;,&amp;quot;gatewayid&amp;quot;=&amp;gt;$results[&amp;quot;token&amp;quot;],&amp;quot;rawdata&amp;quot;=&amp;gt;$results);&lt;br /&gt;
&lt;br /&gt;
return array(&amp;quot;status&amp;quot;=&amp;gt;&amp;quot;failed&amp;quot;,&amp;quot;rawdata&amp;quot;=&amp;gt;$results);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When this function exists in a gateway module, WHMCS will only store the card type, expiry date and the last 4 digits (only) locally in the WHMCS database. So you and your clients will still be able to see exactly what card is stored remotely from within WHMCS.&lt;br /&gt;
&lt;br /&gt;
Then within the capture function, instead of $params[‘cardnum’] you will be passed $params[‘gatewayid’] with which to perform the capture.&lt;br /&gt;
&lt;br /&gt;
==Installation &amp;amp; Activation==&lt;br /&gt;
&lt;br /&gt;
To install the module you’ve created, simply upload it to the /modules/gateways/ folder and then go to Setup &amp;gt; Payment Gateways to activate. If you have create a callback file as well then that should also be uploaded but to the /modules/gateways/callback/ folder.&lt;br /&gt;
&lt;br /&gt;
'''Important:''' It is important that you do not activate your gateway module until you have&lt;br /&gt;
completed step 1 of either the third party gateway or merchant gateway module&lt;br /&gt;
documentation steps to remove the appropriate functions as it’s at the time of activation&lt;br /&gt;
that the type of module you are setting up gets stored in the system.&lt;br /&gt;
&lt;br /&gt;
==Blank Screen/Errors==&lt;br /&gt;
&lt;br /&gt;
If you get a blank page or errors in the Setup &amp;gt; Payment Gateways page after uploading your new module file then this indicates there is a syntax error in your code. To debug that, you can add the following line to your WHMCS configuration.php file to turn on error reporting:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$display_errors = true;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That will enable PHP error reporting and should show you the cause of any issues. Once you are done testing you must remember to remove that line again.&lt;br /&gt;
&lt;br /&gt;
==App Store==&lt;br /&gt;
WHMCS offers an app store to which your completed module can be submitted. The listings are displayed under the Addons tab within the administration area and online at http://www.whmcs.com/appstore . This is a great way to make WHMCS users aware of your module.&lt;br /&gt;
&lt;br /&gt;
In order to submit a listing you'll need a login for whmcs.com/members, if you do not have one please [https://www.whmcs.com/members/submitticket.php?step=2&amp;amp;deptid=5 Contact Us]. Once logged in, visit the app store page at the above URL and click the &amp;quot;Submit your Addon&amp;quot; link. We aim to review submissions in 1-2 weeks.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Developer_Links}}&lt;/div&gt;</summary>
		<author><name>Nicolas</name></author>	</entry>

	<entry>
		<id>http://3.19.219.109/index.php?title=Gateway_Module_Developer_Docs&amp;diff=17522</id>
		<title>Gateway Module Developer Docs</title>
		<link rel="alternate" type="text/html" href="http://3.19.219.109/index.php?title=Gateway_Module_Developer_Docs&amp;diff=17522"/>
				<updated>2016-01-06T19:54:27Z</updated>
		
		<summary type="html">&lt;p&gt;Nicolas: /* #System Variables */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Creating a gateway module allows you to connect WHMCS to third party payment and credit card processors that aren’t natively supported in WHMCS as standard.&lt;br /&gt;
&lt;br /&gt;
There are 2 core types of gateway module:&lt;br /&gt;
&lt;br /&gt;
#'''Third Party Gateways''' – this is where the customer leaves your site to pay and is returned once the payment process is completed&lt;br /&gt;
#'''Merchant Gateways''' – this is where the customer enters credit card details directly on your website and the payment is then processed in the background (can also include 3D Secure where the user leaves your site)&lt;br /&gt;
&lt;br /&gt;
{{Developer_Links}}&lt;br /&gt;
&lt;br /&gt;
So the first decision you need to make before starting your module for WHMCS is which type of gateway module you will be creating.  Once you have that, you're ready to begin.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Introduction==&lt;br /&gt;
&lt;br /&gt;
Gateway modules allow a connection between WHMCS and gateways or credit card processors that aren't natively supported in WHMCS.&lt;br /&gt;
&lt;br /&gt;
This documentation will explain the module's structure and contains everything needed in order to successfully create a gateway module for WHMCS.&lt;br /&gt;
&lt;br /&gt;
==Getting Started==&lt;br /&gt;
&lt;br /&gt;
To get started, begin by downloading the module development kit from our GitHub site. There are two sample modules available, depending upon the [[#Module Type|type of gateway]] being developed:&lt;br /&gt;
*Third Party Gateway: https://github.com/WHMCS/sample-gateway-module&lt;br /&gt;
*Merchant Gateway: https://github.com/WHMCS/sample-merchant-gateway&lt;br /&gt;
Take the gateway module template &amp;quot;template.php&amp;quot; from this download and rename it to &amp;quot;yourgatewayname.php&amp;quot;.  It should be all lowercase and must start with a letter.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;docs-alert-warning&amp;quot;&amp;gt;&lt;br /&gt;
All functions within a gateway module must be prefixed with the filename.  Open the file and replace all occurrences of &amp;quot;template_&amp;quot; with &amp;quot;yougatewayname_&amp;quot;.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Config Array===&lt;br /&gt;
&lt;br /&gt;
'''Configure the yourgatewayname_config array'''. This function is the primary function required by all gateway modules and defines both the friendly display name for the module and any custom fields/options/settings that the gateway module requires.&lt;br /&gt;
&lt;br /&gt;
The available field types are &amp;quot;text&amp;quot;, &amp;quot;dropdown&amp;quot;, &amp;quot;textarea&amp;quot; and &amp;quot;yesno&amp;quot; (checkboxes).   The sample config array in &amp;quot;template.php&amp;quot; demonstrates how to use each of these types. &lt;br /&gt;
&lt;br /&gt;
The general formula is to:&lt;br /&gt;
#Specify a system name (''all in lowercase for the setting to be referenced by in the module code itself'')&lt;br /&gt;
#A FriendlyName&lt;br /&gt;
#Type&lt;br /&gt;
#Any settings specific to that field type.&lt;br /&gt;
&lt;br /&gt;
Any fields defined here will be available in all gateway module functions in the $params array, so avoid common names like currency, invoiceid, etc, as these will conflict with the standard variables.&lt;br /&gt;
&lt;br /&gt;
===Module Type===&lt;br /&gt;
&lt;br /&gt;
Determine which type of module needs to be created from the 2 core types:&lt;br /&gt;
&lt;br /&gt;
#'''Third Party Gateways''' – the customer leaves your site to pay and is returned once the payment process is completed.&lt;br /&gt;
#'''Merchant Gateways''' – where the customer enters credit card details directly on your website and the payment is then processed in the background (can also include 3D Secure where the user leaves your site).&lt;br /&gt;
&lt;br /&gt;
For a Third Party gateway go to [[#Third_Party_Gateway]], and for a merchant gateway go to [[#Merchant_Gateway]].&lt;br /&gt;
&lt;br /&gt;
==Third Party Gateway==&lt;br /&gt;
&lt;br /&gt;
Follow the steps below to create a third party gateway module (one where the customer leaves your site to make the payment on the gateway provider's website):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;docs-alert-warning&amp;quot;&amp;gt;'''Important:''' This must be done before activating the gateway module in WHMCS.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#Begin by deleting the _capture function from the module template.&lt;br /&gt;
#Enter the gateway-specific code for taking the user to the payment process within the _link function.  An example of this step is shown in the gateway module template supplied with the dev kit.  Normally, the code output by this function is the HTML for a '''&amp;lt;form&amp;gt;''' with a ''post'' method.&lt;br /&gt;
&lt;br /&gt;
The available variables are:&lt;br /&gt;
&lt;br /&gt;
===Invoice Variables===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['invoiceid'] # Invoice ID Number&lt;br /&gt;
$params['description'] # Description (eg. Company Name - Invoice #xxx)&lt;br /&gt;
$params['amount'] # Format: xxx.xx&lt;br /&gt;
$params['currency'] # Currency Code (eg. GBD, USD, etc...)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Client Variables===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['clientdetails']['firstname'] # Clients First Name&lt;br /&gt;
$params['clientdetails']['lastname'] # Clients Last Name&lt;br /&gt;
$params['clientdetails']['email'] # Clients Email Address&lt;br /&gt;
$params['clientdetails']['address1'] # Clients Address&lt;br /&gt;
$params['clientdetails']['address2'] &lt;br /&gt;
$params['clientdetails']['city']&lt;br /&gt;
$params['clientdetails']['state']&lt;br /&gt;
$params['clientdetails']['postcode']&lt;br /&gt;
$params['clientdetails']['country']&lt;br /&gt;
$params['clientdetails']['phonenumber']&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===System Variables===&lt;br /&gt;
&amp;lt;source lang = &amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['companyname'] # your Company Name setting in WHMCS&lt;br /&gt;
$params['systemurl'] # the url to the Client Area&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# The processing of a payment is handled by a callback file separate from the module (see page 9 for more information).&lt;br /&gt;
# If your gateway provider doesn't support automated refunds or you won't be including them in the module, then delete the '''_refund''' function.  Otherwise, refer to the Refund section on page 7.&lt;br /&gt;
&lt;br /&gt;
==Merchant Gateway==&lt;br /&gt;
&lt;br /&gt;
To create a merchant gateway module, where the customer enters their card details directly via the client area without leaving the site, simply follow the steps below.&lt;br /&gt;
&lt;br /&gt;
# Begin by deleting the _link function from the module template (important: you must do this before activating your new gateway module in WHMCS)&lt;br /&gt;
# Next, enter your gateway specific code for processing the payment into the _capture function. This normally takes the format of an HTTP/Curl request to the gateway providers API.&lt;br /&gt;
&lt;br /&gt;
The variables available to you are:&lt;br /&gt;
&lt;br /&gt;
===Invoice Variables===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['invoiceid'] # Invoice ID Number&lt;br /&gt;
$params['description'] # Description (eg. Company Name - Invoice #xxx)&lt;br /&gt;
$params['amount'] # Format: xxx.xx&lt;br /&gt;
$params['currency'] # Currency Code (eg. GBP, USD, etc...)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Client Variables===&lt;br /&gt;
&amp;lt;source lang = &amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['clientdetails']['firstname'] # Clients First Name&lt;br /&gt;
$params['clientdetails']['lastname'] # Clients Last Name&lt;br /&gt;
$params['clientdetails']['email'] # Clients Email Address&lt;br /&gt;
$params['clientdetails']['address1'] # Clients Address&lt;br /&gt;
$params['clientdetails']['address2']&lt;br /&gt;
$params['clientdetails']['city']&lt;br /&gt;
$params['clientdetails']['state']&lt;br /&gt;
$params['clientdetails']['postcode']&lt;br /&gt;
$params['clientdetails']['country']&lt;br /&gt;
$params['clientdetails']['phonenumber']&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===# System Variables===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['companyname'] # your Company Name setting in WHMCS&lt;br /&gt;
$params['systemurl'] – the url to the Client Area&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Card Details===&lt;br /&gt;
&amp;lt;source lang = &amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['cardtype'] # the Card Type (Visa, MasterCard, etc…)&lt;br /&gt;
$params['cardnum'] # the Card Number&lt;br /&gt;
$params['cardexp'] # the Card’s Expiry Date (Format: MMYY)&lt;br /&gt;
$params['cardstart'] # the Card’s Start Date (Format: MMYY)&lt;br /&gt;
$params['cardissuenum'] # the Card’s Issue Number (Switch/Solo Cards)&lt;br /&gt;
$params['cccvv'] #Not always present (recurring transactions)&lt;br /&gt;
#but would always be present for client initiated attempts&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# Once you have processed the transaction and got a response, you need to return an array to WHMCS with the results. The return for a successful capture should be as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
return array(&amp;quot;status&amp;quot;=&amp;gt;&amp;quot;success&amp;quot;,&amp;quot;transid&amp;quot;=&amp;gt;$results[&amp;quot;transid&amp;quot;],&amp;quot;rawdata&amp;quot;=&amp;gt;$results);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Within this array, the status must be success to tell WHMCS the capture was successful, transid should be passed the value of the transaction ID that came back from the gateway, and the rawdata variable should be passed an array of the data returned from the gateway to be stored in the WHMCS Gateway Log.&lt;br /&gt;
&lt;br /&gt;
If the transaction were to fail then the response should instead be as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
return array(&amp;quot;status&amp;quot;=&amp;gt;&amp;quot;declined&amp;quot;,&amp;quot;rawdata&amp;quot;=&amp;gt;$results);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this response, the status can be any value you want, declined, error, invalid hash, etc… and will be what staff get to see as the failure reason within the gateway log. The rawdata variable should again be passed an array of the data returned from the gateway to be stored in the WHMCS Gateway Log for debugging purposes.&lt;br /&gt;
&lt;br /&gt;
# If your gateway supports 3D Secure (Verified by Visa or MasterCard Secure Code) then please refer to page 8 for information on how to do handle that.&lt;br /&gt;
&lt;br /&gt;
===Refunds===&lt;br /&gt;
&lt;br /&gt;
# If your gateway provider supports automated refunds then you should add your code for processing a refund into the _refund function which is passed all the same variables as capture but with one additional variable:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['transid'] # the transaction ID of the original transaction to be refunded&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The return arrays for a success or failure should be done exactly the same as described above for the capture function.&lt;br /&gt;
&lt;br /&gt;
If your gateway provider does not support refunds, then the _refund function should be deleted from the module file.&lt;br /&gt;
&lt;br /&gt;
==Callbacks==&lt;br /&gt;
If your gateway provider supports notifying a script when a payment is successful, then you can create a callback file in WHMCS to detect and apply those calls as payments inside WHMCS.&lt;br /&gt;
&lt;br /&gt;
A sample callback file is included in the dev kit for this purpose named “callback.php”. To utilise this script, you simply need to rename it to match your gateway module, and modify the variables within it as per the comments in the code, and to match the variables your specific gateway returns.&lt;br /&gt;
&lt;br /&gt;
These are some helper functions within the sample that you might find useful:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$GATEWAY = getGatewayVariables(‘yourgatewayname’);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function can be used to retrieve the configuration data for your module as specified in&lt;br /&gt;
the _config array. For example you might need it to get a gateway username or secret key to&lt;br /&gt;
validate a callback.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$invoiceid = checkCbInvoiceID($invoiceid,$GATEWAY[‘name’]);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function can be used to check the invoice ID received back is valid. You should simply pass the $invoiceid into this function and your gateway name and if a valid invoice number the script will continue executing, otherwise the script will be halted and an appropriate gateway log entry created.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang =&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
checkCbTransID($transid);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function can be used to check for any existing transactions already recorded for a given transaction ID. This can be useful for protecting against duplicate callbacks as if the transaction ID is already found in the database, the callback script execution will be halted.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
logTransaction($GATEWAY[‘name’],$_POST,&amp;quot;Successful&amp;quot;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function can be used to create a gateway log entry. The first variable needs to be the name of the gateway module, the second should be an array of data, such as the $_POST or $_REQUEST super globals, and the last variable should be the result/status to show in the log.&lt;br /&gt;
&lt;br /&gt;
== 3D Secure Process ==&lt;br /&gt;
&lt;br /&gt;
If your merchant gateway supports 3D Secure (also known as Verified by Visa or MasterCard Secure Code) and you want to implement that then you can as WHMCS fully supports 3D Secured payments.&lt;br /&gt;
&lt;br /&gt;
To do this you need to add a function to your module named yourgatewayname_3dsecure and then similar to the _link function of a third party gateway module, you need to return the HTML for the form post to take the user to the 3D Secure process. An example of this is below.&lt;br /&gt;
&lt;br /&gt;
The _3dsecure function is passed all the same variables that the _capture function is (see page 6). Your return url should be a callback file to handle the response (see page 9)&lt;br /&gt;
&lt;br /&gt;
==Example==&lt;br /&gt;
&amp;lt;source lang = &amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
function yourgatewayname_3dsecure($params) {&lt;br /&gt;
$code = '&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;https://www.gateway.com/3dsecure/&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;gwlogin&amp;quot; value=&amp;quot;'.$params[&amp;quot;loginid&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;invoiceid&amp;quot; value=&amp;quot;'.$params[&amp;quot;invoiceid&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;amount&amp;quot; value=&amp;quot;'. $params[&amp;quot;amount&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;firstname&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;firstname&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;lastname&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;lastname&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;address&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;address1&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;city&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;city&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;state&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;state&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;postcode&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;postcode&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;country&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;country&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;phonenumber&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;phonenumber&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;email&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;email&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;ccnumber&amp;quot; value=&amp;quot;'. $params[&amp;quot;cardnum&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;expirymonth&amp;quot; value=&amp;quot;'.substr($params['cardexp'],0,2).'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;expiryyear&amp;quot; value=&amp;quot;'.substr($params['cardexp'],2,2).'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;cvv2&amp;quot; value=&amp;quot;'. $params[&amp;quot;cccvv&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;return_url&amp;quot; value=&amp;quot;'.&lt;br /&gt;
$params['systemurl'].'/modules/gateways/callback/yourgatewayname.php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;noscript&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;errorbox&amp;quot;&amp;gt;&amp;lt;b&amp;gt;JavaScript is currently disabled or is not supported by your&lt;br /&gt;
browser.&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Please click the continue button to proceed with the processing of your&lt;br /&gt;
transaction.&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Continue &amp;gt;&amp;gt;&amp;quot; /&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/noscript&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;';&lt;br /&gt;
      return $code;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Tokenised Remote Storage==&lt;br /&gt;
&lt;br /&gt;
These days, with the increasing rules &amp;amp; requirements surrounding the storing of credit card details, many merchant gateways are offering services where you can perform repeat rebills without needing to store credit card details locally on your own system. And with WHMCS, gateway modules can utilise this functionality when available.&lt;br /&gt;
&lt;br /&gt;
The basic logic behind token gateways in WHMCS is that clients must either have a credit card number or a token stored in order for recurring billing to be attempted. So if you create a function named _storeremote in your custom gateway module, this function will then override the default local storage when new credit card details are entered. And instead of&lt;br /&gt;
saving in the database, that function then needs to communicate with the gateways API, and return the token that gets assigned to WHMCS.&lt;br /&gt;
&lt;br /&gt;
The variables passed into the _storeremote function are as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang =&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['gatewayid'] # the token stored for the client&lt;br /&gt;
$params['cardtype'] #the Card Type (Visa, MasterCard, etc…)&lt;br /&gt;
$params['cardnum'] # the Card Number&lt;br /&gt;
$params['cardexp'] # the Card’s Expiry Date (Format: MMYY)&lt;br /&gt;
$params['cardstart'] # the Card’s Start Date (Format: MMYY)&lt;br /&gt;
$params['cardissuenum'] # the Card’s Issue Number (Switch/Solo Cards)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
On the first call, the gatewayid will be empty. So when empty you need to create a new profile at the gateway. On subsequent calls the gatewayid that was originally created and stored will be passed in and the existing profile simply needs to be updated. And if the cardnum variable is empty, this indicates that deleting/removal of the stored credit card&lt;br /&gt;
details has been requested.&lt;br /&gt;
&lt;br /&gt;
Once the card details have been updated or stored remotely, you need to return either a success or failure response to tell WHMCS if it worked, and if it did, the token that has been assigned:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang =&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
return array(&amp;quot;status&amp;quot;=&amp;gt;&amp;quot;success&amp;quot;,&amp;quot;gatewayid&amp;quot;=&amp;gt;$results[&amp;quot;token&amp;quot;],&amp;quot;rawdata&amp;quot;=&amp;gt;$results);&lt;br /&gt;
&lt;br /&gt;
return array(&amp;quot;status&amp;quot;=&amp;gt;&amp;quot;failed&amp;quot;,&amp;quot;rawdata&amp;quot;=&amp;gt;$results);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When this function exists in a gateway module, WHMCS will only store the card type, expiry date and the last 4 digits (only) locally in the WHMCS database. So you and your clients will still be able to see exactly what card is stored remotely from within WHMCS.&lt;br /&gt;
&lt;br /&gt;
Then within the capture function, instead of $params[‘cardnum’] you will be passed $params[‘gatewayid’] with which to perform the capture.&lt;br /&gt;
&lt;br /&gt;
==Installation &amp;amp; Activation==&lt;br /&gt;
&lt;br /&gt;
To install the module you’ve created, simply upload it to the /modules/gateways/ folder and then go to Setup &amp;gt; Payment Gateways to activate. If you have create a callback file as well then that should also be uploaded but to the /modules/gateways/callback/ folder.&lt;br /&gt;
&lt;br /&gt;
'''Important:''' It is important that you do not activate your gateway module until you have&lt;br /&gt;
completed step 1 of either the third party gateway or merchant gateway module&lt;br /&gt;
documentation steps to remove the appropriate functions as it’s at the time of activation&lt;br /&gt;
that the type of module you are setting up gets stored in the system.&lt;br /&gt;
&lt;br /&gt;
==Blank Screen/Errors==&lt;br /&gt;
&lt;br /&gt;
If you get a blank page or errors in the Setup &amp;gt; Payment Gateways page after uploading your new module file then this indicates there is a syntax error in your code. To debug that, you can add the following line to your WHMCS configuration.php file to turn on error reporting:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$display_errors = true;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That will enable PHP error reporting and should show you the cause of any issues. Once you are done testing you must remember to remove that line again.&lt;br /&gt;
&lt;br /&gt;
==App Store==&lt;br /&gt;
WHMCS offers an app store to which your completed module can be submitted. The listings are displayed under the Addons tab within the administration area and online at http://www.whmcs.com/appstore . This is a great way to make WHMCS users aware of your module.&lt;br /&gt;
&lt;br /&gt;
In order to submit a listing you'll need a login for whmcs.com/members, if you do not have one please [https://www.whmcs.com/members/submitticket.php?step=2&amp;amp;deptid=5 Contact Us]. Once logged in, visit the app store page at the above URL and click the &amp;quot;Submit your Addon&amp;quot; link. We aim to review submissions in 1-2 weeks.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Developer_Links}}&lt;/div&gt;</summary>
		<author><name>Nicolas</name></author>	</entry>

	<entry>
		<id>http://3.19.219.109/index.php?title=Gateway_Module_Developer_Docs&amp;diff=17518</id>
		<title>Gateway Module Developer Docs</title>
		<link rel="alternate" type="text/html" href="http://3.19.219.109/index.php?title=Gateway_Module_Developer_Docs&amp;diff=17518"/>
				<updated>2016-01-06T19:51:59Z</updated>
		
		<summary type="html">&lt;p&gt;Nicolas: /* Third Party Gateway */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Creating a gateway module allows you to connect WHMCS to third party payment and credit card processors that aren’t natively supported in WHMCS as standard.&lt;br /&gt;
&lt;br /&gt;
There are 2 core types of gateway module:&lt;br /&gt;
&lt;br /&gt;
#'''Third Party Gateways''' – this is where the customer leaves your site to pay and is returned once the payment process is completed&lt;br /&gt;
#'''Merchant Gateways''' – this is where the customer enters credit card details directly on your website and the payment is then processed in the background (can also include 3D Secure where the user leaves your site)&lt;br /&gt;
&lt;br /&gt;
{{Developer_Links}}&lt;br /&gt;
&lt;br /&gt;
So the first decision you need to make before starting your module for WHMCS is which type of gateway module you will be creating.  Once you have that, you're ready to begin.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Introduction==&lt;br /&gt;
&lt;br /&gt;
Gateway modules allow a connection between WHMCS and gateways or credit card processors that aren't natively supported in WHMCS.&lt;br /&gt;
&lt;br /&gt;
This documentation will explain the module's structure and contains everything needed in order to successfully create a gateway module for WHMCS.&lt;br /&gt;
&lt;br /&gt;
==Getting Started==&lt;br /&gt;
&lt;br /&gt;
To get started, begin by downloading the module development kit from our GitHub site. There are two sample modules available, depending upon the [[#Module Type|type of gateway]] being developed:&lt;br /&gt;
*Third Party Gateway: https://github.com/WHMCS/sample-gateway-module&lt;br /&gt;
*Merchant Gateway: https://github.com/WHMCS/sample-merchant-gateway&lt;br /&gt;
Take the gateway module template &amp;quot;template.php&amp;quot; from this download and rename it to &amp;quot;yourgatewayname.php&amp;quot;.  It should be all lowercase and must start with a letter.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;docs-alert-warning&amp;quot;&amp;gt;&lt;br /&gt;
All functions within a gateway module must be prefixed with the filename.  Open the file and replace all occurrences of &amp;quot;template_&amp;quot; with &amp;quot;yougatewayname_&amp;quot;.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Config Array===&lt;br /&gt;
&lt;br /&gt;
'''Configure the yourgatewayname_config array'''. This function is the primary function required by all gateway modules and defines both the friendly display name for the module and any custom fields/options/settings that the gateway module requires.&lt;br /&gt;
&lt;br /&gt;
The available field types are &amp;quot;text&amp;quot;, &amp;quot;dropdown&amp;quot;, &amp;quot;textarea&amp;quot; and &amp;quot;yesno&amp;quot; (checkboxes).   The sample config array in &amp;quot;template.php&amp;quot; demonstrates how to use each of these types. &lt;br /&gt;
&lt;br /&gt;
The general formula is to:&lt;br /&gt;
#Specify a system name (''all in lowercase for the setting to be referenced by in the module code itself'')&lt;br /&gt;
#A FriendlyName&lt;br /&gt;
#Type&lt;br /&gt;
#Any settings specific to that field type.&lt;br /&gt;
&lt;br /&gt;
Any fields defined here will be available in all gateway module functions in the $params array, so avoid common names like currency, invoiceid, etc, as these will conflict with the standard variables.&lt;br /&gt;
&lt;br /&gt;
===Module Type===&lt;br /&gt;
&lt;br /&gt;
Determine which type of module needs to be created from the 2 core types:&lt;br /&gt;
&lt;br /&gt;
#'''Third Party Gateways''' – the customer leaves your site to pay and is returned once the payment process is completed.&lt;br /&gt;
#'''Merchant Gateways''' – where the customer enters credit card details directly on your website and the payment is then processed in the background (can also include 3D Secure where the user leaves your site).&lt;br /&gt;
&lt;br /&gt;
For a Third Party gateway go to [[#Third_Party_Gateway]], and for a merchant gateway go to [[#Merchant_Gateway]].&lt;br /&gt;
&lt;br /&gt;
==Third Party Gateway==&lt;br /&gt;
&lt;br /&gt;
Follow the steps below to create a third party gateway module (one where the customer leaves your site to make the payment on the gateway provider's website):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;docs-alert-warning&amp;quot;&amp;gt;'''Important:''' This must be done before activating the gateway module in WHMCS.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#Begin by deleting the _capture function from the module template.&lt;br /&gt;
#Enter the gateway-specific code for taking the user to the payment process within the _link function.  An example of this step is shown in the gateway module template supplied with the dev kit.  Normally, the code output by this function is the HTML for a '''&amp;lt;form&amp;gt;''' with a ''post'' method.&lt;br /&gt;
&lt;br /&gt;
The available variables are:&lt;br /&gt;
&lt;br /&gt;
===Invoice Variables===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['invoiceid'] # Invoice ID Number&lt;br /&gt;
$params['description'] # Description (eg. Company Name - Invoice #xxx)&lt;br /&gt;
$params['amount'] # Format: xxx.xx&lt;br /&gt;
$params['currency'] # Currency Code (eg. GBD, USD, etc...)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Client Variables===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['clientdetails']['firstname'] # Clients First Name&lt;br /&gt;
$params['clientdetails']['lastname'] # Clients Last Name&lt;br /&gt;
$params['clientdetails']['email'] # Clients Email Address&lt;br /&gt;
$params['clientdetails']['address1'] # Clients Address&lt;br /&gt;
$params['clientdetails']['address2'] &lt;br /&gt;
$params['clientdetails']['city']&lt;br /&gt;
$params['clientdetails']['state']&lt;br /&gt;
$params['clientdetails']['postcode']&lt;br /&gt;
$params['clientdetails']['country']&lt;br /&gt;
$params['clientdetails']['phonenumber']&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===#System Variables===&lt;br /&gt;
&amp;lt;source lang = &amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['companyname'] # your Company Name setting in WHMCS&lt;br /&gt;
$params['systemurl'] # the url to the Client Area&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# The processing of a payment is handled by a callback file separate from the module (see page 9 for more info on that).&lt;br /&gt;
# If your gateway provider doesn't support automated refunds or you won't be including them in the module then you should delete the _refund function as well, otherwise refer to the Refund section on page 7.&lt;br /&gt;
&lt;br /&gt;
==Merchant Gateway==&lt;br /&gt;
&lt;br /&gt;
To create a merchant gateway module, where the customer enters their card details directly via the client area without leaving the site, simply follow the steps below.&lt;br /&gt;
&lt;br /&gt;
# Begin by deleting the _link function from the module template (important: you must do this before activating your new gateway module in WHMCS)&lt;br /&gt;
# Next, enter your gateway specific code for processing the payment into the _capture function. This normally takes the format of an HTTP/Curl request to the gateway providers API.&lt;br /&gt;
&lt;br /&gt;
The variables available to you are:&lt;br /&gt;
&lt;br /&gt;
===Invoice Variables===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['invoiceid'] # Invoice ID Number&lt;br /&gt;
$params['description'] # Description (eg. Company Name - Invoice #xxx)&lt;br /&gt;
$params['amount'] # Format: xxx.xx&lt;br /&gt;
$params['currency'] # Currency Code (eg. GBP, USD, etc...)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Client Variables===&lt;br /&gt;
&amp;lt;source lang = &amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['clientdetails']['firstname'] # Clients First Name&lt;br /&gt;
$params['clientdetails']['lastname'] # Clients Last Name&lt;br /&gt;
$params['clientdetails']['email'] # Clients Email Address&lt;br /&gt;
$params['clientdetails']['address1'] # Clients Address&lt;br /&gt;
$params['clientdetails']['address2']&lt;br /&gt;
$params['clientdetails']['city']&lt;br /&gt;
$params['clientdetails']['state']&lt;br /&gt;
$params['clientdetails']['postcode']&lt;br /&gt;
$params['clientdetails']['country']&lt;br /&gt;
$params['clientdetails']['phonenumber']&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===# System Variables===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['companyname'] # your Company Name setting in WHMCS&lt;br /&gt;
$params['systemurl'] – the url to the Client Area&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Card Details===&lt;br /&gt;
&amp;lt;source lang = &amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['cardtype'] # the Card Type (Visa, MasterCard, etc…)&lt;br /&gt;
$params['cardnum'] # the Card Number&lt;br /&gt;
$params['cardexp'] # the Card’s Expiry Date (Format: MMYY)&lt;br /&gt;
$params['cardstart'] # the Card’s Start Date (Format: MMYY)&lt;br /&gt;
$params['cardissuenum'] # the Card’s Issue Number (Switch/Solo Cards)&lt;br /&gt;
$params['cccvv'] #Not always present (recurring transactions)&lt;br /&gt;
#but would always be present for client initiated attempts&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# Once you have processed the transaction and got a response, you need to return an array to WHMCS with the results. The return for a successful capture should be as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
return array(&amp;quot;status&amp;quot;=&amp;gt;&amp;quot;success&amp;quot;,&amp;quot;transid&amp;quot;=&amp;gt;$results[&amp;quot;transid&amp;quot;],&amp;quot;rawdata&amp;quot;=&amp;gt;$results);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Within this array, the status must be success to tell WHMCS the capture was successful, transid should be passed the value of the transaction ID that came back from the gateway, and the rawdata variable should be passed an array of the data returned from the gateway to be stored in the WHMCS Gateway Log.&lt;br /&gt;
&lt;br /&gt;
If the transaction were to fail then the response should instead be as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
return array(&amp;quot;status&amp;quot;=&amp;gt;&amp;quot;declined&amp;quot;,&amp;quot;rawdata&amp;quot;=&amp;gt;$results);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this response, the status can be any value you want, declined, error, invalid hash, etc… and will be what staff get to see as the failure reason within the gateway log. The rawdata variable should again be passed an array of the data returned from the gateway to be stored in the WHMCS Gateway Log for debugging purposes.&lt;br /&gt;
&lt;br /&gt;
# If your gateway supports 3D Secure (Verified by Visa or MasterCard Secure Code) then please refer to page 8 for information on how to do handle that.&lt;br /&gt;
&lt;br /&gt;
===Refunds===&lt;br /&gt;
&lt;br /&gt;
# If your gateway provider supports automated refunds then you should add your code for processing a refund into the _refund function which is passed all the same variables as capture but with one additional variable:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['transid'] # the transaction ID of the original transaction to be refunded&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The return arrays for a success or failure should be done exactly the same as described above for the capture function.&lt;br /&gt;
&lt;br /&gt;
If your gateway provider does not support refunds, then the _refund function should be deleted from the module file.&lt;br /&gt;
&lt;br /&gt;
==Callbacks==&lt;br /&gt;
If your gateway provider supports notifying a script when a payment is successful, then you can create a callback file in WHMCS to detect and apply those calls as payments inside WHMCS.&lt;br /&gt;
&lt;br /&gt;
A sample callback file is included in the dev kit for this purpose named “callback.php”. To utilise this script, you simply need to rename it to match your gateway module, and modify the variables within it as per the comments in the code, and to match the variables your specific gateway returns.&lt;br /&gt;
&lt;br /&gt;
These are some helper functions within the sample that you might find useful:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$GATEWAY = getGatewayVariables(‘yourgatewayname’);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function can be used to retrieve the configuration data for your module as specified in&lt;br /&gt;
the _config array. For example you might need it to get a gateway username or secret key to&lt;br /&gt;
validate a callback.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$invoiceid = checkCbInvoiceID($invoiceid,$GATEWAY[‘name’]);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function can be used to check the invoice ID received back is valid. You should simply pass the $invoiceid into this function and your gateway name and if a valid invoice number the script will continue executing, otherwise the script will be halted and an appropriate gateway log entry created.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang =&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
checkCbTransID($transid);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function can be used to check for any existing transactions already recorded for a given transaction ID. This can be useful for protecting against duplicate callbacks as if the transaction ID is already found in the database, the callback script execution will be halted.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
logTransaction($GATEWAY[‘name’],$_POST,&amp;quot;Successful&amp;quot;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function can be used to create a gateway log entry. The first variable needs to be the name of the gateway module, the second should be an array of data, such as the $_POST or $_REQUEST super globals, and the last variable should be the result/status to show in the log.&lt;br /&gt;
&lt;br /&gt;
== 3D Secure Process ==&lt;br /&gt;
&lt;br /&gt;
If your merchant gateway supports 3D Secure (also known as Verified by Visa or MasterCard Secure Code) and you want to implement that then you can as WHMCS fully supports 3D Secured payments.&lt;br /&gt;
&lt;br /&gt;
To do this you need to add a function to your module named yourgatewayname_3dsecure and then similar to the _link function of a third party gateway module, you need to return the HTML for the form post to take the user to the 3D Secure process. An example of this is below.&lt;br /&gt;
&lt;br /&gt;
The _3dsecure function is passed all the same variables that the _capture function is (see page 6). Your return url should be a callback file to handle the response (see page 9)&lt;br /&gt;
&lt;br /&gt;
==Example==&lt;br /&gt;
&amp;lt;source lang = &amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
function yourgatewayname_3dsecure($params) {&lt;br /&gt;
$code = '&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;https://www.gateway.com/3dsecure/&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;gwlogin&amp;quot; value=&amp;quot;'.$params[&amp;quot;loginid&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;invoiceid&amp;quot; value=&amp;quot;'.$params[&amp;quot;invoiceid&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;amount&amp;quot; value=&amp;quot;'. $params[&amp;quot;amount&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;firstname&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;firstname&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;lastname&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;lastname&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;address&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;address1&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;city&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;city&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;state&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;state&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;postcode&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;postcode&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;country&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;country&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;phonenumber&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;phonenumber&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;email&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;email&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;ccnumber&amp;quot; value=&amp;quot;'. $params[&amp;quot;cardnum&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;expirymonth&amp;quot; value=&amp;quot;'.substr($params['cardexp'],0,2).'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;expiryyear&amp;quot; value=&amp;quot;'.substr($params['cardexp'],2,2).'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;cvv2&amp;quot; value=&amp;quot;'. $params[&amp;quot;cccvv&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;return_url&amp;quot; value=&amp;quot;'.&lt;br /&gt;
$params['systemurl'].'/modules/gateways/callback/yourgatewayname.php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;noscript&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;errorbox&amp;quot;&amp;gt;&amp;lt;b&amp;gt;JavaScript is currently disabled or is not supported by your&lt;br /&gt;
browser.&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Please click the continue button to proceed with the processing of your&lt;br /&gt;
transaction.&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Continue &amp;gt;&amp;gt;&amp;quot; /&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/noscript&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;';&lt;br /&gt;
      return $code;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Tokenised Remote Storage==&lt;br /&gt;
&lt;br /&gt;
These days, with the increasing rules &amp;amp; requirements surrounding the storing of credit card details, many merchant gateways are offering services where you can perform repeat rebills without needing to store credit card details locally on your own system. And with WHMCS, gateway modules can utilise this functionality when available.&lt;br /&gt;
&lt;br /&gt;
The basic logic behind token gateways in WHMCS is that clients must either have a credit card number or a token stored in order for recurring billing to be attempted. So if you create a function named _storeremote in your custom gateway module, this function will then override the default local storage when new credit card details are entered. And instead of&lt;br /&gt;
saving in the database, that function then needs to communicate with the gateways API, and return the token that gets assigned to WHMCS.&lt;br /&gt;
&lt;br /&gt;
The variables passed into the _storeremote function are as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang =&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['gatewayid'] # the token stored for the client&lt;br /&gt;
$params['cardtype'] #the Card Type (Visa, MasterCard, etc…)&lt;br /&gt;
$params['cardnum'] # the Card Number&lt;br /&gt;
$params['cardexp'] # the Card’s Expiry Date (Format: MMYY)&lt;br /&gt;
$params['cardstart'] # the Card’s Start Date (Format: MMYY)&lt;br /&gt;
$params['cardissuenum'] # the Card’s Issue Number (Switch/Solo Cards)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
On the first call, the gatewayid will be empty. So when empty you need to create a new profile at the gateway. On subsequent calls the gatewayid that was originally created and stored will be passed in and the existing profile simply needs to be updated. And if the cardnum variable is empty, this indicates that deleting/removal of the stored credit card&lt;br /&gt;
details has been requested.&lt;br /&gt;
&lt;br /&gt;
Once the card details have been updated or stored remotely, you need to return either a success or failure response to tell WHMCS if it worked, and if it did, the token that has been assigned:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang =&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
return array(&amp;quot;status&amp;quot;=&amp;gt;&amp;quot;success&amp;quot;,&amp;quot;gatewayid&amp;quot;=&amp;gt;$results[&amp;quot;token&amp;quot;],&amp;quot;rawdata&amp;quot;=&amp;gt;$results);&lt;br /&gt;
&lt;br /&gt;
return array(&amp;quot;status&amp;quot;=&amp;gt;&amp;quot;failed&amp;quot;,&amp;quot;rawdata&amp;quot;=&amp;gt;$results);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When this function exists in a gateway module, WHMCS will only store the card type, expiry date and the last 4 digits (only) locally in the WHMCS database. So you and your clients will still be able to see exactly what card is stored remotely from within WHMCS.&lt;br /&gt;
&lt;br /&gt;
Then within the capture function, instead of $params[‘cardnum’] you will be passed $params[‘gatewayid’] with which to perform the capture.&lt;br /&gt;
&lt;br /&gt;
==Installation &amp;amp; Activation==&lt;br /&gt;
&lt;br /&gt;
To install the module you’ve created, simply upload it to the /modules/gateways/ folder and then go to Setup &amp;gt; Payment Gateways to activate. If you have create a callback file as well then that should also be uploaded but to the /modules/gateways/callback/ folder.&lt;br /&gt;
&lt;br /&gt;
'''Important:''' It is important that you do not activate your gateway module until you have&lt;br /&gt;
completed step 1 of either the third party gateway or merchant gateway module&lt;br /&gt;
documentation steps to remove the appropriate functions as it’s at the time of activation&lt;br /&gt;
that the type of module you are setting up gets stored in the system.&lt;br /&gt;
&lt;br /&gt;
==Blank Screen/Errors==&lt;br /&gt;
&lt;br /&gt;
If you get a blank page or errors in the Setup &amp;gt; Payment Gateways page after uploading your new module file then this indicates there is a syntax error in your code. To debug that, you can add the following line to your WHMCS configuration.php file to turn on error reporting:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$display_errors = true;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That will enable PHP error reporting and should show you the cause of any issues. Once you are done testing you must remember to remove that line again.&lt;br /&gt;
&lt;br /&gt;
==App Store==&lt;br /&gt;
WHMCS offers an app store to which your completed module can be submitted. The listings are displayed under the Addons tab within the administration area and online at http://www.whmcs.com/appstore . This is a great way to make WHMCS users aware of your module.&lt;br /&gt;
&lt;br /&gt;
In order to submit a listing you'll need a login for whmcs.com/members, if you do not have one please [https://www.whmcs.com/members/submitticket.php?step=2&amp;amp;deptid=5 Contact Us]. Once logged in, visit the app store page at the above URL and click the &amp;quot;Submit your Addon&amp;quot; link. We aim to review submissions in 1-2 weeks.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Developer_Links}}&lt;/div&gt;</summary>
		<author><name>Nicolas</name></author>	</entry>

	<entry>
		<id>http://3.19.219.109/index.php?title=Gateway_Module_Developer_Docs&amp;diff=17514</id>
		<title>Gateway Module Developer Docs</title>
		<link rel="alternate" type="text/html" href="http://3.19.219.109/index.php?title=Gateway_Module_Developer_Docs&amp;diff=17514"/>
				<updated>2016-01-06T19:22:42Z</updated>
		
		<summary type="html">&lt;p&gt;Nicolas: /* Getting Started */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Creating a gateway module allows you to connect WHMCS to third party payment and credit card processors that aren’t natively supported in WHMCS as standard.&lt;br /&gt;
&lt;br /&gt;
There are 2 core types of gateway module:&lt;br /&gt;
&lt;br /&gt;
#'''Third Party Gateways''' – this is where the customer leaves your site to pay and is returned once the payment process is completed&lt;br /&gt;
#'''Merchant Gateways''' – this is where the customer enters credit card details directly on your website and the payment is then processed in the background (can also include 3D Secure where the user leaves your site)&lt;br /&gt;
&lt;br /&gt;
{{Developer_Links}}&lt;br /&gt;
&lt;br /&gt;
So the first decision you need to make before starting your module for WHMCS is which type of gateway module you will be creating.  Once you have that, you're ready to begin.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Introduction==&lt;br /&gt;
&lt;br /&gt;
Gateway modules allow a connection between WHMCS and gateways or credit card processors that aren't natively supported in WHMCS.&lt;br /&gt;
&lt;br /&gt;
This documentation will explain the module's structure and contains everything needed in order to successfully create a gateway module for WHMCS.&lt;br /&gt;
&lt;br /&gt;
==Getting Started==&lt;br /&gt;
&lt;br /&gt;
To get started, begin by downloading the module development kit from our GitHub site. There are two sample modules available, depending upon the [[#Module Type|type of gateway]] being developed:&lt;br /&gt;
*Third Party Gateway: https://github.com/WHMCS/sample-gateway-module&lt;br /&gt;
*Merchant Gateway: https://github.com/WHMCS/sample-merchant-gateway&lt;br /&gt;
Take the gateway module template &amp;quot;template.php&amp;quot; from this download and rename it to &amp;quot;yourgatewayname.php&amp;quot;.  It should be all lowercase and must start with a letter.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;docs-alert-warning&amp;quot;&amp;gt;&lt;br /&gt;
All functions within a gateway module must be prefixed with the filename.  Open the file and replace all occurrences of &amp;quot;template_&amp;quot; with &amp;quot;yougatewayname_&amp;quot;.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Config Array===&lt;br /&gt;
&lt;br /&gt;
'''Configure the yourgatewayname_config array'''. This function is the primary function required by all gateway modules and defines both the friendly display name for the module and any custom fields/options/settings that the gateway module requires.&lt;br /&gt;
&lt;br /&gt;
The available field types are &amp;quot;text&amp;quot;, &amp;quot;dropdown&amp;quot;, &amp;quot;textarea&amp;quot; and &amp;quot;yesno&amp;quot; (checkboxes).   The sample config array in &amp;quot;template.php&amp;quot; demonstrates how to use each of these types. &lt;br /&gt;
&lt;br /&gt;
The general formula is to:&lt;br /&gt;
#Specify a system name (''all in lowercase for the setting to be referenced by in the module code itself'')&lt;br /&gt;
#A FriendlyName&lt;br /&gt;
#Type&lt;br /&gt;
#Any settings specific to that field type.&lt;br /&gt;
&lt;br /&gt;
Any fields defined here will be available in all gateway module functions in the $params array, so avoid common names like currency, invoiceid, etc, as these will conflict with the standard variables.&lt;br /&gt;
&lt;br /&gt;
===Module Type===&lt;br /&gt;
&lt;br /&gt;
Determine which type of module needs to be created from the 2 core types:&lt;br /&gt;
&lt;br /&gt;
#'''Third Party Gateways''' – the customer leaves your site to pay and is returned once the payment process is completed.&lt;br /&gt;
#'''Merchant Gateways''' – where the customer enters credit card details directly on your website and the payment is then processed in the background (can also include 3D Secure where the user leaves your site).&lt;br /&gt;
&lt;br /&gt;
For a Third Party gateway go to [[#Third_Party_Gateway]], and for a merchant gateway go to [[#Merchant_Gateway]].&lt;br /&gt;
&lt;br /&gt;
==Third Party Gateway==&lt;br /&gt;
&lt;br /&gt;
To create a third party gateway module, which is one where the customer leaves your site to make payment on the gateway providers website, simply follow the steps below.&lt;br /&gt;
&lt;br /&gt;
# Begin by deleting the _capture function from the module template (important: you must do this before activating your new module in WHMCS)&lt;br /&gt;
# Next, enter your gateway specific code for taking the user to the payment process in the _link function - an example for how to do this is shown in the gateway module template supplied with this dev kit. This should normally take the format of a form post and you simply need to return the HTML code for the form from this function.&lt;br /&gt;
&lt;br /&gt;
The variables available to you are:&lt;br /&gt;
&lt;br /&gt;
===Invoice Variables===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['invoiceid'] # Invoice ID Number&lt;br /&gt;
$params['description'] # Description (eg. Company Name - Invoice #xxx)&lt;br /&gt;
$params['amount'] # Format: xxx.xx&lt;br /&gt;
$params['currency'] # Currency Code (eg. GBD, USD, etc...)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Client Variables===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['clientdetails']['firstname'] # Clients First Name&lt;br /&gt;
$params['clientdetails']['lastname'] # Clients Last Name&lt;br /&gt;
$params['clientdetails']['email'] # Clients Email Address&lt;br /&gt;
$params['clientdetails']['address1'] # Clients Address&lt;br /&gt;
$params['clientdetails']['address2'] &lt;br /&gt;
$params['clientdetails']['city']&lt;br /&gt;
$params['clientdetails']['state']&lt;br /&gt;
$params['clientdetails']['postcode']&lt;br /&gt;
$params['clientdetails']['country']&lt;br /&gt;
$params['clientdetails']['phonenumber']&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===#System Variables===&lt;br /&gt;
&amp;lt;source lang = &amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['companyname'] # your Company Name setting in WHMCS&lt;br /&gt;
$params['systemurl'] # the url to the Client Area&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# The processing of a payment is handled by a callback file separate from the module (see page 9 for more info on that).&lt;br /&gt;
# If your gateway provider dosen't support automated refunds or you won't be including them in the module then you should delete the _refund function as well, otherwise refer to the Refund section on page 7.&lt;br /&gt;
&lt;br /&gt;
==Merchant Gateway==&lt;br /&gt;
&lt;br /&gt;
To create a merchant gateway module, where the customer enters their card details directly via the client area without leaving the site, simply follow the steps below.&lt;br /&gt;
&lt;br /&gt;
# Begin by deleting the _link function from the module template (important: you must do this before activating your new gateway module in WHMCS)&lt;br /&gt;
# Next, enter your gateway specific code for processing the payment into the _capture function. This normally takes the format of an HTTP/Curl request to the gateway providers API.&lt;br /&gt;
&lt;br /&gt;
The variables available to you are:&lt;br /&gt;
&lt;br /&gt;
===Invoice Variables===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['invoiceid'] # Invoice ID Number&lt;br /&gt;
$params['description'] # Description (eg. Company Name - Invoice #xxx)&lt;br /&gt;
$params['amount'] # Format: xxx.xx&lt;br /&gt;
$params['currency'] # Currency Code (eg. GBP, USD, etc...)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Client Variables===&lt;br /&gt;
&amp;lt;source lang = &amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['clientdetails']['firstname'] # Clients First Name&lt;br /&gt;
$params['clientdetails']['lastname'] # Clients Last Name&lt;br /&gt;
$params['clientdetails']['email'] # Clients Email Address&lt;br /&gt;
$params['clientdetails']['address1'] # Clients Address&lt;br /&gt;
$params['clientdetails']['address2']&lt;br /&gt;
$params['clientdetails']['city']&lt;br /&gt;
$params['clientdetails']['state']&lt;br /&gt;
$params['clientdetails']['postcode']&lt;br /&gt;
$params['clientdetails']['country']&lt;br /&gt;
$params['clientdetails']['phonenumber']&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===# System Variables===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['companyname'] # your Company Name setting in WHMCS&lt;br /&gt;
$params['systemurl'] – the url to the Client Area&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Card Details===&lt;br /&gt;
&amp;lt;source lang = &amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['cardtype'] # the Card Type (Visa, MasterCard, etc…)&lt;br /&gt;
$params['cardnum'] # the Card Number&lt;br /&gt;
$params['cardexp'] # the Card’s Expiry Date (Format: MMYY)&lt;br /&gt;
$params['cardstart'] # the Card’s Start Date (Format: MMYY)&lt;br /&gt;
$params['cardissuenum'] # the Card’s Issue Number (Switch/Solo Cards)&lt;br /&gt;
$params['cccvv'] #Not always present (recurring transactions)&lt;br /&gt;
#but would always be present for client initiated attempts&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# Once you have processed the transaction and got a response, you need to return an array to WHMCS with the results. The return for a successful capture should be as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
return array(&amp;quot;status&amp;quot;=&amp;gt;&amp;quot;success&amp;quot;,&amp;quot;transid&amp;quot;=&amp;gt;$results[&amp;quot;transid&amp;quot;],&amp;quot;rawdata&amp;quot;=&amp;gt;$results);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Within this array, the status must be success to tell WHMCS the capture was successful, transid should be passed the value of the transaction ID that came back from the gateway, and the rawdata variable should be passed an array of the data returned from the gateway to be stored in the WHMCS Gateway Log.&lt;br /&gt;
&lt;br /&gt;
If the transaction were to fail then the response should instead be as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
return array(&amp;quot;status&amp;quot;=&amp;gt;&amp;quot;declined&amp;quot;,&amp;quot;rawdata&amp;quot;=&amp;gt;$results);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this response, the status can be any value you want, declined, error, invalid hash, etc… and will be what staff get to see as the failure reason within the gateway log. The rawdata variable should again be passed an array of the data returned from the gateway to be stored in the WHMCS Gateway Log for debugging purposes.&lt;br /&gt;
&lt;br /&gt;
# If your gateway supports 3D Secure (Verified by Visa or MasterCard Secure Code) then please refer to page 8 for information on how to do handle that.&lt;br /&gt;
&lt;br /&gt;
===Refunds===&lt;br /&gt;
&lt;br /&gt;
# If your gateway provider supports automated refunds then you should add your code for processing a refund into the _refund function which is passed all the same variables as capture but with one additional variable:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['transid'] # the transaction ID of the original transaction to be refunded&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The return arrays for a success or failure should be done exactly the same as described above for the capture function.&lt;br /&gt;
&lt;br /&gt;
If your gateway provider does not support refunds, then the _refund function should be deleted from the module file.&lt;br /&gt;
&lt;br /&gt;
==Callbacks==&lt;br /&gt;
If your gateway provider supports notifying a script when a payment is successful, then you can create a callback file in WHMCS to detect and apply those calls as payments inside WHMCS.&lt;br /&gt;
&lt;br /&gt;
A sample callback file is included in the dev kit for this purpose named “callback.php”. To utilise this script, you simply need to rename it to match your gateway module, and modify the variables within it as per the comments in the code, and to match the variables your specific gateway returns.&lt;br /&gt;
&lt;br /&gt;
These are some helper functions within the sample that you might find useful:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$GATEWAY = getGatewayVariables(‘yourgatewayname’);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function can be used to retrieve the configuration data for your module as specified in&lt;br /&gt;
the _config array. For example you might need it to get a gateway username or secret key to&lt;br /&gt;
validate a callback.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$invoiceid = checkCbInvoiceID($invoiceid,$GATEWAY[‘name’]);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function can be used to check the invoice ID received back is valid. You should simply pass the $invoiceid into this function and your gateway name and if a valid invoice number the script will continue executing, otherwise the script will be halted and an appropriate gateway log entry created.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang =&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
checkCbTransID($transid);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function can be used to check for any existing transactions already recorded for a given transaction ID. This can be useful for protecting against duplicate callbacks as if the transaction ID is already found in the database, the callback script execution will be halted.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
logTransaction($GATEWAY[‘name’],$_POST,&amp;quot;Successful&amp;quot;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function can be used to create a gateway log entry. The first variable needs to be the name of the gateway module, the second should be an array of data, such as the $_POST or $_REQUEST super globals, and the last variable should be the result/status to show in the log.&lt;br /&gt;
&lt;br /&gt;
== 3D Secure Process ==&lt;br /&gt;
&lt;br /&gt;
If your merchant gateway supports 3D Secure (also known as Verified by Visa or MasterCard Secure Code) and you want to implement that then you can as WHMCS fully supports 3D Secured payments.&lt;br /&gt;
&lt;br /&gt;
To do this you need to add a function to your module named yourgatewayname_3dsecure and then similar to the _link function of a third party gateway module, you need to return the HTML for the form post to take the user to the 3D Secure process. An example of this is below.&lt;br /&gt;
&lt;br /&gt;
The _3dsecure function is passed all the same variables that the _capture function is (see page 6). Your return url should be a callback file to handle the response (see page 9)&lt;br /&gt;
&lt;br /&gt;
==Example==&lt;br /&gt;
&amp;lt;source lang = &amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
function yourgatewayname_3dsecure($params) {&lt;br /&gt;
$code = '&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;https://www.gateway.com/3dsecure/&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;gwlogin&amp;quot; value=&amp;quot;'.$params[&amp;quot;loginid&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;invoiceid&amp;quot; value=&amp;quot;'.$params[&amp;quot;invoiceid&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;amount&amp;quot; value=&amp;quot;'. $params[&amp;quot;amount&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;firstname&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;firstname&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;lastname&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;lastname&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;address&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;address1&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;city&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;city&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;state&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;state&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;postcode&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;postcode&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;country&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;country&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;phonenumber&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;phonenumber&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;email&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;email&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;ccnumber&amp;quot; value=&amp;quot;'. $params[&amp;quot;cardnum&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;expirymonth&amp;quot; value=&amp;quot;'.substr($params['cardexp'],0,2).'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;expiryyear&amp;quot; value=&amp;quot;'.substr($params['cardexp'],2,2).'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;cvv2&amp;quot; value=&amp;quot;'. $params[&amp;quot;cccvv&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;return_url&amp;quot; value=&amp;quot;'.&lt;br /&gt;
$params['systemurl'].'/modules/gateways/callback/yourgatewayname.php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;noscript&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;errorbox&amp;quot;&amp;gt;&amp;lt;b&amp;gt;JavaScript is currently disabled or is not supported by your&lt;br /&gt;
browser.&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Please click the continue button to proceed with the processing of your&lt;br /&gt;
transaction.&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Continue &amp;gt;&amp;gt;&amp;quot; /&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/noscript&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;';&lt;br /&gt;
      return $code;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Tokenised Remote Storage==&lt;br /&gt;
&lt;br /&gt;
These days, with the increasing rules &amp;amp; requirements surrounding the storing of credit card details, many merchant gateways are offering services where you can perform repeat rebills without needing to store credit card details locally on your own system. And with WHMCS, gateway modules can utilise this functionality when available.&lt;br /&gt;
&lt;br /&gt;
The basic logic behind token gateways in WHMCS is that clients must either have a credit card number or a token stored in order for recurring billing to be attempted. So if you create a function named _storeremote in your custom gateway module, this function will then override the default local storage when new credit card details are entered. And instead of&lt;br /&gt;
saving in the database, that function then needs to communicate with the gateways API, and return the token that gets assigned to WHMCS.&lt;br /&gt;
&lt;br /&gt;
The variables passed into the _storeremote function are as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang =&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['gatewayid'] # the token stored for the client&lt;br /&gt;
$params['cardtype'] #the Card Type (Visa, MasterCard, etc…)&lt;br /&gt;
$params['cardnum'] # the Card Number&lt;br /&gt;
$params['cardexp'] # the Card’s Expiry Date (Format: MMYY)&lt;br /&gt;
$params['cardstart'] # the Card’s Start Date (Format: MMYY)&lt;br /&gt;
$params['cardissuenum'] # the Card’s Issue Number (Switch/Solo Cards)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
On the first call, the gatewayid will be empty. So when empty you need to create a new profile at the gateway. On subsequent calls the gatewayid that was originally created and stored will be passed in and the existing profile simply needs to be updated. And if the cardnum variable is empty, this indicates that deleting/removal of the stored credit card&lt;br /&gt;
details has been requested.&lt;br /&gt;
&lt;br /&gt;
Once the card details have been updated or stored remotely, you need to return either a success or failure response to tell WHMCS if it worked, and if it did, the token that has been assigned:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang =&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
return array(&amp;quot;status&amp;quot;=&amp;gt;&amp;quot;success&amp;quot;,&amp;quot;gatewayid&amp;quot;=&amp;gt;$results[&amp;quot;token&amp;quot;],&amp;quot;rawdata&amp;quot;=&amp;gt;$results);&lt;br /&gt;
&lt;br /&gt;
return array(&amp;quot;status&amp;quot;=&amp;gt;&amp;quot;failed&amp;quot;,&amp;quot;rawdata&amp;quot;=&amp;gt;$results);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When this function exists in a gateway module, WHMCS will only store the card type, expiry date and the last 4 digits (only) locally in the WHMCS database. So you and your clients will still be able to see exactly what card is stored remotely from within WHMCS.&lt;br /&gt;
&lt;br /&gt;
Then within the capture function, instead of $params[‘cardnum’] you will be passed $params[‘gatewayid’] with which to perform the capture.&lt;br /&gt;
&lt;br /&gt;
==Installation &amp;amp; Activation==&lt;br /&gt;
&lt;br /&gt;
To install the module you’ve created, simply upload it to the /modules/gateways/ folder and then go to Setup &amp;gt; Payment Gateways to activate. If you have create a callback file as well then that should also be uploaded but to the /modules/gateways/callback/ folder.&lt;br /&gt;
&lt;br /&gt;
'''Important:''' It is important that you do not activate your gateway module until you have&lt;br /&gt;
completed step 1 of either the third party gateway or merchant gateway module&lt;br /&gt;
documentation steps to remove the appropriate functions as it’s at the time of activation&lt;br /&gt;
that the type of module you are setting up gets stored in the system.&lt;br /&gt;
&lt;br /&gt;
==Blank Screen/Errors==&lt;br /&gt;
&lt;br /&gt;
If you get a blank page or errors in the Setup &amp;gt; Payment Gateways page after uploading your new module file then this indicates there is a syntax error in your code. To debug that, you can add the following line to your WHMCS configuration.php file to turn on error reporting:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$display_errors = true;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That will enable PHP error reporting and should show you the cause of any issues. Once you are done testing you must remember to remove that line again.&lt;br /&gt;
&lt;br /&gt;
==App Store==&lt;br /&gt;
WHMCS offers an app store to which your completed module can be submitted. The listings are displayed under the Addons tab within the administration area and online at http://www.whmcs.com/appstore . This is a great way to make WHMCS users aware of your module.&lt;br /&gt;
&lt;br /&gt;
In order to submit a listing you'll need a login for whmcs.com/members, if you do not have one please [https://www.whmcs.com/members/submitticket.php?step=2&amp;amp;deptid=5 Contact Us]. Once logged in, visit the app store page at the above URL and click the &amp;quot;Submit your Addon&amp;quot; link. We aim to review submissions in 1-2 weeks.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Developer_Links}}&lt;/div&gt;</summary>
		<author><name>Nicolas</name></author>	</entry>

	<entry>
		<id>http://3.19.219.109/index.php?title=Gateway_Module_Developer_Docs&amp;diff=17510</id>
		<title>Gateway Module Developer Docs</title>
		<link rel="alternate" type="text/html" href="http://3.19.219.109/index.php?title=Gateway_Module_Developer_Docs&amp;diff=17510"/>
				<updated>2016-01-06T19:10:44Z</updated>
		
		<summary type="html">&lt;p&gt;Nicolas: /* Getting Started */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Creating a gateway module allows you to connect WHMCS to third party payment and credit card processors that aren’t natively supported in WHMCS as standard.&lt;br /&gt;
&lt;br /&gt;
There are 2 core types of gateway module:&lt;br /&gt;
&lt;br /&gt;
#'''Third Party Gateways''' – this is where the customer leaves your site to pay and is returned once the payment process is completed&lt;br /&gt;
#'''Merchant Gateways''' – this is where the customer enters credit card details directly on your website and the payment is then processed in the background (can also include 3D Secure where the user leaves your site)&lt;br /&gt;
&lt;br /&gt;
{{Developer_Links}}&lt;br /&gt;
&lt;br /&gt;
So the first decision you need to make before starting your module for WHMCS is which type of gateway module you will be creating.  Once you have that, you're ready to begin.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Introduction==&lt;br /&gt;
&lt;br /&gt;
Gateway modules allow a connection between WHMCS and gateways or credit card processors that aren't natively supported in WHMCS.&lt;br /&gt;
&lt;br /&gt;
This documentation will explain the module's structure and contains everything needed in order to successfully create a gateway module for WHMCS.&lt;br /&gt;
&lt;br /&gt;
==Getting Started==&lt;br /&gt;
&lt;br /&gt;
To get started, begin by downloading the module development kit from our GitHub site. There are two sample modules available, depending upon the [[#Module Type|type of gateway]] being developed:&lt;br /&gt;
*Third Party Gateway: https://github.com/WHMCS/sample-gateway-module&lt;br /&gt;
*Merchant Gateway: https://github.com/WHMCS/sample-merchant-gateway&lt;br /&gt;
Take the gateway module template &amp;quot;template.php&amp;quot; from this download and rename it to &amp;quot;yourgatewayname.php&amp;quot;.  It should be all lowercase and must start with a letter.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;docs-alert-warning&amp;quot;&amp;gt;&lt;br /&gt;
All functions within a gateway module must be prefixed with the filename.  Open the file and replace all occurrences of &amp;quot;template_&amp;quot; with &amp;quot;yougatewayname_&amp;quot;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Config Array===&lt;br /&gt;
&lt;br /&gt;
Next you can configure the yourgatewayname_config array. This function is the primary function required by all gateway modules and defines both the friendly display name for the module and any custom fields/options/settings your gateway module requires.&lt;br /&gt;
&lt;br /&gt;
The available field types are &amp;quot;text&amp;quot;, &amp;quot;dropdown&amp;quot;, &amp;quot;textarea&amp;quot; and &amp;quot;yesno&amp;quot; (checkboxes) the same as with all modules in WHMCS and the sample config array in &amp;quot;template.php&amp;quot; demonstrates how to use each of these types. The general format is that you specify a system name, all in lowercase for the setting to be referenced by in the module code itself, and then a FriendlyName, Type, and any settings specific to that field type.&lt;br /&gt;
&lt;br /&gt;
Any fields you define here will be available in all gateway module's functions in the $params array so you should avoid common names like currency, invoiceid, etc... that will conflict with the standard variables.&lt;br /&gt;
&lt;br /&gt;
===Module Type===&lt;br /&gt;
&lt;br /&gt;
Now you need to determine what type of module you are creating. There are 2 core types of gateway module:&lt;br /&gt;
&lt;br /&gt;
#'''Third Party Gateways''' – this is where the customer leaves your site to pay and is returned once the payment process is completed&lt;br /&gt;
#'''Merchant Gateways''' – this is where the customer enters credit card details directly on your website and the payment is then processed in the background (can also include 3D Secure where the user leaves your site)&lt;br /&gt;
&lt;br /&gt;
Once you know the of module you are creating then you can proceed. For a Third Party gateway go to [[#Third_Party_Gateway]], and for a merchant gateway go to [[#Merchant_Gateway]].&lt;br /&gt;
&lt;br /&gt;
==Third Party Gateway==&lt;br /&gt;
&lt;br /&gt;
To create a third party gateway module, which is one where the customer leaves your site to make payment on the gateway providers website, simply follow the steps below.&lt;br /&gt;
&lt;br /&gt;
# Begin by deleting the _capture function from the module template (important: you must do this before activating your new module in WHMCS)&lt;br /&gt;
# Next, enter your gateway specific code for taking the user to the payment process in the _link function - an example for how to do this is shown in the gateway module template supplied with this dev kit. This should normally take the format of a form post and you simply need to return the HTML code for the form from this function.&lt;br /&gt;
&lt;br /&gt;
The variables available to you are:&lt;br /&gt;
&lt;br /&gt;
===Invoice Variables===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['invoiceid'] # Invoice ID Number&lt;br /&gt;
$params['description'] # Description (eg. Company Name - Invoice #xxx)&lt;br /&gt;
$params['amount'] # Format: xxx.xx&lt;br /&gt;
$params['currency'] # Currency Code (eg. GBD, USD, etc...)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Client Variables===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['clientdetails']['firstname'] # Clients First Name&lt;br /&gt;
$params['clientdetails']['lastname'] # Clients Last Name&lt;br /&gt;
$params['clientdetails']['email'] # Clients Email Address&lt;br /&gt;
$params['clientdetails']['address1'] # Clients Address&lt;br /&gt;
$params['clientdetails']['address2'] &lt;br /&gt;
$params['clientdetails']['city']&lt;br /&gt;
$params['clientdetails']['state']&lt;br /&gt;
$params['clientdetails']['postcode']&lt;br /&gt;
$params['clientdetails']['country']&lt;br /&gt;
$params['clientdetails']['phonenumber']&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===#System Variables===&lt;br /&gt;
&amp;lt;source lang = &amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['companyname'] # your Company Name setting in WHMCS&lt;br /&gt;
$params['systemurl'] # the url to the Client Area&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# The processing of a payment is handled by a callback file separate from the module (see page 9 for more info on that).&lt;br /&gt;
# If your gateway provider dosen't support automated refunds or you won't be including them in the module then you should delete the _refund function as well, otherwise refer to the Refund section on page 7.&lt;br /&gt;
&lt;br /&gt;
==Merchant Gateway==&lt;br /&gt;
&lt;br /&gt;
To create a merchant gateway module, where the customer enters their card details directly via the client area without leaving the site, simply follow the steps below.&lt;br /&gt;
&lt;br /&gt;
# Begin by deleting the _link function from the module template (important: you must do this before activating your new gateway module in WHMCS)&lt;br /&gt;
# Next, enter your gateway specific code for processing the payment into the _capture function. This normally takes the format of an HTTP/Curl request to the gateway providers API.&lt;br /&gt;
&lt;br /&gt;
The variables available to you are:&lt;br /&gt;
&lt;br /&gt;
===Invoice Variables===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['invoiceid'] # Invoice ID Number&lt;br /&gt;
$params['description'] # Description (eg. Company Name - Invoice #xxx)&lt;br /&gt;
$params['amount'] # Format: xxx.xx&lt;br /&gt;
$params['currency'] # Currency Code (eg. GBP, USD, etc...)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Client Variables===&lt;br /&gt;
&amp;lt;source lang = &amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['clientdetails']['firstname'] # Clients First Name&lt;br /&gt;
$params['clientdetails']['lastname'] # Clients Last Name&lt;br /&gt;
$params['clientdetails']['email'] # Clients Email Address&lt;br /&gt;
$params['clientdetails']['address1'] # Clients Address&lt;br /&gt;
$params['clientdetails']['address2']&lt;br /&gt;
$params['clientdetails']['city']&lt;br /&gt;
$params['clientdetails']['state']&lt;br /&gt;
$params['clientdetails']['postcode']&lt;br /&gt;
$params['clientdetails']['country']&lt;br /&gt;
$params['clientdetails']['phonenumber']&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===# System Variables===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['companyname'] # your Company Name setting in WHMCS&lt;br /&gt;
$params['systemurl'] – the url to the Client Area&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Card Details===&lt;br /&gt;
&amp;lt;source lang = &amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['cardtype'] # the Card Type (Visa, MasterCard, etc…)&lt;br /&gt;
$params['cardnum'] # the Card Number&lt;br /&gt;
$params['cardexp'] # the Card’s Expiry Date (Format: MMYY)&lt;br /&gt;
$params['cardstart'] # the Card’s Start Date (Format: MMYY)&lt;br /&gt;
$params['cardissuenum'] # the Card’s Issue Number (Switch/Solo Cards)&lt;br /&gt;
$params['cccvv'] #Not always present (recurring transactions)&lt;br /&gt;
#but would always be present for client initiated attempts&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# Once you have processed the transaction and got a response, you need to return an array to WHMCS with the results. The return for a successful capture should be as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
return array(&amp;quot;status&amp;quot;=&amp;gt;&amp;quot;success&amp;quot;,&amp;quot;transid&amp;quot;=&amp;gt;$results[&amp;quot;transid&amp;quot;],&amp;quot;rawdata&amp;quot;=&amp;gt;$results);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Within this array, the status must be success to tell WHMCS the capture was successful, transid should be passed the value of the transaction ID that came back from the gateway, and the rawdata variable should be passed an array of the data returned from the gateway to be stored in the WHMCS Gateway Log.&lt;br /&gt;
&lt;br /&gt;
If the transaction were to fail then the response should instead be as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
return array(&amp;quot;status&amp;quot;=&amp;gt;&amp;quot;declined&amp;quot;,&amp;quot;rawdata&amp;quot;=&amp;gt;$results);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this response, the status can be any value you want, declined, error, invalid hash, etc… and will be what staff get to see as the failure reason within the gateway log. The rawdata variable should again be passed an array of the data returned from the gateway to be stored in the WHMCS Gateway Log for debugging purposes.&lt;br /&gt;
&lt;br /&gt;
# If your gateway supports 3D Secure (Verified by Visa or MasterCard Secure Code) then please refer to page 8 for information on how to do handle that.&lt;br /&gt;
&lt;br /&gt;
===Refunds===&lt;br /&gt;
&lt;br /&gt;
# If your gateway provider supports automated refunds then you should add your code for processing a refund into the _refund function which is passed all the same variables as capture but with one additional variable:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['transid'] # the transaction ID of the original transaction to be refunded&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The return arrays for a success or failure should be done exactly the same as described above for the capture function.&lt;br /&gt;
&lt;br /&gt;
If your gateway provider does not support refunds, then the _refund function should be deleted from the module file.&lt;br /&gt;
&lt;br /&gt;
==Callbacks==&lt;br /&gt;
If your gateway provider supports notifying a script when a payment is successful, then you can create a callback file in WHMCS to detect and apply those calls as payments inside WHMCS.&lt;br /&gt;
&lt;br /&gt;
A sample callback file is included in the dev kit for this purpose named “callback.php”. To utilise this script, you simply need to rename it to match your gateway module, and modify the variables within it as per the comments in the code, and to match the variables your specific gateway returns.&lt;br /&gt;
&lt;br /&gt;
These are some helper functions within the sample that you might find useful:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$GATEWAY = getGatewayVariables(‘yourgatewayname’);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function can be used to retrieve the configuration data for your module as specified in&lt;br /&gt;
the _config array. For example you might need it to get a gateway username or secret key to&lt;br /&gt;
validate a callback.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$invoiceid = checkCbInvoiceID($invoiceid,$GATEWAY[‘name’]);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function can be used to check the invoice ID received back is valid. You should simply pass the $invoiceid into this function and your gateway name and if a valid invoice number the script will continue executing, otherwise the script will be halted and an appropriate gateway log entry created.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang =&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
checkCbTransID($transid);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function can be used to check for any existing transactions already recorded for a given transaction ID. This can be useful for protecting against duplicate callbacks as if the transaction ID is already found in the database, the callback script execution will be halted.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
logTransaction($GATEWAY[‘name’],$_POST,&amp;quot;Successful&amp;quot;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function can be used to create a gateway log entry. The first variable needs to be the name of the gateway module, the second should be an array of data, such as the $_POST or $_REQUEST super globals, and the last variable should be the result/status to show in the log.&lt;br /&gt;
&lt;br /&gt;
== 3D Secure Process ==&lt;br /&gt;
&lt;br /&gt;
If your merchant gateway supports 3D Secure (also known as Verified by Visa or MasterCard Secure Code) and you want to implement that then you can as WHMCS fully supports 3D Secured payments.&lt;br /&gt;
&lt;br /&gt;
To do this you need to add a function to your module named yourgatewayname_3dsecure and then similar to the _link function of a third party gateway module, you need to return the HTML for the form post to take the user to the 3D Secure process. An example of this is below.&lt;br /&gt;
&lt;br /&gt;
The _3dsecure function is passed all the same variables that the _capture function is (see page 6). Your return url should be a callback file to handle the response (see page 9)&lt;br /&gt;
&lt;br /&gt;
==Example==&lt;br /&gt;
&amp;lt;source lang = &amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
function yourgatewayname_3dsecure($params) {&lt;br /&gt;
$code = '&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;https://www.gateway.com/3dsecure/&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;gwlogin&amp;quot; value=&amp;quot;'.$params[&amp;quot;loginid&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;invoiceid&amp;quot; value=&amp;quot;'.$params[&amp;quot;invoiceid&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;amount&amp;quot; value=&amp;quot;'. $params[&amp;quot;amount&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;firstname&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;firstname&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;lastname&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;lastname&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;address&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;address1&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;city&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;city&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;state&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;state&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;postcode&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;postcode&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;country&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;country&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;phonenumber&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;phonenumber&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;email&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;email&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;ccnumber&amp;quot; value=&amp;quot;'. $params[&amp;quot;cardnum&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;expirymonth&amp;quot; value=&amp;quot;'.substr($params['cardexp'],0,2).'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;expiryyear&amp;quot; value=&amp;quot;'.substr($params['cardexp'],2,2).'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;cvv2&amp;quot; value=&amp;quot;'. $params[&amp;quot;cccvv&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;return_url&amp;quot; value=&amp;quot;'.&lt;br /&gt;
$params['systemurl'].'/modules/gateways/callback/yourgatewayname.php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;noscript&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;errorbox&amp;quot;&amp;gt;&amp;lt;b&amp;gt;JavaScript is currently disabled or is not supported by your&lt;br /&gt;
browser.&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Please click the continue button to proceed with the processing of your&lt;br /&gt;
transaction.&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Continue &amp;gt;&amp;gt;&amp;quot; /&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/noscript&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;';&lt;br /&gt;
      return $code;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Tokenised Remote Storage==&lt;br /&gt;
&lt;br /&gt;
These days, with the increasing rules &amp;amp; requirements surrounding the storing of credit card details, many merchant gateways are offering services where you can perform repeat rebills without needing to store credit card details locally on your own system. And with WHMCS, gateway modules can utilise this functionality when available.&lt;br /&gt;
&lt;br /&gt;
The basic logic behind token gateways in WHMCS is that clients must either have a credit card number or a token stored in order for recurring billing to be attempted. So if you create a function named _storeremote in your custom gateway module, this function will then override the default local storage when new credit card details are entered. And instead of&lt;br /&gt;
saving in the database, that function then needs to communicate with the gateways API, and return the token that gets assigned to WHMCS.&lt;br /&gt;
&lt;br /&gt;
The variables passed into the _storeremote function are as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang =&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['gatewayid'] # the token stored for the client&lt;br /&gt;
$params['cardtype'] #the Card Type (Visa, MasterCard, etc…)&lt;br /&gt;
$params['cardnum'] # the Card Number&lt;br /&gt;
$params['cardexp'] # the Card’s Expiry Date (Format: MMYY)&lt;br /&gt;
$params['cardstart'] # the Card’s Start Date (Format: MMYY)&lt;br /&gt;
$params['cardissuenum'] # the Card’s Issue Number (Switch/Solo Cards)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
On the first call, the gatewayid will be empty. So when empty you need to create a new profile at the gateway. On subsequent calls the gatewayid that was originally created and stored will be passed in and the existing profile simply needs to be updated. And if the cardnum variable is empty, this indicates that deleting/removal of the stored credit card&lt;br /&gt;
details has been requested.&lt;br /&gt;
&lt;br /&gt;
Once the card details have been updated or stored remotely, you need to return either a success or failure response to tell WHMCS if it worked, and if it did, the token that has been assigned:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang =&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
return array(&amp;quot;status&amp;quot;=&amp;gt;&amp;quot;success&amp;quot;,&amp;quot;gatewayid&amp;quot;=&amp;gt;$results[&amp;quot;token&amp;quot;],&amp;quot;rawdata&amp;quot;=&amp;gt;$results);&lt;br /&gt;
&lt;br /&gt;
return array(&amp;quot;status&amp;quot;=&amp;gt;&amp;quot;failed&amp;quot;,&amp;quot;rawdata&amp;quot;=&amp;gt;$results);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When this function exists in a gateway module, WHMCS will only store the card type, expiry date and the last 4 digits (only) locally in the WHMCS database. So you and your clients will still be able to see exactly what card is stored remotely from within WHMCS.&lt;br /&gt;
&lt;br /&gt;
Then within the capture function, instead of $params[‘cardnum’] you will be passed $params[‘gatewayid’] with which to perform the capture.&lt;br /&gt;
&lt;br /&gt;
==Installation &amp;amp; Activation==&lt;br /&gt;
&lt;br /&gt;
To install the module you’ve created, simply upload it to the /modules/gateways/ folder and then go to Setup &amp;gt; Payment Gateways to activate. If you have create a callback file as well then that should also be uploaded but to the /modules/gateways/callback/ folder.&lt;br /&gt;
&lt;br /&gt;
'''Important:''' It is important that you do not activate your gateway module until you have&lt;br /&gt;
completed step 1 of either the third party gateway or merchant gateway module&lt;br /&gt;
documentation steps to remove the appropriate functions as it’s at the time of activation&lt;br /&gt;
that the type of module you are setting up gets stored in the system.&lt;br /&gt;
&lt;br /&gt;
==Blank Screen/Errors==&lt;br /&gt;
&lt;br /&gt;
If you get a blank page or errors in the Setup &amp;gt; Payment Gateways page after uploading your new module file then this indicates there is a syntax error in your code. To debug that, you can add the following line to your WHMCS configuration.php file to turn on error reporting:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$display_errors = true;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That will enable PHP error reporting and should show you the cause of any issues. Once you are done testing you must remember to remove that line again.&lt;br /&gt;
&lt;br /&gt;
==App Store==&lt;br /&gt;
WHMCS offers an app store to which your completed module can be submitted. The listings are displayed under the Addons tab within the administration area and online at http://www.whmcs.com/appstore . This is a great way to make WHMCS users aware of your module.&lt;br /&gt;
&lt;br /&gt;
In order to submit a listing you'll need a login for whmcs.com/members, if you do not have one please [https://www.whmcs.com/members/submitticket.php?step=2&amp;amp;deptid=5 Contact Us]. Once logged in, visit the app store page at the above URL and click the &amp;quot;Submit your Addon&amp;quot; link. We aim to review submissions in 1-2 weeks.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Developer_Links}}&lt;/div&gt;</summary>
		<author><name>Nicolas</name></author>	</entry>

	<entry>
		<id>http://3.19.219.109/index.php?title=Gateway_Module_Developer_Docs&amp;diff=17506</id>
		<title>Gateway Module Developer Docs</title>
		<link rel="alternate" type="text/html" href="http://3.19.219.109/index.php?title=Gateway_Module_Developer_Docs&amp;diff=17506"/>
				<updated>2016-01-06T19:08:04Z</updated>
		
		<summary type="html">&lt;p&gt;Nicolas: /* Getting Started */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Creating a gateway module allows you to connect WHMCS to third party payment and credit card processors that aren’t natively supported in WHMCS as standard.&lt;br /&gt;
&lt;br /&gt;
There are 2 core types of gateway module:&lt;br /&gt;
&lt;br /&gt;
#'''Third Party Gateways''' – this is where the customer leaves your site to pay and is returned once the payment process is completed&lt;br /&gt;
#'''Merchant Gateways''' – this is where the customer enters credit card details directly on your website and the payment is then processed in the background (can also include 3D Secure where the user leaves your site)&lt;br /&gt;
&lt;br /&gt;
{{Developer_Links}}&lt;br /&gt;
&lt;br /&gt;
So the first decision you need to make before starting your module for WHMCS is which type of gateway module you will be creating.  Once you have that, you're ready to begin.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Introduction==&lt;br /&gt;
&lt;br /&gt;
Gateway modules allow a connection between WHMCS and gateways or credit card processors that aren't natively supported in WHMCS.&lt;br /&gt;
&lt;br /&gt;
This documentation will explain the module's structure and contains everything needed in order to successfully create a gateway module for WHMCS.&lt;br /&gt;
&lt;br /&gt;
==Getting Started==&lt;br /&gt;
&lt;br /&gt;
To get started, begin by downloading the module development kit from our GitHub site. There are two sample modules depending upon the [[#Module Type|type of gateway]] you are developing:&lt;br /&gt;
*Third Party Gateway: https://github.com/WHMCS/sample-gateway-module&lt;br /&gt;
*Merchant Gateway: https://github.com/WHMCS/sample-merchant-gateway&lt;br /&gt;
Take the gateway module template &amp;quot;template.php&amp;quot; from this download and rename to &amp;quot;yourgatewayname.php&amp;quot;. it should be all lowercase and must start with a letter.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;docs-alert-info&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;span class=&amp;quot;title&amp;quot;&amp;gt;xyz&amp;lt;/span&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
All functions within a gateway module must be prefixed with the filename.  Open the file and replace all occurrences of &amp;quot;template_&amp;quot; with &amp;quot;yougatewayname_&amp;quot;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Config Array===&lt;br /&gt;
&lt;br /&gt;
Next you can configure the yourgatewayname_config array. This function is the primary function required by all gateway modules and defines both the friendly display name for the module and any custom fields/options/settings your gateway module requires.&lt;br /&gt;
&lt;br /&gt;
The available field types are &amp;quot;text&amp;quot;, &amp;quot;dropdown&amp;quot;, &amp;quot;textarea&amp;quot; and &amp;quot;yesno&amp;quot; (checkboxes) the same as with all modules in WHMCS and the sample config array in &amp;quot;template.php&amp;quot; demonstrates how to use each of these types. The general format is that you specify a system name, all in lowercase for the setting to be referenced by in the module code itself, and then a FriendlyName, Type, and any settings specific to that field type.&lt;br /&gt;
&lt;br /&gt;
Any fields you define here will be available in all gateway module's functions in the $params array so you should avoid common names like currency, invoiceid, etc... that will conflict with the standard variables.&lt;br /&gt;
&lt;br /&gt;
===Module Type===&lt;br /&gt;
&lt;br /&gt;
Now you need to determine what type of module you are creating. There are 2 core types of gateway module:&lt;br /&gt;
&lt;br /&gt;
#'''Third Party Gateways''' – this is where the customer leaves your site to pay and is returned once the payment process is completed&lt;br /&gt;
#'''Merchant Gateways''' – this is where the customer enters credit card details directly on your website and the payment is then processed in the background (can also include 3D Secure where the user leaves your site)&lt;br /&gt;
&lt;br /&gt;
Once you know the of module you are creating then you can proceed. For a Third Party gateway go to [[#Third_Party_Gateway]], and for a merchant gateway go to [[#Merchant_Gateway]].&lt;br /&gt;
&lt;br /&gt;
==Third Party Gateway==&lt;br /&gt;
&lt;br /&gt;
To create a third party gateway module, which is one where the customer leaves your site to make payment on the gateway providers website, simply follow the steps below.&lt;br /&gt;
&lt;br /&gt;
# Begin by deleting the _capture function from the module template (important: you must do this before activating your new module in WHMCS)&lt;br /&gt;
# Next, enter your gateway specific code for taking the user to the payment process in the _link function - an example for how to do this is shown in the gateway module template supplied with this dev kit. This should normally take the format of a form post and you simply need to return the HTML code for the form from this function.&lt;br /&gt;
&lt;br /&gt;
The variables available to you are:&lt;br /&gt;
&lt;br /&gt;
===Invoice Variables===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['invoiceid'] # Invoice ID Number&lt;br /&gt;
$params['description'] # Description (eg. Company Name - Invoice #xxx)&lt;br /&gt;
$params['amount'] # Format: xxx.xx&lt;br /&gt;
$params['currency'] # Currency Code (eg. GBD, USD, etc...)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Client Variables===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['clientdetails']['firstname'] # Clients First Name&lt;br /&gt;
$params['clientdetails']['lastname'] # Clients Last Name&lt;br /&gt;
$params['clientdetails']['email'] # Clients Email Address&lt;br /&gt;
$params['clientdetails']['address1'] # Clients Address&lt;br /&gt;
$params['clientdetails']['address2'] &lt;br /&gt;
$params['clientdetails']['city']&lt;br /&gt;
$params['clientdetails']['state']&lt;br /&gt;
$params['clientdetails']['postcode']&lt;br /&gt;
$params['clientdetails']['country']&lt;br /&gt;
$params['clientdetails']['phonenumber']&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===#System Variables===&lt;br /&gt;
&amp;lt;source lang = &amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['companyname'] # your Company Name setting in WHMCS&lt;br /&gt;
$params['systemurl'] # the url to the Client Area&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# The processing of a payment is handled by a callback file separate from the module (see page 9 for more info on that).&lt;br /&gt;
# If your gateway provider dosen't support automated refunds or you won't be including them in the module then you should delete the _refund function as well, otherwise refer to the Refund section on page 7.&lt;br /&gt;
&lt;br /&gt;
==Merchant Gateway==&lt;br /&gt;
&lt;br /&gt;
To create a merchant gateway module, where the customer enters their card details directly via the client area without leaving the site, simply follow the steps below.&lt;br /&gt;
&lt;br /&gt;
# Begin by deleting the _link function from the module template (important: you must do this before activating your new gateway module in WHMCS)&lt;br /&gt;
# Next, enter your gateway specific code for processing the payment into the _capture function. This normally takes the format of an HTTP/Curl request to the gateway providers API.&lt;br /&gt;
&lt;br /&gt;
The variables available to you are:&lt;br /&gt;
&lt;br /&gt;
===Invoice Variables===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['invoiceid'] # Invoice ID Number&lt;br /&gt;
$params['description'] # Description (eg. Company Name - Invoice #xxx)&lt;br /&gt;
$params['amount'] # Format: xxx.xx&lt;br /&gt;
$params['currency'] # Currency Code (eg. GBP, USD, etc...)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Client Variables===&lt;br /&gt;
&amp;lt;source lang = &amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['clientdetails']['firstname'] # Clients First Name&lt;br /&gt;
$params['clientdetails']['lastname'] # Clients Last Name&lt;br /&gt;
$params['clientdetails']['email'] # Clients Email Address&lt;br /&gt;
$params['clientdetails']['address1'] # Clients Address&lt;br /&gt;
$params['clientdetails']['address2']&lt;br /&gt;
$params['clientdetails']['city']&lt;br /&gt;
$params['clientdetails']['state']&lt;br /&gt;
$params['clientdetails']['postcode']&lt;br /&gt;
$params['clientdetails']['country']&lt;br /&gt;
$params['clientdetails']['phonenumber']&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===# System Variables===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['companyname'] # your Company Name setting in WHMCS&lt;br /&gt;
$params['systemurl'] – the url to the Client Area&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Card Details===&lt;br /&gt;
&amp;lt;source lang = &amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['cardtype'] # the Card Type (Visa, MasterCard, etc…)&lt;br /&gt;
$params['cardnum'] # the Card Number&lt;br /&gt;
$params['cardexp'] # the Card’s Expiry Date (Format: MMYY)&lt;br /&gt;
$params['cardstart'] # the Card’s Start Date (Format: MMYY)&lt;br /&gt;
$params['cardissuenum'] # the Card’s Issue Number (Switch/Solo Cards)&lt;br /&gt;
$params['cccvv'] #Not always present (recurring transactions)&lt;br /&gt;
#but would always be present for client initiated attempts&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# Once you have processed the transaction and got a response, you need to return an array to WHMCS with the results. The return for a successful capture should be as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
return array(&amp;quot;status&amp;quot;=&amp;gt;&amp;quot;success&amp;quot;,&amp;quot;transid&amp;quot;=&amp;gt;$results[&amp;quot;transid&amp;quot;],&amp;quot;rawdata&amp;quot;=&amp;gt;$results);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Within this array, the status must be success to tell WHMCS the capture was successful, transid should be passed the value of the transaction ID that came back from the gateway, and the rawdata variable should be passed an array of the data returned from the gateway to be stored in the WHMCS Gateway Log.&lt;br /&gt;
&lt;br /&gt;
If the transaction were to fail then the response should instead be as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
return array(&amp;quot;status&amp;quot;=&amp;gt;&amp;quot;declined&amp;quot;,&amp;quot;rawdata&amp;quot;=&amp;gt;$results);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this response, the status can be any value you want, declined, error, invalid hash, etc… and will be what staff get to see as the failure reason within the gateway log. The rawdata variable should again be passed an array of the data returned from the gateway to be stored in the WHMCS Gateway Log for debugging purposes.&lt;br /&gt;
&lt;br /&gt;
# If your gateway supports 3D Secure (Verified by Visa or MasterCard Secure Code) then please refer to page 8 for information on how to do handle that.&lt;br /&gt;
&lt;br /&gt;
===Refunds===&lt;br /&gt;
&lt;br /&gt;
# If your gateway provider supports automated refunds then you should add your code for processing a refund into the _refund function which is passed all the same variables as capture but with one additional variable:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['transid'] # the transaction ID of the original transaction to be refunded&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The return arrays for a success or failure should be done exactly the same as described above for the capture function.&lt;br /&gt;
&lt;br /&gt;
If your gateway provider does not support refunds, then the _refund function should be deleted from the module file.&lt;br /&gt;
&lt;br /&gt;
==Callbacks==&lt;br /&gt;
If your gateway provider supports notifying a script when a payment is successful, then you can create a callback file in WHMCS to detect and apply those calls as payments inside WHMCS.&lt;br /&gt;
&lt;br /&gt;
A sample callback file is included in the dev kit for this purpose named “callback.php”. To utilise this script, you simply need to rename it to match your gateway module, and modify the variables within it as per the comments in the code, and to match the variables your specific gateway returns.&lt;br /&gt;
&lt;br /&gt;
These are some helper functions within the sample that you might find useful:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$GATEWAY = getGatewayVariables(‘yourgatewayname’);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function can be used to retrieve the configuration data for your module as specified in&lt;br /&gt;
the _config array. For example you might need it to get a gateway username or secret key to&lt;br /&gt;
validate a callback.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$invoiceid = checkCbInvoiceID($invoiceid,$GATEWAY[‘name’]);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function can be used to check the invoice ID received back is valid. You should simply pass the $invoiceid into this function and your gateway name and if a valid invoice number the script will continue executing, otherwise the script will be halted and an appropriate gateway log entry created.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang =&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
checkCbTransID($transid);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function can be used to check for any existing transactions already recorded for a given transaction ID. This can be useful for protecting against duplicate callbacks as if the transaction ID is already found in the database, the callback script execution will be halted.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
logTransaction($GATEWAY[‘name’],$_POST,&amp;quot;Successful&amp;quot;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function can be used to create a gateway log entry. The first variable needs to be the name of the gateway module, the second should be an array of data, such as the $_POST or $_REQUEST super globals, and the last variable should be the result/status to show in the log.&lt;br /&gt;
&lt;br /&gt;
== 3D Secure Process ==&lt;br /&gt;
&lt;br /&gt;
If your merchant gateway supports 3D Secure (also known as Verified by Visa or MasterCard Secure Code) and you want to implement that then you can as WHMCS fully supports 3D Secured payments.&lt;br /&gt;
&lt;br /&gt;
To do this you need to add a function to your module named yourgatewayname_3dsecure and then similar to the _link function of a third party gateway module, you need to return the HTML for the form post to take the user to the 3D Secure process. An example of this is below.&lt;br /&gt;
&lt;br /&gt;
The _3dsecure function is passed all the same variables that the _capture function is (see page 6). Your return url should be a callback file to handle the response (see page 9)&lt;br /&gt;
&lt;br /&gt;
==Example==&lt;br /&gt;
&amp;lt;source lang = &amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
function yourgatewayname_3dsecure($params) {&lt;br /&gt;
$code = '&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;https://www.gateway.com/3dsecure/&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;gwlogin&amp;quot; value=&amp;quot;'.$params[&amp;quot;loginid&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;invoiceid&amp;quot; value=&amp;quot;'.$params[&amp;quot;invoiceid&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;amount&amp;quot; value=&amp;quot;'. $params[&amp;quot;amount&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;firstname&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;firstname&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;lastname&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;lastname&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;address&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;address1&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;city&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;city&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;state&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;state&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;postcode&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;postcode&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;country&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;country&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;phonenumber&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;phonenumber&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;email&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;email&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;ccnumber&amp;quot; value=&amp;quot;'. $params[&amp;quot;cardnum&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;expirymonth&amp;quot; value=&amp;quot;'.substr($params['cardexp'],0,2).'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;expiryyear&amp;quot; value=&amp;quot;'.substr($params['cardexp'],2,2).'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;cvv2&amp;quot; value=&amp;quot;'. $params[&amp;quot;cccvv&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;return_url&amp;quot; value=&amp;quot;'.&lt;br /&gt;
$params['systemurl'].'/modules/gateways/callback/yourgatewayname.php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;noscript&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;errorbox&amp;quot;&amp;gt;&amp;lt;b&amp;gt;JavaScript is currently disabled or is not supported by your&lt;br /&gt;
browser.&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Please click the continue button to proceed with the processing of your&lt;br /&gt;
transaction.&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Continue &amp;gt;&amp;gt;&amp;quot; /&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/noscript&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;';&lt;br /&gt;
      return $code;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Tokenised Remote Storage==&lt;br /&gt;
&lt;br /&gt;
These days, with the increasing rules &amp;amp; requirements surrounding the storing of credit card details, many merchant gateways are offering services where you can perform repeat rebills without needing to store credit card details locally on your own system. And with WHMCS, gateway modules can utilise this functionality when available.&lt;br /&gt;
&lt;br /&gt;
The basic logic behind token gateways in WHMCS is that clients must either have a credit card number or a token stored in order for recurring billing to be attempted. So if you create a function named _storeremote in your custom gateway module, this function will then override the default local storage when new credit card details are entered. And instead of&lt;br /&gt;
saving in the database, that function then needs to communicate with the gateways API, and return the token that gets assigned to WHMCS.&lt;br /&gt;
&lt;br /&gt;
The variables passed into the _storeremote function are as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang =&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['gatewayid'] # the token stored for the client&lt;br /&gt;
$params['cardtype'] #the Card Type (Visa, MasterCard, etc…)&lt;br /&gt;
$params['cardnum'] # the Card Number&lt;br /&gt;
$params['cardexp'] # the Card’s Expiry Date (Format: MMYY)&lt;br /&gt;
$params['cardstart'] # the Card’s Start Date (Format: MMYY)&lt;br /&gt;
$params['cardissuenum'] # the Card’s Issue Number (Switch/Solo Cards)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
On the first call, the gatewayid will be empty. So when empty you need to create a new profile at the gateway. On subsequent calls the gatewayid that was originally created and stored will be passed in and the existing profile simply needs to be updated. And if the cardnum variable is empty, this indicates that deleting/removal of the stored credit card&lt;br /&gt;
details has been requested.&lt;br /&gt;
&lt;br /&gt;
Once the card details have been updated or stored remotely, you need to return either a success or failure response to tell WHMCS if it worked, and if it did, the token that has been assigned:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang =&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
return array(&amp;quot;status&amp;quot;=&amp;gt;&amp;quot;success&amp;quot;,&amp;quot;gatewayid&amp;quot;=&amp;gt;$results[&amp;quot;token&amp;quot;],&amp;quot;rawdata&amp;quot;=&amp;gt;$results);&lt;br /&gt;
&lt;br /&gt;
return array(&amp;quot;status&amp;quot;=&amp;gt;&amp;quot;failed&amp;quot;,&amp;quot;rawdata&amp;quot;=&amp;gt;$results);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When this function exists in a gateway module, WHMCS will only store the card type, expiry date and the last 4 digits (only) locally in the WHMCS database. So you and your clients will still be able to see exactly what card is stored remotely from within WHMCS.&lt;br /&gt;
&lt;br /&gt;
Then within the capture function, instead of $params[‘cardnum’] you will be passed $params[‘gatewayid’] with which to perform the capture.&lt;br /&gt;
&lt;br /&gt;
==Installation &amp;amp; Activation==&lt;br /&gt;
&lt;br /&gt;
To install the module you’ve created, simply upload it to the /modules/gateways/ folder and then go to Setup &amp;gt; Payment Gateways to activate. If you have create a callback file as well then that should also be uploaded but to the /modules/gateways/callback/ folder.&lt;br /&gt;
&lt;br /&gt;
'''Important:''' It is important that you do not activate your gateway module until you have&lt;br /&gt;
completed step 1 of either the third party gateway or merchant gateway module&lt;br /&gt;
documentation steps to remove the appropriate functions as it’s at the time of activation&lt;br /&gt;
that the type of module you are setting up gets stored in the system.&lt;br /&gt;
&lt;br /&gt;
==Blank Screen/Errors==&lt;br /&gt;
&lt;br /&gt;
If you get a blank page or errors in the Setup &amp;gt; Payment Gateways page after uploading your new module file then this indicates there is a syntax error in your code. To debug that, you can add the following line to your WHMCS configuration.php file to turn on error reporting:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$display_errors = true;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That will enable PHP error reporting and should show you the cause of any issues. Once you are done testing you must remember to remove that line again.&lt;br /&gt;
&lt;br /&gt;
==App Store==&lt;br /&gt;
WHMCS offers an app store to which your completed module can be submitted. The listings are displayed under the Addons tab within the administration area and online at http://www.whmcs.com/appstore . This is a great way to make WHMCS users aware of your module.&lt;br /&gt;
&lt;br /&gt;
In order to submit a listing you'll need a login for whmcs.com/members, if you do not have one please [https://www.whmcs.com/members/submitticket.php?step=2&amp;amp;deptid=5 Contact Us]. Once logged in, visit the app store page at the above URL and click the &amp;quot;Submit your Addon&amp;quot; link. We aim to review submissions in 1-2 weeks.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Developer_Links}}&lt;/div&gt;</summary>
		<author><name>Nicolas</name></author>	</entry>

	<entry>
		<id>http://3.19.219.109/index.php?title=Gateway_Module_Developer_Docs&amp;diff=17502</id>
		<title>Gateway Module Developer Docs</title>
		<link rel="alternate" type="text/html" href="http://3.19.219.109/index.php?title=Gateway_Module_Developer_Docs&amp;diff=17502"/>
				<updated>2016-01-06T18:56:15Z</updated>
		
		<summary type="html">&lt;p&gt;Nicolas: /* Introduction */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Creating a gateway module allows you to connect WHMCS to third party payment and credit card processors that aren’t natively supported in WHMCS as standard.&lt;br /&gt;
&lt;br /&gt;
There are 2 core types of gateway module:&lt;br /&gt;
&lt;br /&gt;
#'''Third Party Gateways''' – this is where the customer leaves your site to pay and is returned once the payment process is completed&lt;br /&gt;
#'''Merchant Gateways''' – this is where the customer enters credit card details directly on your website and the payment is then processed in the background (can also include 3D Secure where the user leaves your site)&lt;br /&gt;
&lt;br /&gt;
{{Developer_Links}}&lt;br /&gt;
&lt;br /&gt;
So the first decision you need to make before starting your module for WHMCS is which type of gateway module you will be creating.  Once you have that, you're ready to begin.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Introduction==&lt;br /&gt;
&lt;br /&gt;
Gateway modules allow a connection between WHMCS and gateways or credit card processors that aren't natively supported in WHMCS.&lt;br /&gt;
&lt;br /&gt;
This documentation will explain the module's structure and contains everything needed in order to successfully create a gateway module for WHMCS.&lt;br /&gt;
&lt;br /&gt;
==Getting Started==&lt;br /&gt;
&lt;br /&gt;
To get started, begin by downloading the module development kit from our GitHub site. There are two sample modules depending upon the [[#Module Type|type of gateway]] you are developing:&lt;br /&gt;
*Third Party Gateway: https://github.com/WHMCS/sample-gateway-module&lt;br /&gt;
*Merchant Gateway: https://github.com/WHMCS/sample-merchant-gateway&lt;br /&gt;
Take the gateway module template &amp;quot;template.php&amp;quot; from this download and rename to &amp;quot;yourgatewayname.php&amp;quot;. it should be all lowercase and must start with a letter.&lt;br /&gt;
&lt;br /&gt;
All functions within a gateway module must be prefixed with the filename also so once you've chosen a name, open the file and replace all occurrences of &amp;quot;template_&amp;quot; with &amp;quot;yourgatewayname_&lt;br /&gt;
&lt;br /&gt;
===Config Array===&lt;br /&gt;
&lt;br /&gt;
Next you can configure the yourgatewayname_config array. This function is the primary function required by all gateway modules and defines both the friendly display name for the module and any custom fields/options/settings your gateway module requires.&lt;br /&gt;
&lt;br /&gt;
The available field types are &amp;quot;text&amp;quot;, &amp;quot;dropdown&amp;quot;, &amp;quot;textarea&amp;quot; and &amp;quot;yesno&amp;quot; (checkboxes) the same as with all modules in WHMCS and the sample config array in &amp;quot;template.php&amp;quot; demonstrates how to use each of these types. The general format is that you specify a system name, all in lowercase for the setting to be referenced by in the module code itself, and then a FriendlyName, Type, and any settings specific to that field type.&lt;br /&gt;
&lt;br /&gt;
Any fields you define here will be available in all gateway module's functions in the $params array so you should avoid common names like currency, invoiceid, etc... that will conflict with the standard variables.&lt;br /&gt;
&lt;br /&gt;
===Module Type===&lt;br /&gt;
&lt;br /&gt;
Now you need to determine what type of module you are creating. There are 2 core types of gateway module:&lt;br /&gt;
&lt;br /&gt;
#'''Third Party Gateways''' – this is where the customer leaves your site to pay and is returned once the payment process is completed&lt;br /&gt;
#'''Merchant Gateways''' – this is where the customer enters credit card details directly on your website and the payment is then processed in the background (can also include 3D Secure where the user leaves your site)&lt;br /&gt;
&lt;br /&gt;
Once you know the of module you are creating then you can proceed. For a Third Party gateway go to [[#Third_Party_Gateway]], and for a merchant gateway go to [[#Merchant_Gateway]].&lt;br /&gt;
&lt;br /&gt;
==Third Party Gateway==&lt;br /&gt;
&lt;br /&gt;
To create a third party gateway module, which is one where the customer leaves your site to make payment on the gateway providers website, simply follow the steps below.&lt;br /&gt;
&lt;br /&gt;
# Begin by deleting the _capture function from the module template (important: you must do this before activating your new module in WHMCS)&lt;br /&gt;
# Next, enter your gateway specific code for taking the user to the payment process in the _link function - an example for how to do this is shown in the gateway module template supplied with this dev kit. This should normally take the format of a form post and you simply need to return the HTML code for the form from this function.&lt;br /&gt;
&lt;br /&gt;
The variables available to you are:&lt;br /&gt;
&lt;br /&gt;
===Invoice Variables===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['invoiceid'] # Invoice ID Number&lt;br /&gt;
$params['description'] # Description (eg. Company Name - Invoice #xxx)&lt;br /&gt;
$params['amount'] # Format: xxx.xx&lt;br /&gt;
$params['currency'] # Currency Code (eg. GBD, USD, etc...)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Client Variables===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['clientdetails']['firstname'] # Clients First Name&lt;br /&gt;
$params['clientdetails']['lastname'] # Clients Last Name&lt;br /&gt;
$params['clientdetails']['email'] # Clients Email Address&lt;br /&gt;
$params['clientdetails']['address1'] # Clients Address&lt;br /&gt;
$params['clientdetails']['address2'] &lt;br /&gt;
$params['clientdetails']['city']&lt;br /&gt;
$params['clientdetails']['state']&lt;br /&gt;
$params['clientdetails']['postcode']&lt;br /&gt;
$params['clientdetails']['country']&lt;br /&gt;
$params['clientdetails']['phonenumber']&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===#System Variables===&lt;br /&gt;
&amp;lt;source lang = &amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['companyname'] # your Company Name setting in WHMCS&lt;br /&gt;
$params['systemurl'] # the url to the Client Area&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# The processing of a payment is handled by a callback file separate from the module (see page 9 for more info on that).&lt;br /&gt;
# If your gateway provider dosen't support automated refunds or you won't be including them in the module then you should delete the _refund function as well, otherwise refer to the Refund section on page 7.&lt;br /&gt;
&lt;br /&gt;
==Merchant Gateway==&lt;br /&gt;
&lt;br /&gt;
To create a merchant gateway module, where the customer enters their card details directly via the client area without leaving the site, simply follow the steps below.&lt;br /&gt;
&lt;br /&gt;
# Begin by deleting the _link function from the module template (important: you must do this before activating your new gateway module in WHMCS)&lt;br /&gt;
# Next, enter your gateway specific code for processing the payment into the _capture function. This normally takes the format of an HTTP/Curl request to the gateway providers API.&lt;br /&gt;
&lt;br /&gt;
The variables available to you are:&lt;br /&gt;
&lt;br /&gt;
===Invoice Variables===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['invoiceid'] # Invoice ID Number&lt;br /&gt;
$params['description'] # Description (eg. Company Name - Invoice #xxx)&lt;br /&gt;
$params['amount'] # Format: xxx.xx&lt;br /&gt;
$params['currency'] # Currency Code (eg. GBP, USD, etc...)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Client Variables===&lt;br /&gt;
&amp;lt;source lang = &amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['clientdetails']['firstname'] # Clients First Name&lt;br /&gt;
$params['clientdetails']['lastname'] # Clients Last Name&lt;br /&gt;
$params['clientdetails']['email'] # Clients Email Address&lt;br /&gt;
$params['clientdetails']['address1'] # Clients Address&lt;br /&gt;
$params['clientdetails']['address2']&lt;br /&gt;
$params['clientdetails']['city']&lt;br /&gt;
$params['clientdetails']['state']&lt;br /&gt;
$params['clientdetails']['postcode']&lt;br /&gt;
$params['clientdetails']['country']&lt;br /&gt;
$params['clientdetails']['phonenumber']&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===# System Variables===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['companyname'] # your Company Name setting in WHMCS&lt;br /&gt;
$params['systemurl'] – the url to the Client Area&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Card Details===&lt;br /&gt;
&amp;lt;source lang = &amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['cardtype'] # the Card Type (Visa, MasterCard, etc…)&lt;br /&gt;
$params['cardnum'] # the Card Number&lt;br /&gt;
$params['cardexp'] # the Card’s Expiry Date (Format: MMYY)&lt;br /&gt;
$params['cardstart'] # the Card’s Start Date (Format: MMYY)&lt;br /&gt;
$params['cardissuenum'] # the Card’s Issue Number (Switch/Solo Cards)&lt;br /&gt;
$params['cccvv'] #Not always present (recurring transactions)&lt;br /&gt;
#but would always be present for client initiated attempts&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# Once you have processed the transaction and got a response, you need to return an array to WHMCS with the results. The return for a successful capture should be as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
return array(&amp;quot;status&amp;quot;=&amp;gt;&amp;quot;success&amp;quot;,&amp;quot;transid&amp;quot;=&amp;gt;$results[&amp;quot;transid&amp;quot;],&amp;quot;rawdata&amp;quot;=&amp;gt;$results);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Within this array, the status must be success to tell WHMCS the capture was successful, transid should be passed the value of the transaction ID that came back from the gateway, and the rawdata variable should be passed an array of the data returned from the gateway to be stored in the WHMCS Gateway Log.&lt;br /&gt;
&lt;br /&gt;
If the transaction were to fail then the response should instead be as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
return array(&amp;quot;status&amp;quot;=&amp;gt;&amp;quot;declined&amp;quot;,&amp;quot;rawdata&amp;quot;=&amp;gt;$results);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this response, the status can be any value you want, declined, error, invalid hash, etc… and will be what staff get to see as the failure reason within the gateway log. The rawdata variable should again be passed an array of the data returned from the gateway to be stored in the WHMCS Gateway Log for debugging purposes.&lt;br /&gt;
&lt;br /&gt;
# If your gateway supports 3D Secure (Verified by Visa or MasterCard Secure Code) then please refer to page 8 for information on how to do handle that.&lt;br /&gt;
&lt;br /&gt;
===Refunds===&lt;br /&gt;
&lt;br /&gt;
# If your gateway provider supports automated refunds then you should add your code for processing a refund into the _refund function which is passed all the same variables as capture but with one additional variable:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['transid'] # the transaction ID of the original transaction to be refunded&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The return arrays for a success or failure should be done exactly the same as described above for the capture function.&lt;br /&gt;
&lt;br /&gt;
If your gateway provider does not support refunds, then the _refund function should be deleted from the module file.&lt;br /&gt;
&lt;br /&gt;
==Callbacks==&lt;br /&gt;
If your gateway provider supports notifying a script when a payment is successful, then you can create a callback file in WHMCS to detect and apply those calls as payments inside WHMCS.&lt;br /&gt;
&lt;br /&gt;
A sample callback file is included in the dev kit for this purpose named “callback.php”. To utilise this script, you simply need to rename it to match your gateway module, and modify the variables within it as per the comments in the code, and to match the variables your specific gateway returns.&lt;br /&gt;
&lt;br /&gt;
These are some helper functions within the sample that you might find useful:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$GATEWAY = getGatewayVariables(‘yourgatewayname’);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function can be used to retrieve the configuration data for your module as specified in&lt;br /&gt;
the _config array. For example you might need it to get a gateway username or secret key to&lt;br /&gt;
validate a callback.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$invoiceid = checkCbInvoiceID($invoiceid,$GATEWAY[‘name’]);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function can be used to check the invoice ID received back is valid. You should simply pass the $invoiceid into this function and your gateway name and if a valid invoice number the script will continue executing, otherwise the script will be halted and an appropriate gateway log entry created.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang =&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
checkCbTransID($transid);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function can be used to check for any existing transactions already recorded for a given transaction ID. This can be useful for protecting against duplicate callbacks as if the transaction ID is already found in the database, the callback script execution will be halted.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
logTransaction($GATEWAY[‘name’],$_POST,&amp;quot;Successful&amp;quot;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function can be used to create a gateway log entry. The first variable needs to be the name of the gateway module, the second should be an array of data, such as the $_POST or $_REQUEST super globals, and the last variable should be the result/status to show in the log.&lt;br /&gt;
&lt;br /&gt;
== 3D Secure Process ==&lt;br /&gt;
&lt;br /&gt;
If your merchant gateway supports 3D Secure (also known as Verified by Visa or MasterCard Secure Code) and you want to implement that then you can as WHMCS fully supports 3D Secured payments.&lt;br /&gt;
&lt;br /&gt;
To do this you need to add a function to your module named yourgatewayname_3dsecure and then similar to the _link function of a third party gateway module, you need to return the HTML for the form post to take the user to the 3D Secure process. An example of this is below.&lt;br /&gt;
&lt;br /&gt;
The _3dsecure function is passed all the same variables that the _capture function is (see page 6). Your return url should be a callback file to handle the response (see page 9)&lt;br /&gt;
&lt;br /&gt;
==Example==&lt;br /&gt;
&amp;lt;source lang = &amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
function yourgatewayname_3dsecure($params) {&lt;br /&gt;
$code = '&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;https://www.gateway.com/3dsecure/&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;gwlogin&amp;quot; value=&amp;quot;'.$params[&amp;quot;loginid&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;invoiceid&amp;quot; value=&amp;quot;'.$params[&amp;quot;invoiceid&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;amount&amp;quot; value=&amp;quot;'. $params[&amp;quot;amount&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;firstname&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;firstname&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;lastname&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;lastname&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;address&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;address1&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;city&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;city&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;state&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;state&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;postcode&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;postcode&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;country&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;country&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;phonenumber&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;phonenumber&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;email&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;email&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;ccnumber&amp;quot; value=&amp;quot;'. $params[&amp;quot;cardnum&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;expirymonth&amp;quot; value=&amp;quot;'.substr($params['cardexp'],0,2).'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;expiryyear&amp;quot; value=&amp;quot;'.substr($params['cardexp'],2,2).'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;cvv2&amp;quot; value=&amp;quot;'. $params[&amp;quot;cccvv&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;return_url&amp;quot; value=&amp;quot;'.&lt;br /&gt;
$params['systemurl'].'/modules/gateways/callback/yourgatewayname.php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;noscript&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;errorbox&amp;quot;&amp;gt;&amp;lt;b&amp;gt;JavaScript is currently disabled or is not supported by your&lt;br /&gt;
browser.&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Please click the continue button to proceed with the processing of your&lt;br /&gt;
transaction.&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Continue &amp;gt;&amp;gt;&amp;quot; /&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/noscript&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;';&lt;br /&gt;
      return $code;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Tokenised Remote Storage==&lt;br /&gt;
&lt;br /&gt;
These days, with the increasing rules &amp;amp; requirements surrounding the storing of credit card details, many merchant gateways are offering services where you can perform repeat rebills without needing to store credit card details locally on your own system. And with WHMCS, gateway modules can utilise this functionality when available.&lt;br /&gt;
&lt;br /&gt;
The basic logic behind token gateways in WHMCS is that clients must either have a credit card number or a token stored in order for recurring billing to be attempted. So if you create a function named _storeremote in your custom gateway module, this function will then override the default local storage when new credit card details are entered. And instead of&lt;br /&gt;
saving in the database, that function then needs to communicate with the gateways API, and return the token that gets assigned to WHMCS.&lt;br /&gt;
&lt;br /&gt;
The variables passed into the _storeremote function are as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang =&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['gatewayid'] # the token stored for the client&lt;br /&gt;
$params['cardtype'] #the Card Type (Visa, MasterCard, etc…)&lt;br /&gt;
$params['cardnum'] # the Card Number&lt;br /&gt;
$params['cardexp'] # the Card’s Expiry Date (Format: MMYY)&lt;br /&gt;
$params['cardstart'] # the Card’s Start Date (Format: MMYY)&lt;br /&gt;
$params['cardissuenum'] # the Card’s Issue Number (Switch/Solo Cards)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
On the first call, the gatewayid will be empty. So when empty you need to create a new profile at the gateway. On subsequent calls the gatewayid that was originally created and stored will be passed in and the existing profile simply needs to be updated. And if the cardnum variable is empty, this indicates that deleting/removal of the stored credit card&lt;br /&gt;
details has been requested.&lt;br /&gt;
&lt;br /&gt;
Once the card details have been updated or stored remotely, you need to return either a success or failure response to tell WHMCS if it worked, and if it did, the token that has been assigned:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang =&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
return array(&amp;quot;status&amp;quot;=&amp;gt;&amp;quot;success&amp;quot;,&amp;quot;gatewayid&amp;quot;=&amp;gt;$results[&amp;quot;token&amp;quot;],&amp;quot;rawdata&amp;quot;=&amp;gt;$results);&lt;br /&gt;
&lt;br /&gt;
return array(&amp;quot;status&amp;quot;=&amp;gt;&amp;quot;failed&amp;quot;,&amp;quot;rawdata&amp;quot;=&amp;gt;$results);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When this function exists in a gateway module, WHMCS will only store the card type, expiry date and the last 4 digits (only) locally in the WHMCS database. So you and your clients will still be able to see exactly what card is stored remotely from within WHMCS.&lt;br /&gt;
&lt;br /&gt;
Then within the capture function, instead of $params[‘cardnum’] you will be passed $params[‘gatewayid’] with which to perform the capture.&lt;br /&gt;
&lt;br /&gt;
==Installation &amp;amp; Activation==&lt;br /&gt;
&lt;br /&gt;
To install the module you’ve created, simply upload it to the /modules/gateways/ folder and then go to Setup &amp;gt; Payment Gateways to activate. If you have create a callback file as well then that should also be uploaded but to the /modules/gateways/callback/ folder.&lt;br /&gt;
&lt;br /&gt;
'''Important:''' It is important that you do not activate your gateway module until you have&lt;br /&gt;
completed step 1 of either the third party gateway or merchant gateway module&lt;br /&gt;
documentation steps to remove the appropriate functions as it’s at the time of activation&lt;br /&gt;
that the type of module you are setting up gets stored in the system.&lt;br /&gt;
&lt;br /&gt;
==Blank Screen/Errors==&lt;br /&gt;
&lt;br /&gt;
If you get a blank page or errors in the Setup &amp;gt; Payment Gateways page after uploading your new module file then this indicates there is a syntax error in your code. To debug that, you can add the following line to your WHMCS configuration.php file to turn on error reporting:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$display_errors = true;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That will enable PHP error reporting and should show you the cause of any issues. Once you are done testing you must remember to remove that line again.&lt;br /&gt;
&lt;br /&gt;
==App Store==&lt;br /&gt;
WHMCS offers an app store to which your completed module can be submitted. The listings are displayed under the Addons tab within the administration area and online at http://www.whmcs.com/appstore . This is a great way to make WHMCS users aware of your module.&lt;br /&gt;
&lt;br /&gt;
In order to submit a listing you'll need a login for whmcs.com/members, if you do not have one please [https://www.whmcs.com/members/submitticket.php?step=2&amp;amp;deptid=5 Contact Us]. Once logged in, visit the app store page at the above URL and click the &amp;quot;Submit your Addon&amp;quot; link. We aim to review submissions in 1-2 weeks.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Developer_Links}}&lt;/div&gt;</summary>
		<author><name>Nicolas</name></author>	</entry>

	<entry>
		<id>http://3.19.219.109/index.php?title=Gateway_Module_Developer_Docs&amp;diff=17499</id>
		<title>Gateway Module Developer Docs</title>
		<link rel="alternate" type="text/html" href="http://3.19.219.109/index.php?title=Gateway_Module_Developer_Docs&amp;diff=17499"/>
				<updated>2016-01-06T18:55:10Z</updated>
		
		<summary type="html">&lt;p&gt;Nicolas: /* Introduction */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Creating a gateway module allows you to connect WHMCS to third party payment and credit card processors that aren’t natively supported in WHMCS as standard.&lt;br /&gt;
&lt;br /&gt;
There are 2 core types of gateway module:&lt;br /&gt;
&lt;br /&gt;
#'''Third Party Gateways''' – this is where the customer leaves your site to pay and is returned once the payment process is completed&lt;br /&gt;
#'''Merchant Gateways''' – this is where the customer enters credit card details directly on your website and the payment is then processed in the background (can also include 3D Secure where the user leaves your site)&lt;br /&gt;
&lt;br /&gt;
{{Developer_Links}}&lt;br /&gt;
&lt;br /&gt;
So the first decision you need to make before starting your module for WHMCS is which type of gateway module you will be creating.  Once you have that, you're ready to begin.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Introduction==&lt;br /&gt;
&lt;br /&gt;
Gateway modules allow a connection between WHMCS and gateways or credit card processors that aren't natively supported in WHMCS.&lt;br /&gt;
&lt;br /&gt;
This documentation will explain the module structure and contains everything needed in order to successfully create a gateway module.&lt;br /&gt;
&lt;br /&gt;
==Getting Started==&lt;br /&gt;
&lt;br /&gt;
To get started, begin by downloading the module development kit from our GitHub site. There are two sample modules depending upon the [[#Module Type|type of gateway]] you are developing:&lt;br /&gt;
*Third Party Gateway: https://github.com/WHMCS/sample-gateway-module&lt;br /&gt;
*Merchant Gateway: https://github.com/WHMCS/sample-merchant-gateway&lt;br /&gt;
Take the gateway module template &amp;quot;template.php&amp;quot; from this download and rename to &amp;quot;yourgatewayname.php&amp;quot;. it should be all lowercase and must start with a letter.&lt;br /&gt;
&lt;br /&gt;
All functions within a gateway module must be prefixed with the filename also so once you've chosen a name, open the file and replace all occurrences of &amp;quot;template_&amp;quot; with &amp;quot;yourgatewayname_&lt;br /&gt;
&lt;br /&gt;
===Config Array===&lt;br /&gt;
&lt;br /&gt;
Next you can configure the yourgatewayname_config array. This function is the primary function required by all gateway modules and defines both the friendly display name for the module and any custom fields/options/settings your gateway module requires.&lt;br /&gt;
&lt;br /&gt;
The available field types are &amp;quot;text&amp;quot;, &amp;quot;dropdown&amp;quot;, &amp;quot;textarea&amp;quot; and &amp;quot;yesno&amp;quot; (checkboxes) the same as with all modules in WHMCS and the sample config array in &amp;quot;template.php&amp;quot; demonstrates how to use each of these types. The general format is that you specify a system name, all in lowercase for the setting to be referenced by in the module code itself, and then a FriendlyName, Type, and any settings specific to that field type.&lt;br /&gt;
&lt;br /&gt;
Any fields you define here will be available in all gateway module's functions in the $params array so you should avoid common names like currency, invoiceid, etc... that will conflict with the standard variables.&lt;br /&gt;
&lt;br /&gt;
===Module Type===&lt;br /&gt;
&lt;br /&gt;
Now you need to determine what type of module you are creating. There are 2 core types of gateway module:&lt;br /&gt;
&lt;br /&gt;
#'''Third Party Gateways''' – this is where the customer leaves your site to pay and is returned once the payment process is completed&lt;br /&gt;
#'''Merchant Gateways''' – this is where the customer enters credit card details directly on your website and the payment is then processed in the background (can also include 3D Secure where the user leaves your site)&lt;br /&gt;
&lt;br /&gt;
Once you know the of module you are creating then you can proceed. For a Third Party gateway go to [[#Third_Party_Gateway]], and for a merchant gateway go to [[#Merchant_Gateway]].&lt;br /&gt;
&lt;br /&gt;
==Third Party Gateway==&lt;br /&gt;
&lt;br /&gt;
To create a third party gateway module, which is one where the customer leaves your site to make payment on the gateway providers website, simply follow the steps below.&lt;br /&gt;
&lt;br /&gt;
# Begin by deleting the _capture function from the module template (important: you must do this before activating your new module in WHMCS)&lt;br /&gt;
# Next, enter your gateway specific code for taking the user to the payment process in the _link function - an example for how to do this is shown in the gateway module template supplied with this dev kit. This should normally take the format of a form post and you simply need to return the HTML code for the form from this function.&lt;br /&gt;
&lt;br /&gt;
The variables available to you are:&lt;br /&gt;
&lt;br /&gt;
===Invoice Variables===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['invoiceid'] # Invoice ID Number&lt;br /&gt;
$params['description'] # Description (eg. Company Name - Invoice #xxx)&lt;br /&gt;
$params['amount'] # Format: xxx.xx&lt;br /&gt;
$params['currency'] # Currency Code (eg. GBD, USD, etc...)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Client Variables===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['clientdetails']['firstname'] # Clients First Name&lt;br /&gt;
$params['clientdetails']['lastname'] # Clients Last Name&lt;br /&gt;
$params['clientdetails']['email'] # Clients Email Address&lt;br /&gt;
$params['clientdetails']['address1'] # Clients Address&lt;br /&gt;
$params['clientdetails']['address2'] &lt;br /&gt;
$params['clientdetails']['city']&lt;br /&gt;
$params['clientdetails']['state']&lt;br /&gt;
$params['clientdetails']['postcode']&lt;br /&gt;
$params['clientdetails']['country']&lt;br /&gt;
$params['clientdetails']['phonenumber']&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===#System Variables===&lt;br /&gt;
&amp;lt;source lang = &amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['companyname'] # your Company Name setting in WHMCS&lt;br /&gt;
$params['systemurl'] # the url to the Client Area&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# The processing of a payment is handled by a callback file separate from the module (see page 9 for more info on that).&lt;br /&gt;
# If your gateway provider dosen't support automated refunds or you won't be including them in the module then you should delete the _refund function as well, otherwise refer to the Refund section on page 7.&lt;br /&gt;
&lt;br /&gt;
==Merchant Gateway==&lt;br /&gt;
&lt;br /&gt;
To create a merchant gateway module, where the customer enters their card details directly via the client area without leaving the site, simply follow the steps below.&lt;br /&gt;
&lt;br /&gt;
# Begin by deleting the _link function from the module template (important: you must do this before activating your new gateway module in WHMCS)&lt;br /&gt;
# Next, enter your gateway specific code for processing the payment into the _capture function. This normally takes the format of an HTTP/Curl request to the gateway providers API.&lt;br /&gt;
&lt;br /&gt;
The variables available to you are:&lt;br /&gt;
&lt;br /&gt;
===Invoice Variables===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['invoiceid'] # Invoice ID Number&lt;br /&gt;
$params['description'] # Description (eg. Company Name - Invoice #xxx)&lt;br /&gt;
$params['amount'] # Format: xxx.xx&lt;br /&gt;
$params['currency'] # Currency Code (eg. GBP, USD, etc...)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Client Variables===&lt;br /&gt;
&amp;lt;source lang = &amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['clientdetails']['firstname'] # Clients First Name&lt;br /&gt;
$params['clientdetails']['lastname'] # Clients Last Name&lt;br /&gt;
$params['clientdetails']['email'] # Clients Email Address&lt;br /&gt;
$params['clientdetails']['address1'] # Clients Address&lt;br /&gt;
$params['clientdetails']['address2']&lt;br /&gt;
$params['clientdetails']['city']&lt;br /&gt;
$params['clientdetails']['state']&lt;br /&gt;
$params['clientdetails']['postcode']&lt;br /&gt;
$params['clientdetails']['country']&lt;br /&gt;
$params['clientdetails']['phonenumber']&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===# System Variables===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['companyname'] # your Company Name setting in WHMCS&lt;br /&gt;
$params['systemurl'] – the url to the Client Area&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Card Details===&lt;br /&gt;
&amp;lt;source lang = &amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['cardtype'] # the Card Type (Visa, MasterCard, etc…)&lt;br /&gt;
$params['cardnum'] # the Card Number&lt;br /&gt;
$params['cardexp'] # the Card’s Expiry Date (Format: MMYY)&lt;br /&gt;
$params['cardstart'] # the Card’s Start Date (Format: MMYY)&lt;br /&gt;
$params['cardissuenum'] # the Card’s Issue Number (Switch/Solo Cards)&lt;br /&gt;
$params['cccvv'] #Not always present (recurring transactions)&lt;br /&gt;
#but would always be present for client initiated attempts&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# Once you have processed the transaction and got a response, you need to return an array to WHMCS with the results. The return for a successful capture should be as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
return array(&amp;quot;status&amp;quot;=&amp;gt;&amp;quot;success&amp;quot;,&amp;quot;transid&amp;quot;=&amp;gt;$results[&amp;quot;transid&amp;quot;],&amp;quot;rawdata&amp;quot;=&amp;gt;$results);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Within this array, the status must be success to tell WHMCS the capture was successful, transid should be passed the value of the transaction ID that came back from the gateway, and the rawdata variable should be passed an array of the data returned from the gateway to be stored in the WHMCS Gateway Log.&lt;br /&gt;
&lt;br /&gt;
If the transaction were to fail then the response should instead be as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
return array(&amp;quot;status&amp;quot;=&amp;gt;&amp;quot;declined&amp;quot;,&amp;quot;rawdata&amp;quot;=&amp;gt;$results);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this response, the status can be any value you want, declined, error, invalid hash, etc… and will be what staff get to see as the failure reason within the gateway log. The rawdata variable should again be passed an array of the data returned from the gateway to be stored in the WHMCS Gateway Log for debugging purposes.&lt;br /&gt;
&lt;br /&gt;
# If your gateway supports 3D Secure (Verified by Visa or MasterCard Secure Code) then please refer to page 8 for information on how to do handle that.&lt;br /&gt;
&lt;br /&gt;
===Refunds===&lt;br /&gt;
&lt;br /&gt;
# If your gateway provider supports automated refunds then you should add your code for processing a refund into the _refund function which is passed all the same variables as capture but with one additional variable:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['transid'] # the transaction ID of the original transaction to be refunded&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The return arrays for a success or failure should be done exactly the same as described above for the capture function.&lt;br /&gt;
&lt;br /&gt;
If your gateway provider does not support refunds, then the _refund function should be deleted from the module file.&lt;br /&gt;
&lt;br /&gt;
==Callbacks==&lt;br /&gt;
If your gateway provider supports notifying a script when a payment is successful, then you can create a callback file in WHMCS to detect and apply those calls as payments inside WHMCS.&lt;br /&gt;
&lt;br /&gt;
A sample callback file is included in the dev kit for this purpose named “callback.php”. To utilise this script, you simply need to rename it to match your gateway module, and modify the variables within it as per the comments in the code, and to match the variables your specific gateway returns.&lt;br /&gt;
&lt;br /&gt;
These are some helper functions within the sample that you might find useful:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$GATEWAY = getGatewayVariables(‘yourgatewayname’);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function can be used to retrieve the configuration data for your module as specified in&lt;br /&gt;
the _config array. For example you might need it to get a gateway username or secret key to&lt;br /&gt;
validate a callback.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$invoiceid = checkCbInvoiceID($invoiceid,$GATEWAY[‘name’]);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function can be used to check the invoice ID received back is valid. You should simply pass the $invoiceid into this function and your gateway name and if a valid invoice number the script will continue executing, otherwise the script will be halted and an appropriate gateway log entry created.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang =&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
checkCbTransID($transid);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function can be used to check for any existing transactions already recorded for a given transaction ID. This can be useful for protecting against duplicate callbacks as if the transaction ID is already found in the database, the callback script execution will be halted.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
logTransaction($GATEWAY[‘name’],$_POST,&amp;quot;Successful&amp;quot;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function can be used to create a gateway log entry. The first variable needs to be the name of the gateway module, the second should be an array of data, such as the $_POST or $_REQUEST super globals, and the last variable should be the result/status to show in the log.&lt;br /&gt;
&lt;br /&gt;
== 3D Secure Process ==&lt;br /&gt;
&lt;br /&gt;
If your merchant gateway supports 3D Secure (also known as Verified by Visa or MasterCard Secure Code) and you want to implement that then you can as WHMCS fully supports 3D Secured payments.&lt;br /&gt;
&lt;br /&gt;
To do this you need to add a function to your module named yourgatewayname_3dsecure and then similar to the _link function of a third party gateway module, you need to return the HTML for the form post to take the user to the 3D Secure process. An example of this is below.&lt;br /&gt;
&lt;br /&gt;
The _3dsecure function is passed all the same variables that the _capture function is (see page 6). Your return url should be a callback file to handle the response (see page 9)&lt;br /&gt;
&lt;br /&gt;
==Example==&lt;br /&gt;
&amp;lt;source lang = &amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
function yourgatewayname_3dsecure($params) {&lt;br /&gt;
$code = '&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;https://www.gateway.com/3dsecure/&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;gwlogin&amp;quot; value=&amp;quot;'.$params[&amp;quot;loginid&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;invoiceid&amp;quot; value=&amp;quot;'.$params[&amp;quot;invoiceid&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;amount&amp;quot; value=&amp;quot;'. $params[&amp;quot;amount&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;firstname&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;firstname&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;lastname&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;lastname&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;address&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;address1&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;city&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;city&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;state&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;state&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;postcode&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;postcode&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;country&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;country&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;phonenumber&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;phonenumber&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;email&amp;quot; value=&amp;quot;'. $params[&amp;quot;clientdetails&amp;quot;][&amp;quot;email&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;ccnumber&amp;quot; value=&amp;quot;'. $params[&amp;quot;cardnum&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;expirymonth&amp;quot; value=&amp;quot;'.substr($params['cardexp'],0,2).'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;expiryyear&amp;quot; value=&amp;quot;'.substr($params['cardexp'],2,2).'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;cvv2&amp;quot; value=&amp;quot;'. $params[&amp;quot;cccvv&amp;quot;].'&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;return_url&amp;quot; value=&amp;quot;'.&lt;br /&gt;
$params['systemurl'].'/modules/gateways/callback/yourgatewayname.php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;noscript&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;errorbox&amp;quot;&amp;gt;&amp;lt;b&amp;gt;JavaScript is currently disabled or is not supported by your&lt;br /&gt;
browser.&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Please click the continue button to proceed with the processing of your&lt;br /&gt;
transaction.&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Continue &amp;gt;&amp;gt;&amp;quot; /&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/noscript&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;';&lt;br /&gt;
      return $code;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Tokenised Remote Storage==&lt;br /&gt;
&lt;br /&gt;
These days, with the increasing rules &amp;amp; requirements surrounding the storing of credit card details, many merchant gateways are offering services where you can perform repeat rebills without needing to store credit card details locally on your own system. And with WHMCS, gateway modules can utilise this functionality when available.&lt;br /&gt;
&lt;br /&gt;
The basic logic behind token gateways in WHMCS is that clients must either have a credit card number or a token stored in order for recurring billing to be attempted. So if you create a function named _storeremote in your custom gateway module, this function will then override the default local storage when new credit card details are entered. And instead of&lt;br /&gt;
saving in the database, that function then needs to communicate with the gateways API, and return the token that gets assigned to WHMCS.&lt;br /&gt;
&lt;br /&gt;
The variables passed into the _storeremote function are as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang =&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$params['gatewayid'] # the token stored for the client&lt;br /&gt;
$params['cardtype'] #the Card Type (Visa, MasterCard, etc…)&lt;br /&gt;
$params['cardnum'] # the Card Number&lt;br /&gt;
$params['cardexp'] # the Card’s Expiry Date (Format: MMYY)&lt;br /&gt;
$params['cardstart'] # the Card’s Start Date (Format: MMYY)&lt;br /&gt;
$params['cardissuenum'] # the Card’s Issue Number (Switch/Solo Cards)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
On the first call, the gatewayid will be empty. So when empty you need to create a new profile at the gateway. On subsequent calls the gatewayid that was originally created and stored will be passed in and the existing profile simply needs to be updated. And if the cardnum variable is empty, this indicates that deleting/removal of the stored credit card&lt;br /&gt;
details has been requested.&lt;br /&gt;
&lt;br /&gt;
Once the card details have been updated or stored remotely, you need to return either a success or failure response to tell WHMCS if it worked, and if it did, the token that has been assigned:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang =&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
return array(&amp;quot;status&amp;quot;=&amp;gt;&amp;quot;success&amp;quot;,&amp;quot;gatewayid&amp;quot;=&amp;gt;$results[&amp;quot;token&amp;quot;],&amp;quot;rawdata&amp;quot;=&amp;gt;$results);&lt;br /&gt;
&lt;br /&gt;
return array(&amp;quot;status&amp;quot;=&amp;gt;&amp;quot;failed&amp;quot;,&amp;quot;rawdata&amp;quot;=&amp;gt;$results);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When this function exists in a gateway module, WHMCS will only store the card type, expiry date and the last 4 digits (only) locally in the WHMCS database. So you and your clients will still be able to see exactly what card is stored remotely from within WHMCS.&lt;br /&gt;
&lt;br /&gt;
Then within the capture function, instead of $params[‘cardnum’] you will be passed $params[‘gatewayid’] with which to perform the capture.&lt;br /&gt;
&lt;br /&gt;
==Installation &amp;amp; Activation==&lt;br /&gt;
&lt;br /&gt;
To install the module you’ve created, simply upload it to the /modules/gateways/ folder and then go to Setup &amp;gt; Payment Gateways to activate. If you have create a callback file as well then that should also be uploaded but to the /modules/gateways/callback/ folder.&lt;br /&gt;
&lt;br /&gt;
'''Important:''' It is important that you do not activate your gateway module until you have&lt;br /&gt;
completed step 1 of either the third party gateway or merchant gateway module&lt;br /&gt;
documentation steps to remove the appropriate functions as it’s at the time of activation&lt;br /&gt;
that the type of module you are setting up gets stored in the system.&lt;br /&gt;
&lt;br /&gt;
==Blank Screen/Errors==&lt;br /&gt;
&lt;br /&gt;
If you get a blank page or errors in the Setup &amp;gt; Payment Gateways page after uploading your new module file then this indicates there is a syntax error in your code. To debug that, you can add the following line to your WHMCS configuration.php file to turn on error reporting:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$display_errors = true;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That will enable PHP error reporting and should show you the cause of any issues. Once you are done testing you must remember to remove that line again.&lt;br /&gt;
&lt;br /&gt;
==App Store==&lt;br /&gt;
WHMCS offers an app store to which your completed module can be submitted. The listings are displayed under the Addons tab within the administration area and online at http://www.whmcs.com/appstore . This is a great way to make WHMCS users aware of your module.&lt;br /&gt;
&lt;br /&gt;
In order to submit a listing you'll need a login for whmcs.com/members, if you do not have one please [https://www.whmcs.com/members/submitticket.php?step=2&amp;amp;deptid=5 Contact Us]. Once logged in, visit the app store page at the above URL and click the &amp;quot;Submit your Addon&amp;quot; link. We aim to review submissions in 1-2 weeks.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Developer_Links}}&lt;/div&gt;</summary>
		<author><name>Nicolas</name></author>	</entry>

	</feed>