Develop OS Property Plugins

[TOC] OS Property supports multiple payment plugins. After being installed, the payment plugins are stored in the folder components/com_osproperty/plugins.
Following are steps to create a payment plugin for OS Property:
Step 1: Create a .xml file to define the plugin package (example os_paypal.xml) with the structure as following: Step 2: Create a .php file to put the code to process the payment (example os_paypal.php):

ipn_log = true ;
        $this->ipn_log_file = JPATH_COMPONENT.DS.'ipn_logs.txt';
        $this->_mode = $params->get('paypal_mode') ;
        if ($this->_mode)
            $this->_url = 'https://www.paypal.com/cgi-bin/webscr';
        else
            $this->_url = 'https://www.sandbox.paypal.com/cgi-bin/webscr';                                          
        $this->setParam('business', $params->get('paypal_id')); 
        $this->setParam('rm', 2);
        $this->setParam('cmd', '_xclick');
        $this->setParam('no_shipping', 1);
        $this->setParam('no_note', 1);
        $this->setParam('lc', 'US');
        $this->setParam('currency_code', $params->get('paypal_currency', 'USD'));
    }
    /**
     * Set param value
     *
     * @param string $name
     * @param string $val
     */
    function setParam($name, $val) {
        $this->_params[$name] = $val;
    }
    /**
     * Setup payment parameter
     *
     * @param array $params
     */
    function setParams($params) {
        foreach ($params as $key => $value) {
            $this->_params[$key] = $value ;
        }
    }
    /**
     * Process Payment
     *
     * @param object $row
     * @param array $params
     */
    function processPayment($row, $data) {
        $jinput = JFactory::getApplication()->input;
        $Itemid = $jinput->getInt('Itemid');        
        $siteUrl = JURI::base() ;
        $db = & JFactory::getDBO() ;
        $this->setParam('item_name', $data['item_name']); 
        $this->setParam('amount', $data['amount']);

        $this->setParam('custom', $row->id);                                                                                                
        $this->setParam('return', $siteUrl."index.php?option=com_osproperty&task=payment_return&order_id=$row->id&Itemid=".$Itemid);    
        $this->setParam('cancel_return', $siteUrl.'index.php?option=com_osproperty&task=payment_cancel&order_id='.$row->id);
        $this->setParam('notify_url', $siteUrl.'index.php?option=com_osproperty&task=payment_confirm&payment_method=os_paypal');        
        $this->setParam('address1', $data['address']);      
        $this->setParam('address2', '');        
        $this->setParam('city', $data['city']);     
        $this->setParam('country', $data['country']);       
        $this->setParam('first_name', $data['first_name']);
        $this->setParam('last_name', $data['last_name']);
        $this->setParam('state', $data['state']);
        $this->setParam('zip', $data['zip']);
        $this->setParam('email', $data['email']) ;      
        $this->submitPost();                
    }
    /**
     * Validate the post data from paypal to our server
     *
     * @return string
     */
    function _validate() {
        $errNum="";
        $errStr="";
        $urlParsed = parse_url($this->_url);
        $host = $urlParsed['host'];
        $path = $urlParsed['path'];        
        $postString = ''; 
        $response = '';   
        foreach ($_POST as $key=>$value) { 
           $this->_data[$key] = $value;
           $postString .= $key.'='.urlencode(stripslashes($value)).'&'; 
        }
        $postString .='cmd=_notify-validate';
        $fp = fsockopen($host , '80', $errNum, $errStr, 30); 
          if(!$fp) {                    
             return false;
          } else {              
             fputs($fp, "POST $path HTTP/1.1\r\n"); 
             fputs($fp, "Host: $host\r\n"); 
             fputs($fp, "Content-type: application/x-www-form-urlencoded\r\n"); 
             fputs($fp, "Content-length: ".strlen($postString)."\r\n"); 
             fputs($fp, "Connection: close\r\n\r\n"); 
             fputs($fp, $postString . "\r\n\r\n"); 
             while(!feof($fp)) { 
                $response .= fgets($fp, 1024); 
             } 
             fclose($fp);
          }         
         $this->ipn_response = $response ;       
         $this->log_ipn_results(true); 
         if ($this->_mode) {
             if (stristr($response, "VERIFIED") && ($this->_data['payment_status'] == 'Completed'))              
                 return true;       
             else              
                 return false;
         } else {           
            //Always return true for test mode, prevent unnecessary support requests            
             return true ;    
         }              
    }
    /**
     * Log IPN result
     *
     * @param string $success
     */
    function log_ipn_results($success) {
      if (!$this->ipn_log) return;
      $text = '['.date('m/d/Y g:i A').'] - '; 
      if ($success) $text .= "SUCCESS!\n";
        else $text .= 'FAIL: '.$this->last_error."\n"; 
      $text .= "IPN POST Vars from Paypal:\n";
      foreach ($this->_data as $key=>$value) {
         $text .= "$key=$value, ";
      }
      $text .= "\nIPN Response from Paypal Server:\n ".$this->ipn_response;
      $fp=fopen($this->ipn_log_file,'a');
      fwrite($fp, $text . "\n\n"); 
      fclose($fp);  // close file
   }
    /**
     * Process payment 
     *
     */
    function verifyPayment() {
        $ret = $this->_validate();              
        if ($ret) {
            require_once(JPATH_COMPONENT_ADMINISTRATOR.DS."tables".DS."order.php");
            $row = JTable::getInstance('Order', 'OspropertyTable');
            $id = $this->_data['custom'];
            $db = JFactory::getDbo();
            $db->setQuery("Select order_status from #__osrs_orders where id = '$id'");
            $order_status = $db->loadResult();
            if($order_status != "S"){ //only running when the system already update Order status
                $transactionId = $this->_data['txn_id'];
                $amount = $this->_data['mc_gross'];             
                if ($amount < 0)
                    return false ;                          
                $row->load($id);
                if ($row->published)
                    return false ;
                $row->transaction_id = $transactionId;
                $row->order_status = "S";
                $row->payment_made = 1;
                $row->store();  
                OspropertyPayment::paymentComplete($row->id,0);
                return true;
            }
        } else {
            return false;
        }            
    }   
}

Step 3: Make a zip package include 2 above files, then login to the back-end of your site, go to OS Property -> Payment Plugins to choose the zip package of payment plugin and install it from there.

To develop your own payment plugin easily, you should based on the source code of the default payment plugins in EShop.