API for Third Party Gateway Integration

We'll implement a Paypal payment gateway, this process will require PHP knowledge which is not part of support, this documentation is written for programmers.

1. Create the gateway folder in the [Joomla dir]\administrator\components\com_lovefactory\payment\gateways\ folder.
The name must be lowercase and must contain just letters.

For the Paypal gateway the folder created will be:

[Joomla dir]\administrator\components\com_lovefactory\payment\gateways\paypal

2. Now you will have to create the language file for the gateway, the name of the file must contain the language abbreviation (e.g. en-GB) followed by the name of the gateway added on first step.

[Joomla dir]\administrator\components\com_lovefactory\payment\language\en-GB\en-GB.paypal.ini

3. The main folder of any gateway should contain 3 files: a parameters file, a payment process file and a logo (optional).
Add in the gateway folder the logo in the following format: paypal.jpg|png|gif

4. Create the gateway configuration form: paypal.xml. What options you will add here will differ depending on the gateway. This is a regular Joomla XML form:

  <fieldset name="params">
    <fields name="params">
		Your options here

5. Create the main file that processes the payments:

[Joomla dir]\administrator\components\com_lovefactory\payment\gateways\paypal\paypal.php

class Paypal extends factoryPaymentPlugin

The name of the class must be the same name as the one set on point 1, just that this time it can be with uppercase.

All payment plugins must implement the function "step1". Depending on how complex the payment process is, you can implement as many steps required.

public function step1()
    // Create a new order
    if (!$this->createOrder()) {
      return false;
    // Show the confirmation form
    <h1><?php echo JText::_('FACTORY_PAYMENT_PLUGIN_PAYPAL_CONFIRM_PAGE_TITLE'); ?></h1>
    <p><?php echo JText::sprintf('FACTORY_PAYMENT_PLUGIN_PAYPAL_CONFIRM_PAGE_TEXT', $this->get('order')->title); ?></p>
    <br />
    <form action="<?php echo $this->getAction(); ?>" method="post">
      <input type="hidden" name="item_number"   value="<?php echo $this->get('order')->id; ?>" />
      <input type="hidden" name="on0"           value="userid" />
      <input type="hidden" name="os0"           value="<?php echo $this->get('order')->user_id; ?>" />
      <input type="hidden" name="amount"        value="<?php echo $this->get('order')->amount; ?>" />
      <input type="hidden" name="currency_code" value="<?php echo $this->get('order')->currency; ?>" />
      <input type="hidden" name="cmd"           value="_xclick" />
      <input type="hidden" name="business"      value="<?php echo $this->getParam('email'); ?>" />
    	<input type="hidden" name="item_name"     value="<?php echo $this->get('order')->title; ?>" />
    	<input type="hidden" name="quantity"      value="1" />
    	<input type="hidden" name="return"        value="<?php echo $this->get('url.complete'); ?>" />
    	<input type="hidden" name="cancel_return" value="<?php echo $this->get('url.cancel'); ?>" />
    	<input type="hidden" name="notify_url"    value="<?php echo $this->get('url.notification'); ?>" />
    	<input type="hidden" name="tax"           value="0" />
    	<input type="hidden" name="no_note"       value="1" />
    	<input type="hidden" name="no_shipping"   value="1" />
    	<input type="image" src="<?php echo $this->getButton(); ?>" name="submit" />
    return true;

We are first creating a new order and after that we are displaying the Paypal form to be submitted by the user to the Paypal servers.

Here we can access:

  • the newly created order using: $this→get('order') (id, title, user_id, membership_id, price_id, amount, currency)
  • the configuration parameters of the payment plugin defined on step 4 using: $this→getParam('PARAMETER_NAME_HERE')
  • the url used by Paypal if the transactiaon was completed: $this→get('url.complete')
  • the url used by Paypal if the transactiaon was cancelled: $this→get('url.cancel')
  • the url used by Paypal to send the IPN regarding the transaction: $this→get('url.notification')

To process the IPN, create the function "processIpn". This function must process the Gateway IPN and return a status for the Payment.
The variables included in notifications are listed in the IPN Variable Reference. These variables are different for each payment gateway.

public function processIpn()
    $ipn = new JRegistry(JRequest::get('POST'));
    // Preprocess ipn
    $ipn->set('user_id',   $ipn->get('option_selection1'));
    $ipn->set('amount',    $ipn->get('mc_gross'));
    $ipn->set('currency',  $ipn->get('mc_currency'));
    $ipn->set('order_id',  $ipn->get('item_number'));
    $ipn->set('refnumber', $ipn->get('txn_id'));
    // Create payment
    $payment = $this->createPayment($ipn);
    // Check for errors
    $errors = $this->validatePayment($ipn);
    switch ($ipn->get('payment_status')) {
      case 'Completed':
      case 'Processed':
        $payment->status = $errors ? 40 : 20; // 40 - Manual check; 20 - Completed
      case 'Failed':
      case 'Denied':
      case 'Canceled-Reversal':
      case 'Expired':
      case 'Voided':
      case 'Reversed':
      case 'Refunded':
        $payment->status = 30; // 30 - Failed
      case 'In-Progress':
      case 'Pending':
        $payment->status = 10; // 10 - Pending
    $errors[] = 'Received Payment Status: ' . $ipn->get('payment_status');
    $this->savePayment($payment, $errors);

What the function does:
- creates the $ipn variable from the request; the $ipn must be of type JRegistry.
- the $ipn variable must have set the following parameters: user_id, amount, currency, order_id, refnumber
- creates a new payment using the $ipn
- checks for errors
- decides the payment status which can be:

  • 10 - Pending: the payment is still pending
  • 20 - Complemeted: the payment was completed successfully
  • 30 - Failed: the payment has failed
  • 40 - Manual check: the payment was successfull, but other errors occured (for example the expected amount to be paid was different)

In this case the admin must review the payment and to decide if the payment is valid or not.
- saves the payment