This documentation refers to CiviCRM 3.2, current stable version. Please introduce all the documentation changes here.

Creating Additional Payment Processor Plugins


This page refers to CiviCRM 3.2.


Documentation Search


CiviCRM 3.2 Documentation

Support and Participation

Developer Resources


CiviCRM book!
Make sure to check out Understanding CiviCRM as well! You can also support this project by ordering a hard copy.
Guidelines for Developing Payment Processor Plugins
CiviCRM has a plugin architecture for integration of payment processors/gateways. The core team has built plugins for PayPal Pro, PayPal Express, PayPal Web Payments Standard with IPN, and Google Checkout. JMA Consulting (Joe Murray) sponsored Alan Dixon to build and contribute a plugin for Moneris. Marshall Newrock for Ideal Solutions contributed a plugin for Authorize.net. Eileen and Lucas collaborated to contribute a plugin for DPS PaymentExpress and also wrote this document. Eileen wrote the Payment processors for FirstData, Elavon and PayflowPro - which are in the core as of v 3.1. Peter Barwell wrote eWay. We welcome/invite other developers to build and contribute additional plugins - and add tips/guidelines to ease the process on this page.

Understand the processor you are setting up

You need to check your processor's documentation and understand the flow of the processor's process and compare it to existing processors (I intend that people should add descriptions of existing ones at the end of this wiki entry to assist with this)

Factors you should take note of are:

  • Does your processor require the user to interact directly with forms/pages on their servers (like PayPal Express), or are are data fields collected by CiviContrib form and submitted "behind the scenes"?
  • What fields are required?
  • What authentication method(s) are used between Civi and the payment processor servers?
  • In what format is data submitted (soap/xml, arrays...)?
  • What are the steps in completing a transaction (e.g. simple POST and response, vs multi-step sequence...). Are transaction results returned real-time (PayPal Pro/Express and I think Moneris) - or posted back in a separate process (PayPal Standard w/ IPN)?

Note that None of the plugins distributed with CiviCRM use a model where the donor's credit card info is stored in the CiviCRM site's database. For PayPal Pro, Authorize.net and PayJunction - Credit card numbers, exp date and security codes are entered on the CiviCRM contribution page and immediately passed to the processor / not saved. For PayPal Std, Google Checkout - the info is entered at the processors' site.

Determine what 'type' of processor you are dealing with.


Figuring this out will set you on the right track. In CiviCRM there are three 'billing types':


  • form - a form is where the credit card information is collected on a form on your site and submitted to the payment processor
  • button -  As I understand it buttons rely on important information (success, variables etc) being communicated directly between your server and the payment processor. (e.g. in the paypal express method. the customer is transferred to the server to enter their details but the transaction is not pushed through until an html request is sent from your server to the processor and the server replies with the response. The server also uses html to query certain variables from the server.  From what I remember CURL is used for this.) The user's session remains intact but I'm not sure if session variables or variables sent from the payment processor are used to identify the transaction and customise what the user sees
  • notify - the notify method deals with a situation where there is not a direct two way communication between your server and the processor and there is a need for your server to identify which transaction is being responded to. This was the method I worked with (and seemingly most people who were looking at it at the same time). The payment processor I worked on sends two confirmations - one html GET via the user's browser and a later html GET from the payment processor server. If the user's browser never returns the processor needs to be able to figure out which transaction is involved & to complete it. If the GET is from the user's browser it needs to do the same thing but also redirect the user appropriately. My notes will speak predominantly to this method

  • Add the processor into the processor_types table

  • Add a line to `civicrm_payment_processor_type` - eg. using php myadmin or mysql
  • Fields are:
    ID   - unique ID
    DomainID - generally 1
    Name - this name needs to be used as the name for the various php files as well.
    Description (optional field)
    Isactive  - boolean
    Isdefault - boolean
    user_name_label - this is what the username field is described as in the configure payment instruments screen
    password_label - likewise
    signature_label
    class_name - name of class (in code) should be Payment_xxx where xxx is the same as the name field
    various selfexplanatory url fields & then
    BillingID - number from 1-4 - this is the important one - will add more later
    Isrecurr - boolean

The BillingID will determine the process followed. ID types are:
1 = form
2 = button
4 = notify

Curiously although 2 is defined as button in the payment.php script no processors in the processor_type table use type 2 and payment express uses type 3 which seems to have the button functionality. This method seems fairly hard coded to paypal e.g.

 Store any function files from your payment processor

