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:
<form> <fieldset name="params"> <fields name="params"> ... Your options here ... </fields> </fieldset> </form>
5. Create the main file that processes the payments:
[Joomla dir]\administrator\components\com_lovefactory\payment\gateways\paypal\paypal.php
require_once(JPATH_ADMINISTRATOR.DS.'components'.DS.'com_lovefactory'.DS.'payment'.DS.'factoryPaymentPlugin.class.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" /> </form> <?php 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:
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 break; case 'Failed': case 'Denied': case 'Canceled-Reversal': case 'Expired': case 'Voided': case 'Reversed': case 'Refunded': $payment->status = 30; // 30 - Failed break; case 'In-Progress': case 'Pending': default: $payment->status = 10; // 10 - Pending break; } $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:
In this case the admin must review the payment and to decide if the payment is valid or not.
- saves the payment