Introduction 

nBill includes the facility for payments to be made online via a third party payment service provider(PSP), such as Paypal.  As there are literally hundreds of PSPs out there, many of which are specialised to a particular country, nBill has been written in such a way as to allow payment gateway extensions to be 'plugged in' so that the component can be used with virtually any PSP.

Free payment gateway extensions for various PSPs are available. If you want to use a different PSP, you will need to install a new gateway that has been created specifically for your PSP. Creating a payment gateway for nBill is quite a complicated process, requiring a skilled PHP developer. If you are not an experienced PHP developer, don't try to create a payment gateway! You must be capable of producing robust PHP code which is impervious to malicious SQL injection and other cracking methods. If you do not FULLY understand the instructions given in this document, please do not try to create a payment gateway - get a professional to do it for you.

In the following instructions, wherever you see [gateway], insert the name of your payment gateway (avoid spaces or punctuation marks in your gateway name). Look at the code for the supplied gateways to see how the following information has been put into practise.

To develop a new payment gateway:

Create a folder on your computer in which to develop the gateway. In that folder, create a sub-folder called 'admin.[gateway]'. Create a new file called '[gateway].php'.  This file will be used to direct the user to the payment service provider.

Add the following code to the start of the file:
//Ensure this file has been reached through a valid entry point (not always necessary eg. for class files, but included on every file to be safe!)
(defined('_VALID_MOS') || defined('_JEXEC') || defined('NBILL_VALID_NBF')) or die('Access Denied.');

$nb_database = nbf_cms::$interop->database;
                   
  include_once(nbf_cms::$interop->nbill_admin_base_path . "/framework/classes/nbill.date.class.php");

Create a new file called '[gateway].en-GB.php'. If the gateway is to be used in languages other than English, add an appropriately named language file for each language. To ensure that the correct language is picked up at runtime based on the language that Joomla or Wordpress is using, add the following code to your [gateway].php file (after the above lines):

if (file_exists(nbf_cms::$interop->nbill_admin_base_path . "/admin.gateway/admin.[gateway]/[gateway]." . nbf_cms::$interop->language . ".php")) {
        include_once(nbf_cms::$interop->nbill_admin_base_path . "/admin.gateway/admin.[gateway]/[gateway]." . nbf_cms::$interop->language . ".php");
    } else {
        if (file_exists(nbf_cms::$interop->nbill_admin_base_path . "/admin.gateway/admin.[gateway]/[gateway].en-GB.php")) {
            include_once(nbf_cms::$interop->nbill_admin_base_path . "/admin.gateway/admin.[gateway]/[gateway].en-GB.php");
        }
    }


Use the language files to store constants for any text that needs to be displayed to the user. This includes explanatory text for the gateway parameters that will appear in nBill's back end gateway administration functions (see details about creating the gateway parameter values using installation file later on...)

When creating a payment gateway for a particular payment service provider, you typically require some custom settings that are specific to that payment service provider.  For example, you might need a merchant id, or some kind of authentication code. The values for these settings can be stored by nBill, and the user can be given the ability to modify those values through the nBill administrator. Details about how to define gateway parameters are described later in this guide.

In addition to gateway parameter values, you will also need some dynamic values - things such as the amount of the payment, the currency, and possibly the name and address of the person paying (if known). These values are made available through built-in variables which will be available to your script at run-time.

The following variables are available to you to help you construct the necessary URL to redirect to, or form to post (note: these variables are defined and populated by nBill before it calls your gateway script). The most important ones are:

