Latest revision as of 02:38, 25 February 2017

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:

Redirect customer to payment system with correct parameters

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 buildconst PLUGIN_REVISION ='@@VERSION@@';// auto-replaced with production versionconst 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 publicfunction _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 publicfunction _process(Invoice $invoice, Am_Mvc_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 paymentspublicfunction getRecurringType(){returnself::REPORTS_EOT;}publicfunction getReadme(){return<<<CUT
My payment plugin readme
Readme instructions here....
CUT;}publicfunction createTransaction(Am_Mvc_Request $request, Am_Mvc_Response $response,array$invokeArgs){returnnew 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 paymentclass Am_Paysystem_Transaction_Yourps_Ipn extends Am_Paysystem_Transaction_Incoming
{publicfunction validateSource(){// there must be some code to validate if IPN came from payment system, and not from a "hacker"returntrue;}publicfunction validateStatus(){// there must be code to check post variables and confirm that the post indicates successful payment transactionreturntrue;}publicfunction findInvoiceId(){// it takes invoiceId from request as sent by payment systemreturn$this->request->getFiltered('invoiceId');}publicfunction getUniqId(){// take unique transaction id from yourps IPN postreturn$this->request->get('psReceipt');}publicfunction validateTerms(){// compare our invoice payment settings, and what payment system handled // if there is difference, it is possible that redirect url was modified // before paymentreturn($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.