API/Paysystem

From aMember Pro Documentation
Revision as of 08:18, 17 November 2011 by Alex-scott (Talk | contribs)

Jump to: navigation, search

Developing a new payment system plugin is quite easy with aMember Pro v4 once you become familiar with API details. In general, developing a new payment system plugin consists in several parts:

  1. Redirect customer to payment system with correct parameters
  2. Once the customer is returned, show the "thank you" page and (optionally) handle additional parameters payment system sent in return URL

Define payment system plugin

You may use the following payment system plugin template. Put it into application/default/plugins/payment/yourps.php

<?php
// note the class name - it must match filename (but start with upcase letter)
class Am_Paysystem_Yourps extends Am_Paysystem_Abstract
{
    const PLUGIN_STATUS = self::STATUS_DEV; // do not add plugin into production build
    const PLUGIN_REVISION = '@@VERSION@@'; // auto-replaced with production version
 
    const URL = "https://yourps.com/payment.page/url";
 
    protected $defaultTitle = 'YourPS';
    protected $defaultDescription = 'purchase using PayPal or Credit Card';
 
    // here you add elements to HTML_QuickForm2 form with
    // parameters necessary to configure your form
    // saved parameters are available with $this->getConfig('paramname')
    // api call in other plugin functions   
    public function _initSetupForm(Am_Form_Setup $form)
    {
        $form->addInteger('merchant_id', array('size'=>20))
            ->setLabel('Account#');
        $form->addPassword('pass', array('size'=>10))
            ->setLabel('Validation Password');
    }
    /// now lets write payment redirect function 
    public function _process(Invoice $invoice, Am_Request $request, Am_Paysystem_Result $result)
    {
        $a = new Am_Paysystem_Action_Redirect(self::URL);
        // set URL parameter [t] to value of product title 
        $a->t   = $invoice->getLineDescription();
        // set [vp] parameter to total of first subscription payment 
        $a->vp  = $invoice->first_total;
        // set [sp] parameter to total of second subscription payment
        $a->sp  = $invoice->second_total;
        // set [s] to configured [merchant_id]
        $a->s   = $this->getConfig('merchant_id');
        // set [fn] to customer first name
        $a->fn = $invoice->getFirstName();
        // set [sn] to customer last name
        $a->sn = $invoice->getLastName();
        // set [em] to customer email address
        $a->em = $invoice->getEmail();
        // set [ret] to unique, expiring return URL for that invoice
        $a->ret = $this->getReturnUrl();
        // set [lnk] to "cancel" url where customer may choose other payprocessor for this payment
        $a->lnk = $this->getCancelUrl();
        // now return it to core and aMember will do the rest
        $result->setAction($a);
    }
    // let aMember know how this plugin is going to deal with recurring payments
    public function getRecurringType()
    {
        return self::REPORTS_EOT;
    }
 
    public function getReadme()
    {
return <<<CUT
    My payment plugin readme
 
Readme instructions here....
CUT;
    }
 
    public function createTransaction(Am_Request $request, Zend_Controller_Response_Http $response, array $invokeArgs)
    {
        return new Am_Paysystem_Transaction_Yourps_Ipn($this, $request, $response, $invokeArgs);
    }
}

This code makes possible to:

  • enable [yourps] plugin at aMember Cp -> Setup -> Plugins
  • confgure plugin at aMember Cp -> Setup -> YourPS
  • get a working redirect to your payment system when customer chooses it in signup form
  • when customer returned to 'Thank You' page after payment, receipt and welcome words will be automatically displayed

But the plugin does not yet handle mark received payments as paid, and does not make customer active. Lets continue...

Handle IPN posts

Add the following code to the file:

// the following class takes incoming IPN post from your payment system, parses
// it if necessary, checks that it came unchanged, from trusted source, finds
// corresponding amember invoice for it, and adds payment record to the invoice
// it is all what is required to handle payment
class Am_Paysystem_Transaction_Yourps_Ipn extends Am_Paysystem_Transaction_Incoming
{
    public function validateSource()
    {
        // there must be some code to validate if IPN came from payment system, and not from a "hacker"
        return true;
    }
    public function validateStatus()
    {
        // there must be code to check post variables and confirm that the post indicates successful payment transaction
        return true;
    }
    public function findInvoiceId()
    {
        // it takes invoiceId from request as sent by payment system
        return $this->request->getFiltered('invoiceId); 
    }    
    public function getUniqId()
    {
        // take unique transaction id from yourps IPN post
        return $this->request->get('psReceipt'); 
    }
    public function validateTerms()
    {
        // compare our invoice payment settings, and what payment system handled 
        // if there is difference, it is possible that redirect url was modified 
        // before payment
        return ($this->request->get('vp') == $this->invoice->first_total) 
            && ($this->request->get('sp') == $this->invoice->second_total);
    }
}

Once you implement and test this, the plugin will be able to handle IPN posts coming from payment system and plugin will become functional. There are lot more complex cases. Check existing amember payment plugins as examples, and if that is not necessary, do not hesitate to contact CGI-Central staff via helpdesk for explanation.