Create an appropriately named folder in the 'packages' directory for any files provided by your payment processor which have functions you need

 Create files in the components for your processor

There needs to be a file for your processor in CRM\Event\Payment and in CRM\Contribute\Payment. The name needs to be the same as the name you inserted into the processor_types table. These are pretty easy to copy from others as they don't have much in them.

 Write your processor

OK, the groundwork is laid but writing the processor is the hard bit.

Depending on your billing mode there are different considerations - I have less information and it is less checked on the first two. The file will live in CRM\Core\Payment and have the same name as entered into your processor_type table.

Test your processor

Some suggestions of what you might test are here

http://wiki.civicrm.org/confluence/display/CRMDOC/Testing+Processor+Plugins

Form mode

The function called by this billing mode is

doDirectPayment()

If you return to the calling class at the end of the function the contribution will be confirmed. Values from the $params array will be updated based on what you return.  If the transaction does not succeed you should return an error to avoid confirming the transaction.

The params available to doDirectPayment() are: -

qfKey -

email-(bltID) -

billing_first_name (=first_name)

billing_middle_name (=middle_name)

- billing_last_name (=last_name)

- location_name-(bltID) = billing_first_name + billing_middle_name + billing_last_name

- streeet_address

-(bltID)

- city-(bltID)

- state_province_id-(bltID) (int)

- state_province-(bltID) (XX)

- postal_code-(bltID)

- country_id-(bltID) (int)

- country-(bltID) (XX)

- credit_card_number

- cvv2 - credit_card_exp_date - M - Y

- credit_card_type

- amount

- amount_other

- year (credit_card_exp_date => Y)

- month (credit_card_exp_date => M)

- ip_address

- amount_level

- currencyID (XXX)

- payment_action

- invoiceID (hex number. hash?)

bltID = Billing Location Type ID. This is not actually seen by the payment class.

Button Mode


the function called by this billing mode is

setExpressCheckout

The customer is returned to confirm.php with the rfp value set to 1 and

getExpressCheckoutDetails

is called

when the form is processed

doExpressCheckout is called to finalise the payment - a result is returned to the civiCRM site.

 Notify mode

 The function called is

doTransferCheckout

 The details from here are processor specific but you want to pass enough details back to your function to identify the transaction. You should be aiming to have these variables to passthrough the processor to the confirmation routine:

contactID

contributionID

contributionTypeID

invoiceID

membershipID(contribution only)

participantID (event only)

eventID (event only)

component (event or contribute)

qfkey

Handling the return was the tricky part.

In order to keep the return url short (because paymentexpress appends a long hex string) our return url goes to a file (in the extern folder ) which redirects through to the 'main' routine in paymentExpressIPN.php (IPN = instant payment notification). I have stuck a copy of the framework of it as an attachment to this post

note - you need to  re-initialise the environment to get civi functions to work

require_once '../civicrm.config.php';
require_once 'CRM/Core/Config.php';

$config =& CRM_Core_Config::singleton();

 An appropriate structure for the return routine file is:

function newOrderNotify( $success, $privateData, $component,$amount,$transactionReference ) {

        $ids = $input = $params = array( );

this version in the paymentexpress file is not processor specific - pass it the variables above and it will complete the transaction. Success is boolean, the private data array holds, the component is (lower case) 'event' or 'contribute' , amount is obvious, transaction reference is any processor related reference.

contactID, contributionID, contributionTypeID,invoiceID, membershipID(contribution only), participantID (event only), eventID (event only)

static function getContext( $privateData, $orderNo)

generic function - taken from google version - retrieves information to complete transaction (required?)

private data as above

orderno - transactionreference is OK

Static function main(blah, blah,  blah)

this function is processor specific - it  converts whatever form your processor response is into the variables required for the above function and if necessary redirects the browser using

CRM_Utils_System::redirect( $finalURL );

Information about existing Payment processors


Describe them here so people can see if they are good matches.....

Google Checkout doesn't support recurring payments nor concurrent multiple payments (as of April 16, 2009).

(It would be great if a matrix of Payment Processor Features could be included in the Civi documentation.)


Enter labels to add to this page:
Please wait 
Looking for a label? Just start typing.

Creative Commons License
Except where otherwise noted, content on this site is licensed under a Creative Commons Attribution-Share Alike 3.0 United States Licence.