$g_tx_id - The gateway id for the transaction (this will be needed if the payment gateway posts back to the merchant's website, to enable nBill to identify what the payment is for)
$currency - The three character code for the currency of the transaction (eg. USD, or GBP).
$standard_totals->total_gross - The full amount that needs to be paid (including any setup fees).
$regular_totals->total_gross - The full amount that needs to be paid on a recurring basis after the initial payment (this will only be different from $standard_totals->total_gross if there is a setup fee defined for an ordered product, or a discount is being applied to the first payment only).
$orders - An array of items that have been ordered:
    $orders[<index>]['product_code'] - The SKU of the item.
    $orders[<index>]['product_name'] - The name of the item.
    $orders[<index>]['net_price'] - The net price of the item.
    $orders[<index>]['setup_fee'] - The net price of the setup fee for the item, if applicable.
    $orders[<index>]['quantity'] - The number of units ordered.    
    $orders[<index>]['tax_amount'] - The amount of tax to be added to the net price.
    $orders[<index>]['setup_fee_tax_amount'] - The amount of tax to be added to the setup fee amount.    
    $payment_frequency - A 2-character code indicating how often to make repeat payments.  Possible values are:

  • AA - One-off
  • BB - Weekly
  • BX - Four Weekly
  • CC - Monthly
  • DD - Quarterly (every three months)
  • DX - Semi-Annually (every six months)
  • EE - Annually (every year)
  • FF - Bi-annually (every two years)
  • GG - Five-yearly
  • HH - Ten-yearly

The following variables provide further information that may be necessary/useful:
$shipping_service - The name of the shipping option (eg. 'First Class', 'Federal Express').
$standard_totals->total_net - The total price of all ordered items, before tax.
$standard_totals->total_tax - The total amount of tax added to the net price of all ordered items.
$standard_totals->total_shipping - The total amount of shipping fees added to the price of all ordered items.
$standard_totals->total_shipping_tax - The total amount of tax added to the shipping fees.
(The above 4 variables, when added together, should equal the value held in $standard_totals->total_gross)
$expiry_date - This value (a timestamp integer) defaults to zero if no expiry date is specified - always check that the value is greater than the current time before use.

Details about the person paying are available, depending on how the gateway was called and what fields were present on the order form. You can use the following variables if they are available, but remember to check to make sure they hold a value (if necessary) before using them.

$billing_data['first_name']
$billing_data['last_name']
$billing_data['company_name']
$billing_data['username']
$billing_data['address_1']
$billing_data['address_2']
$billing_data['address_3']
$billing_data['
town']
$billing_data['
state']
$billing_data['
postcode']
$billing_data['
country']
$billing_data['telephone']
$billing_data['email_address']

Use whichever values you need depending on the requirements of the payment service provider. You probably will not need to use all of the available values.

To get the gateway parameter values defined by the merchant in nBill for this gateway, use the following code:

$sql = "SELECT * FROM #__nbill_payment_gateway WHERE gateway_id = '[gateway]'";
$nb_database->setQuery($sql);
$gateway_fields = $nb_database->loadAssocList('g_key');

The values are then available in the $gateway_fields associative array, for example $gateway_fields['<name of my setting>']['g_value']. g_value means 'gateway value' and the 'g_' prefix is only there because the word 'value' is a reserved word in mySQL (or in some versions at least).

If you can pass parameters to the payment service provider in a URL query string, write the necessary PHP code to construct the URL, and redirect the user using the nbf_common::redirect($url) function.

If you have to POST the parameters to the payment service provider and wait for a response without redirecting the user, you can create your own function to do this based on the documentation provided by the PSP.

Please note that it is not safe to echo sensitive data over HTTP, so only do that if the Joomla or Wordpress site is using SSL. If the site is using HTTP, it will be necessary to introduce an extra confirmation step so that the values can be posted directly to the Payment Service Provider's secure server.  The confirmation form can be posted using Javascript (if enabled on the user's browser), thus removing the necessity for the user to submit an extra form. See the Paypoint (SECPay) gateway for an example of this.

If your gateway script does not redirect the user, control returns to nBill, which will output a 'thank you for your order' message. To suppress that message, just set the $abort flag to true.

NOTE: If you redirect the user to the PSP, you will need to pass the value of $g_tx_id to the PSP so that they can quote it when they call you back. Typically, if the PSP allows, you would use the value as part of the transaction ID. However, please be careful to ensure that all transaction IDs are unique (if required by your PSP, which it usually is) - bearing in mind that a merchant might be using nBill on more than one website, and therefore $g_tx_id might not be unique for that merchant. For example, you could perform an md5 hash on the website address (nbf_cms::$interop->live_site) and use that as a prefix or suffix to make $g_tx_id unique.

NOTE: If you need to collect credit card details on the merchant site (ie. the PSP does not provide a shared service for secure credit card detail capture), you need to be careful to ensure that important values cannot be changed by a cracker between form posts. For example, if you store the payment amount in a hidden field while capturing card details, you must check that the amount has not been changed by the user before sending it off for authorisation. One way to do this would be to run an md5 hash on the important values PLUS at least one piece of information that cannot be figured out by the user - such as the site ID hash which is stored in the #__nbill_license table. You can then check the hash again before posting off to the PSP to ensure no hacking has taken place. Remember: always think like a cracker! Try to look for any important data that could be changed by the user at every step of the process, and put measures in place to verify that the data is valid.

If the payment service provider processes the payment immediately and responds directly to your HTTP POST, you can also add the relevant code for processing the receipt in the same file.  If the payment service provider provides a 'callback', the processing code will need to go in a separate file - create a folder (at the same level as the 'admin.[gateway]' folder), name it [gateway], and add a file called [gateway].php.  That is the file that will be processed when the payment service provider does a callback.  The callback URL would typically be in the format 'http://www.<domain name here>.com/index.php?option=com_nbill&action=gateway&gateway=[gateway]'.  You can use other URL querystring parameters as well if you wish. Use the nbf_cms::$interop->live_site variable to pick up the appropriate callback domain name, and use a gateway parameter for the rest of the callback URL.

Processing receipts

When your gateway receives notification that a payment has been made (either by a response to your POST, or by calling you back), your gateway will need to load the associated order details and process the order.

If using the 'callback' method, you will have created a separate file ([gateway]/[gateway].php) for this processing.  In this case, make sure you add the following code to the start of the file:

//Ensure this file has been reached through a valid entry point (not always necessary eg. for class files, but included on every file to be safe!)
(defined('_VALID_MOS') || defined('_JEXEC') || defined('NBILL_VALID_NBF')) or die('Access Denied.');

$nb_database = nbf_cms::$interop->database;
include_once(nbf_cms::$interop->nbill_admin_base_path . "/framework/classes/nbill.date.class.php");
include_once(nbf_cms::$interop->nbill_admin_base_path . "/framework/classes/nbill.payment.class.php");
if (file_exists(nbf_cms::$interop->nbill_admin_base_path . "/admin.gateway/admin.[gateway]/[gateway]." . nbf_cms::$interop->language . ".php")) {
    include_once(nbf_cms::$interop->nbill_admin_base_path . "/admin.gateway/admin.[gateway]/[gateway]." . nbf_cms::$interop->language . ".php");
} else {
    include_once(nbf_cms::$interop->nbill_admin_base_path . "/admin.gateway/admin.[gateway]/[gateway].en-GB.php");
}


If the payment service provider in question provides various different types of callback (eg. the Paypal gateway has 2 types: one for the IPN, and the other for redirecting the user to after payment has been completed), use a switch statement to control the flow depending on the querystring parameters (see Paypal gateway).

Once again, use this code to get the gateway parameters:

$sql = "SELECT * FROM #__nbill_payment_gateway WHERE gateway_id = '[gateway]'";
$nb_database->setQuery($sql);
$gateway_fields = $nb_database->loadAssocList('g_key');

Then perform any processing that may be required to validate the callback. For example, with Paypal, you post back to Paypal to confirm the details; with SECPay, you check for an md5 hashed key to authenticate (remember, anyone can post a response to your gateway script, so you should have some process to ensure that the notification is authentic). Once we are sure we have a valid callback, it is time to load the nBill order details, and process the payment according to the selected configuration options. 

This may involve the following steps:
1) Make sure we have not already processed this payment
2) Verify that the amount is what we are expecting
3) Create a client record (if applicable)
4) Create an order record (if applicable)
5) Create an invoice record (if applicable)
6) Create an income record (if applicable)

There are 2 built-in functions which will sort out all the bits that have to be created, and send the relevant e-mails out. They are named nbf_payment::gateway_processing() and nbf_payment::finish_gateway_processing().

The first function to call is nbf_payment::gateway_processing(), which takes the following parameters:

$g_tx_id (this is the ID number that was passed to the payment service provider at the time the payment was made, and which should be passed back to you by them)
$payment_amount
$payment_currency
&$warning_message (this is an output parameter which needs to be passed to the 2nd function so that the warning is added to the e-mail to the administrator)
&$error_message (another output parameter that is passed to the 2nd function - if populated, it means the function failed to work - eg. if the ID number passed in does not exist in the database)
$customer (optional - used when creating an income item to indicate who the payment was from. If omitted, nBill will attempt to find a value based on the client record)
$reference (optional - if the payment service provider supplies its own reference, you can pass that in to be stored with the income record)
$notes = (defaults to the value of the NBILL_AUTO_GENERATED_INCOME constant)

After that call has been made, you can either do some extra processing (eg. populating your own transaction table with extra information), or go straight onto the 2nd function: nbf_payment::finish_gateway_processing(), which sends out the relevant e-mails and redirects the user to the success or failure page (if you pass in a URL), or displays an appropriate message (if you don't). The parameters for this function are:

$warning_message (pass in the value that you got back from the nbf_payment::gateway_processing() function)
$error_message (pass in the value that you got back from the nbf_payment::gateway_processing() function)
$add_debug_info (optional - indicate whether or not to add extra environmental information to the administrator's e-mail if there is an error message - defaults to false, as this debug information can contain sensitive data about the transaction and the server configuration. You can use a gateway parameter in your gateway to allow the user to decide whether or not to allow this)
$redirect_url (optional - a URL to redirect to after sending the e-mails. If not supplied, an appropriate message will be displayed).

Note: If the callback from the payment service provider happens behind the scenes from the user's point of view (like Paypal IPN), then of course the user will never see the success or failure message, nor be redirected to a success or failure URL by the gateway script. In such cases, the success or failure URL may be defined by the merchant in the payment service provider's control panel, or it might be a parameter which can be passed to the PSP at the time of the transaction (in which case you can create gateway parameters for the values).

All of the above will make more sense if read in conjunction with the existing payment gateways.

Creating a Manifest File

In order for nBill to know what features are supported by your gateway, you need to include a manifest file. If a manifest file is not included, nBill will go into backward compatibility mode, which slows down processing somewhat and uses more memory. A manifest file should contain the following code (naturally you need to amend the values according to what is supported by your gateway):

//Ensure this file has been reached through a valid entry point (not always necessary eg. for class files, but included on every file to be safe!)
(defined('_VALID_MOS') || defined('_JEXEC') || defined('NBILL_VALID_NBF')) or die('Access Denied.');

class nbill_[gateway]_manifest
{
    /** @var Whether or not recurring payments are supported */
    public $recurring_payments = true;
    /** @var Which pre-defined recurring payment frequencies are supported (comma separated list) */
    public $defined_frequencies = 'BB,BX,CC,DD,DX,EE,FF,GG,HH';
    /** @var Whether or not the first payment can be zero (free trial) */
    public $first_payment_zero = true;
    /** @var Whether or not the first payment can be a different (non-zero) amount to the repeat payments */
    public $first_payment_different = true;
    /** @var Whether or not a fixed number of payments or expiry date is allowed (eg. for paying a fixed sum in installments) */
    public $fixed_no_of_payments = true;
    /** @var If a fixed number of payments is allowed, but there is a minimum number of installments, this property should hold the minimum (it is assumed that 1 single installment is always allowed) */
    public $minimum_no_of_payments = 2;
}

The manifest file should be put in your /admin.[gateway]/ folder, and named [gateway].manifest.php. That covers the core code that you will need to write.  Now for creating the installation package.

Creating an Installation Package

To enable your gateway to be installed using the gateway installer in nBill, you need to create an installation file. This is a simple text file with the file extension .nbe (nBill Extension). In this file, you create the definition of the gateway parameter values that you want to store, as well as any other database tables that you want to create, and PHP files that you want to include. The basic structure of the file is shown below:

#nbill_extension_installer_1.0

# This is a sample install file for an nBill Payment Gateway - replace any values with your own as indicated
# In all cases where you see <gateway_name>, replace it with your actual gateway name!
# Lines that start with a hash (#) or double slash (//) or that are blank, will be ignored by the installer
# If you need to use a hash or double slash in the data, prefix with a backslash escape character (eg. \// or \#)
# Always start a new setting on a new line.
# If you want a line break within a setting, surround the setting value with square brackets
# When you publish your gateway, you can delete these comment lines from the top of the file!

# The following directive tells the installer whether or not to convert the files in this extension to UTF-8.
# If your files are encoded as ISO-8559-1, some CMSs (eg. Joomla 3.x, Mambo 4.6) will require them to be
# converted to UTF-8. Other CMSs may prefer them to be kept as ISO-8559-1, or the user might be able to choose.
# If the files are NOT encoded using ISO-8559-1, you must set this option to C (Don't Convert), as the conversion
# process will not work with any other encoding.
# In most cases though, it is necessary to set this option to A.
#
# Valid values for this directive are:
# A = Convert if required by CMS
# B = Convert always
# C = Don't Convert
Convert_ISO-8859-1_to_UTF-8=A

type=gateway

#Minimum version of nBill on which this extension installation will work
nbill_version=2.0.0

# The name is used for the folder name, so no spaces or punctuation allowed:
name=<gateway_name>

# The title is used as the default human-readable display value (although the user can change it):
title=***Enter Pretty Name Here***

author=***Enter your own name or company name here***

date=***Enter date of this release***

copyright=***Any copyright message***

license=***Licensing information goes here***

author_email=***Contact e-mail address***

author_url=***Website***

version=***Version number of this extension***

description=***Constant that contains the extension description***

file=***Front-end Gateway file (ie. <gateway_name>/<gateway_name>.php)***

admin_file=***Back-end Gateway file (ie. admin.<gateway_name>/<gateway_name>.php)***

admin_file=***Back-end Manifest file (ie. admin.<gateway_name>/<gateway_name>.manifest.php)***

admin_file=***Back-end Language file (ie. admin.<gateway_name>/<gateway_name>.en-GB.php***

# If you want to run some code after installation, include an install file - it MUST be named as indicated below
admin_file=admin.<gateway_name>/<gateway_name>.install.php

# If you want to run some code after uninstallation, include an uninstall file - it MUST be named as indicated below
admin_file=admin.<gateway_name>/<gateway_name>.uninstall.php

# For gateway settings, add a line like the following for each parameter:
gateway_parameter=***key***;value=***;label=***;help=***;required=0;editable=0

# Repeat for as many parameters as you want to add...
gateway_parameter=***key***;value=***;label=***;help=***;required=0;editable=0
gateway_parameter=***key***;value=***;label=***;help=***;required=0;editable=0
gateway_parameter=***key***;value=***;label=***;help=***;required=0;editable=0

# You can split the values onto multiple lines by surrounding in square brackets, like this:
gateway_parameter=[
***parameter_key***;
value=***default_value***;
label=***label_constant***; //You can also add comments at the end of a line, like this
help=***help_text_constant***; #or this!
required=***0 or 1***;
editable=***0 or 1***]

# If you want to run an additional database query, you can define it like this:
query=[***Enter your SQL here, on multiple lines if you like***]

# If the database changes you make by running additional queries, above, can be undone by running another query,
# enter the query here (undo queries will be run if the installation fails or when the extension is uninstalled)
undo_query=[***Enter your SQL here, on multiple lines if you like***]

Note that the gateway parameters will be displayed to the user in the same order that they are defined within the file, so it is probably best to put the most important items at the top.

If you want to add extra functionality to nBill that relates to your payment gateway, you can do so by including a couple of extra files in the either the [gateway] or admin.[gateway] folder (or both): [gateway].functions.php and [gateway].functions.html.php. Put your program flow control and processing logic in [gateway].functions.php, and your html generation in [gateway].functions.html.php. You can add any other files you like as well (eg. [gateway].class.php).

To access back-end (admin) functions, an extra menu item will appear under the 'Extensions' menu in nBill automatically if a functions file is detected.  If your functions file contains more than 1 feature, you should display a menu of options to the user if no parameters are passed in, and use querystring parameters to allow access to your other features. 

To access front-end functions, the URL should follow this pattern: index.php?option=com_nbill&action=gatewayfunctions&gateway=[gateway] - you can of course add your own querystring parameters as required by your script.  Your documentation should inform users of how to access any extra features you have added.

See the installation files that come with the existing gateways for examples of how to put together the file.

Licensing

If you are donating your payment gateway for general use by the public, it is recommended to add a license such as the following to the comments at the start of each file in your gateway:

/**
* This gateway was developed by and is copyright of <Name of your company>.
* Sections of code may be copyrighted to other parties (eg. where sample code was used
* from the <Name of payment service provider> documentation). All parts (of this gateway only)
* written by <Name of your company> are licensed for use in any way you wish, as long as this
* copyright message remains intact, and without any guarantee of any sort - use at your own risk.*/

In order to be accepted as an approved nBill gateway, and qualify for a free 5 year license key, in addition to implementing the above license, the following guidelines should be adhered to:

  • Code should be properly commented for ease of reading.
  • There should be no redundant code - please don't leave artifacts from other gateways that you may have copied from.
  • There should be no 'commented out' code in the gateway unless there is a very good reason for it.
  • Code should be properly indented - please do not include excess white space, and be consistent in the way you use brackets and indentation.
  • Any HTML code that is output must validate with the W3C validator. Please do not use deprecated syntax like <font>.
  • Please do not introduce any extra unnecessary steps - eg. don't require the user to click on a link or a button unless it is absolutely necessary. They have already submitted their form, and submitted a summary page, and will have to submit their card details - we don't want them to have to submit anything else. If you must post a form to the PSP, use Javascript to do it if necessary rather than requiring another click from the user (if Javascript is disabled on the user's browser, then they would have to click themselves to submit, but this is no reason to inconvenience the other 99.9% of users).
  • When reading posted values or request values, always use the nbf_common::get_param() function (you can use the Joomla or Wordpress API, but your gateway will then be tied to the CMS whose API you are using).
  • If your gateway involves a callback from the payment service provider (PSP), always provide some way of checking the authenticity of the callback - even if it is just an IP address check (which you should implement as a gateway parameter in the installation file so that the user can change it).
  • It is preferred if base URLs that are used to call or hand over to the PSP are defined as gateway parameters in the installation file - in case they change in future (individual request parameters that are appended to the base URL can of course be hard-coded).
  • If the PSP supports recurring payments, your gateway should also support them - including whatever development is necessary to pass the payment frequency to the PSP. Please Note: If your gateway does not support recurring payments (whether the PSP supports them or not), you will only be granted a 2-year license key for nBill rather than a 5-year license.

© 2016 Encke Technologies SRL. All Rights Reserved.