CiviCRM Community Forums (archive)

*

News:

Have a question about CiviCRM?
Get it answered quickly at the new
CiviCRM Stack Exchange Q+A site

This forum was archived on 25 November 2017. Learn more.
How to get involved.
What to do if you think you've found a bug.



  • CiviCRM Community Forums (archive) »
  • Old sections (read-only, deprecated) »
  • Developer Discussion (Moderator: Donald Lobo) »
  • Payment Processor - PaymentExpress
Pages: [1] 2

Author Topic: Payment Processor - PaymentExpress  (Read 8026 times)

Eileen

  • Forum Godess / God
  • I’m (like) Lobo ;)
  • *****
  • Posts: 4195
  • Karma: 218
    • Fuzion
Payment Processor - PaymentExpress
August 05, 2008, 03:58:04 am
Hello,

I have been looking at developing a payment processor for PaymentExpress (aka DPS) due to me previously expressed feelings about Paypal -the only one currently available for NZ currency. http://www.paymentexpress.com/ covers all the major NZ banks plus several major Aussie banks and banks in the Pacific, Singapore, US & UK.

I have a *few* questions - the first three are about form rather than getting it to work. I assume this will be useful to other people so I'm trying not to make it just a cludge

1)  is http://www.idealso.com/civicrm/AUTHORIZENET_NOTES the latest / most complete guide to writing a payment processor? It is a bit out-of-date & I have a few notes that would update it.

2) PaymentExpress provide a file with their functions in it called  "pxaccess.inc". Where would this most appropriately be placed? In the sites/all/modules/civicrm/CRM/Core/Payment/  folder with the payment processor file or sites/all/modules/civicrm/extern ? I notice that in their documentation they use "include" to load it up but "require_once" seems to be used throughout civiCRM - what is recommended?

3) I'm struggling to work through the maze of dealing with the response. PaymentExpress redirects the user to a url you specify but the url must not contain "?" and "&" signs. It passes back the result as an encrypted hex string which you decrypt using their functions. It passes it back twice to the same url (once with the user & once as an IPN). I'm assuming I should pass these decryped functions to the ipn.php script & re-direct the user to the Thank you page but the ipn.php file doesn't appear to be generic - it directly calls the paypalipn file. Can someone advise the logic path I should follow here.
Make today the day you step up to support CiviCRM and all the amazing organisations that are using it to improve our world - http://civicrm.org/contribute

Donald Lobo

  • Administrator
  • I’m (like) Lobo ;)
  • *****
  • Posts: 15963
  • Karma: 470
    • CiviCRM site
  • CiviCRM version: 4.2+
  • CMS version: Drupal 7, Joomla 2.5+
  • MySQL version: 5.5.x
  • PHP version: 5.4.x
Re: Payment Processor - PaymentExpress
August 05, 2008, 01:03:49 pm

I just added eWay (thanx to peter from dolphin software) to the 2.1 code base. not sure if that will meet your needs.

1. Yes, can you please update and post it on the CiviCRM wiki

2. you should put it in packages/PaymentExpress. I'd use require_once instead of include

3. We've generalized a fair amount of the ipn code in CRM/Core/Payment/BaseIPN.php. CRM/Core/Payment/PayPalIPN.php inherits from this class. I suspect you can use smething similar for DPS

lobo
 
A new CiviCRM Q&A resource needs YOUR help to get started. Visit our StackExchange proposed site, sign up and vote on 5 questions

Donald Lobo

  • Administrator
  • I’m (like) Lobo ;)
  • *****
  • Posts: 15963
  • Karma: 470
    • CiviCRM site
  • CiviCRM version: 4.2+
  • CMS version: Drupal 7, Joomla 2.5+
  • MySQL version: 5.5.x
  • PHP version: 5.4.x
Re: Payment Processor - PaymentExpress
August 05, 2008, 07:58:42 pm
i saw the following in email, but dont see it on the topic any more:

Quote
I think I'm just about there with PaymentExpress and it's a really good payment processor (they reply to my e-mails almost immediately!) so I'll finish it now.

Basically I have a variable in my code that holds the url that paypal ipn uses

e.g. /sites/all/modules/civicrm/extern/ipn.php?reset=1&contactID=274&contributionID=18&module=event&eventID=9&participantID=45

But I want to call this & then redirect the user to a different url (the thank you page in my script). How do I call the line above from my script (as opposed to redirect to it)

Nb - could someone who knew the various IDs in the line above do a man-in-the-middle attack on that url?

Might be easier to chat with over IRC / Skype. You can get on the #civicrm irc channel: http://embed.mibbit.com/?server=irc.freenode.net&channel=%23civicrm&forcePrompt=true

the paypal IPN sends most of the contents via POST, so in addition to the above GET vars there are quite a few otehr variables which we cross check against in the db. Yes an attack is possible, but the attacker will need to guess a few randomly generated ids right along with the amount etc

I also took a a quick look at the DPS docs, and it seems to resemble "paypal express" more than IPN. You might want to base your code off the paypal express code (which is probably not as generic as the other 2 methods)

lobo
« Last Edit: August 05, 2008, 08:04:05 pm by Donald Lobo »
A new CiviCRM Q&A resource needs YOUR help to get started. Visit our StackExchange proposed site, sign up and vote on 5 questions

Eileen

  • Forum Godess / God
  • I’m (like) Lobo ;)
  • *****
  • Posts: 4195
  • Karma: 218
    • Fuzion
Re: Payment Processor - PaymentExpress
August 07, 2008, 08:10:40 pm
Quick question - has the payment processor code changed in 2.1 (apart from including eWay)?

I'm going to start making some notes here on setting up a payment processor in the hope they will be corrected and something worth posting on the wiki will result

Step 1 as I understand it is to add the processor to the table `civicrm_payment_processor_type`
I believe this replaces the first two steps listed here: http://www.idealso.com/civicrm/AUTHORIZENET_NOTES

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

1) For forms civicrm/CRM/Core/Payment/form.php is added to the form displayed by (in events mode) civicrm/CRM/Event/Form/Registration/register.php

This form collects the credit card data on the civicrm site. Communication takes place between the civicrm server and the processor - i.e. the civicrm server sends a request (encrypted) including the credit card and it gets approved or otherwise.

The function called by this billing mode is

doDirectPayment() - 

2) button - a button is added. 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.

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.

4) Notify - in this case the customer is redirected from the confirm page to the payment processor. The result is returned separately to the customer (as a post from the payment processor)

The processor I am setting up I believe to be a better fit with this method as the result is returned as a POST separately from the customer i.e. returnurl?result=encryptedHex. The customer is returned to the same url so the URL must be able to cope with both the post from the customer and the encrypted hex. The customer needs to be redirected to the thank you page whereas the processor just needs an 'OK' reply.

 (there are two different ways to decrypt the hex pxaccess & pxpay - one using an installed lmcrypt module and the other involves interacting with the processor but these are handled by code provided by the processor and don't pose a difficulty).

The function called is

doTransferCheckout

I now need to figure out:
- how to test the return post for whether it is the user or not.
- If the reply is not from the user it needs to use variables passed back from the processor to the IPN script so it can figure out what payment it relates to & confirm it.

I believe the function for a success is
   function completeTransaction( &$input, &$ids, &$objects, &$transaction, $recur = false )
( I may need to call the validate one first)


Objects includes
        $contribution =& $objects['contribution'];
        $membership   =& $objects['membership']  ;
        $participant  =& $objects['participant'] ;
        $event        =& $objects['event']       ;

$input variables from GoogleIPN.php:

       $input['amount']     = $contribution->total_amount;
        $input['fee_amount'] = null;
        $input['net_amount'] = null;
        $input['trxn_id']    = $orderNo;
        $input['is_test']    = $contribution->is_test;

NB - GoogleIPN seems to check whether the contribution has already been confirmed - I expected to find this in the BaseIPN

but I still need to investigate further what else to pass through

Work in progress
« Last Edit: August 08, 2008, 10:29:47 pm by Eileen »
Make today the day you step up to support CiviCRM and all the amazing organisations that are using it to improve our world - http://civicrm.org/contribute

Chris Burgess

  • Ask me questions
  • ****
  • Posts: 675
  • Karma: 59
Re: Payment Processor - PaymentExpress
August 10, 2008, 08:00:22 pm
hey Eileen

Here we are, implementing separate processors for NZ payment gateways. Madness. Unfortunately I've been instructed to get Web2Pay working this week and can't co-operate with you on yours!

But we can co-operate by documenting the process of making a gateway - I'd love it if I could see your notes on making a payment gateway, and share my experiences with you too.

I'm taking notes on my experience and documenting any gaps in the existing docs here:

 * http://forum.civicrm.org/index.php/topic,4306.0.html

If you want to peer on this, I'm on Skype or #civicrm (Skype username == my forum name here, xurizaemon)
« Last Edit: August 10, 2008, 08:16:05 pm by xurizaemon »
@xurizaemon ● www.fuzion.co.nz

Eileen

  • Forum Godess / God
  • I’m (like) Lobo ;)
  • *****
  • Posts: 4195
  • Karma: 218
    • Fuzion
Re: Payment Processor - PaymentExpress
August 10, 2008, 09:17:44 pm
Hi there,

Yep, will try to when the kids are in bed. I am 90% there. It works but I have to do some more testing.
Make today the day you step up to support CiviCRM and all the amazing organisations that are using it to improve our world - http://civicrm.org/contribute

lucasbaker

  • I’m new here
  • *
  • Posts: 17
  • Karma: 0
Re: Payment Processor - PaymentExpress
August 12, 2008, 10:01:51 pm
Hello.

I, too, have been tasked with writing a DPS payment module for CiviCRM, which has presented a number of challenges.

Eileen, you mentioned that you were having difficulty with the return redirect back to CiviCRM from DPS.  I've had issues with this as well.  Unfortunately, DPS attaches additional information to the URL it sends back to the server, which causes a few headaches when trying to process the information.

My solution is to write a seperate page to parse the incoming URL, filter out the extra information from DPS, and properly redirect to the "thank you" page.  It's not elegant, but it will serve the purpose.

I'd really like to try something a bit more "integrated" with the module.  Have you made any breakthroughs with this?

Regards,
Lucas

Donald Lobo

  • Administrator
  • I’m (like) Lobo ;)
  • *****
  • Posts: 15963
  • Karma: 470
    • CiviCRM site
  • CiviCRM version: 4.2+
  • CMS version: Drupal 7, Joomla 2.5+
  • MySQL version: 5.5.x
  • PHP version: 5.4.x
Re: Payment Processor - PaymentExpress
August 12, 2008, 10:25:11 pm

i assume DPS is the same as paymentexpress that eileen is working on? Since the 4 of us are in NZ, might be easier to coordinate and figure out how to get the PP's working and into the 2.1 codebase. I'm on IRC if you'll need help or assistance :)

Would be good to create a manual for "how to write a payment processor" for civi 2.x

lobo
A new CiviCRM Q&A resource needs YOUR help to get started. Visit our StackExchange proposed site, sign up and vote on 5 questions

Eileen

  • Forum Godess / God
  • I’m (like) Lobo ;)
  • *****
  • Posts: 4195
  • Karma: 218
    • Fuzion
Re: Payment Processor - PaymentExpress
August 13, 2008, 12:31:18 am
Lucas, have you been using pxpay or pxaccess?

I've been using pxaccess (the one that needs lmcrypt installed).

I was working from the google script. I had copied from the google script to package up the $privatedata and $return_url and was passing that to the payment processor and then using functions mostly from the google script to use it on return. However, the resulting URL is too long for IE to redirect back to so. I can get all the data in there - just not in the format that I had copied.

So, I thought I would pick apart the return script into 2 sections - one that gets the variables from the reply and the second one would receive those variables and complete the transaction and return the correct url for re-direction. Thus the second one would be more generic.

NB - I have hacked up my script so it does work but I'm just having trouble constructing the return url from the qfkey. This is the code from the google one:

   
Code: [Select]
if ( $component == "event" ) {
            $returnURL = CRM_Utils_System::url( 'civicrm/event/register',
                                                "_qf_ThankYou_display=1&qfKey={$params['qfKey']}",
                                                true, null, false );
        } elseif ( $component == "contribute" ) {
            $returnURL = CRM_Utils_System::url( 'civicrm/contribute/transact',
                                                "_qf_ThankYou_display=1&qfKey={$params['qfKey']}",
                                                true, null, false );
        }

but the userframework class seems to be different if I try this on return & it doesn't work. (somehow my whole site broke but even phpinfo.php won't load I think the php service has fallen over - cross fingers it will be happy in the morning.

I am successfully confirming transactions although it's a bit ugly at the moment. I would attach my code but can't add a .zip. Am sometimes available on skype - eileen.mcnaughton
« Last Edit: August 13, 2008, 04:01:56 am by Eileen »
Make today the day you step up to support CiviCRM and all the amazing organisations that are using it to improve our world - http://civicrm.org/contribute

lucasbaker

  • I’m new here
  • *
  • Posts: 17
  • Karma: 0
Re: Payment Processor - PaymentExpress
August 13, 2008, 10:54:57 am
Good morning, all.

First, yes, Donald, DPS and Payment Express are one and the same.  :)

Second, Eileen, I am using PxPay and have had success right up to the point where the payment processor redirects back to the server.  I also started with the Google script, but have modified it somewhat (adding in a few functions to build the XML string I need to pass to the server in order to generate a request, etc.). I initially met challenges with the DPS/Payment Express server since they won't allow anything except absolute URLs to be passed to the server in the successURL and failURL XML elements, so I added a couple of rewrite rules to the server and modified the URLs I was passing so that they didn't contain any "?" or "&" characters.

I am now able to complete a transaction with the payment processor.  However, upon redirect back to the server, I am always landing back on the initial contribution form, with all of my information prepopulated (which means it is obviously retrieving the qfKey, but that my Apache rewrite rules aren't working properly because of the rather lengthy string being attached to the end of the URL from the DPS/Payment Express server (which contains the encrypted transaction results)).

So, as I mentioned in my previous post, I am left with the option of adding in a new script outside the current module to parse the incoming URL and then redirect it manually to the correct page.  It's not ideal, as I would like to have the solution integrate completely, but it doesn't seem to be working.  Even adding rewrite rules to the server isn't ideal, but it does get me to the goal of having a working module that much quicker (I'm working under a deadline at the moment.  ;)).  But, adding rewrite rules isn't an option for everyone who could use this module.  Ultimately, I want the module to tie into CiviCRM without requiring any "tweaking" on the server or extra scripts, but, at the moment, DPS/Payment Express has some pretty stringent requirements which make that a tad difficult to achieve.

I, too, am on Skype most days - lucasbaker. 

Happy to hear any thoughts anyone might have about this.  I am pretty close to rigging up a solution that works, but, before calling this a "working" module, I'd like to tie up all the loose ends.

Regards,
Lucas

Eileen

  • Forum Godess / God
  • I’m (like) Lobo ;)
  • *****
  • Posts: 4195
  • Karma: 218
    • Fuzion
Re: Payment Processor - PaymentExpress
August 13, 2008, 11:32:36 am
So, you're really stuck at the same point I am - the best way to re-direct the user's browser at the end.

I was trying to re-construct the url using the bit of script I pasted in but it worked in the original context (i.e. before being forwarded to DPS) but not on return and I think it relates to setting these variables correctly (taken from /extern/ipn.php

$config->userFramework          = 'Soap';
$config->userFrameworkClass     = 'CRM_Utils_System_Soap';
$config->userHookClass          = 'CRM_Utils_Hook_Soap';
Make today the day you step up to support CiviCRM and all the amazing organisations that are using it to improve our world - http://civicrm.org/contribute

Donald Lobo

  • Administrator
  • I’m (like) Lobo ;)
  • *****
  • Posts: 15963
  • Karma: 470
    • CiviCRM site
  • CiviCRM version: 4.2+
  • CMS version: Drupal 7, Joomla 2.5+
  • MySQL version: 5.5.x
  • PHP version: 5.4.x
Re: Payment Processor - PaymentExpress
August 13, 2008, 11:37:39 am

lucas:

check: CRM/Contribute/Form/ContributionBase.php, line 264

there is a hack for paypal there (CRM/Core/Payment.php, function paypalRedirect). Since paypal in some cases does not send us back the return url but makes its own url!

will adding a similar hack for DPS work? If so, we can make this hack a virtual function for each payment processor and allow the payment processor code to decide if we need to redirect to the thankyou page

lobo
A new CiviCRM Q&A resource needs YOUR help to get started. Visit our StackExchange proposed site, sign up and vote on 5 questions

lucasbaker

  • I’m new here
  • *
  • Posts: 17
  • Karma: 0
Re: Payment Processor - PaymentExpress
August 13, 2008, 02:30:30 pm
I've looked over the code a bit more and I keep coming back to some basic snags (maybe I'm not seeing the forest for the trees), however - here are the hang-ups in the process with DPS:

1.  We cannot send a returnURL to DPS which includes a query string. All URLS must be absolute.
2.  CiviCRM requires some information back from the payment processor in order to complete the transaction.
3.  DPS appends their own long querystring to the end of any URL you provide to them.

So, regardless of the approach, I might use for this, I keep coming back to some kind of URL rewriting.  We have to be able to send back some information.  Yet, any time I try to enable a rewrite rule, I am sent right back to the main display page on the form.

It's quite frustrating.  But, again, it could just be forest and trees syndrome.  :)

Regards,
Lucas

Eileen

  • Forum Godess / God
  • I’m (like) Lobo ;)
  • *****
  • Posts: 4195
  • Karma: 218
    • Fuzion
Re: Payment Processor - PaymentExpress
August 13, 2008, 03:41:20 pm
Am at our business now so not on skype or on the computer with my stuff on it but I passed a few variables through paymentexpress back to myself in the encrypted code.

I think I set dpsref1 to something like
a=contactID,b=contributionID,c=contributionTypeID,d=eventID,e=particpantID
(the variable names were originally longer but they made the URL too long).
dpsref2 was the qfkey

In my PaymentExpressIPN file I extracted these from the hex file (along with InvoiceID,& used functions based on the googleIPN file main() and newOrderNotify() to re-construct the order details from the hex file. My code does go as far as confirming the order within CRM and triggering the e-mail - I just haven't constructed the correct url to re-direct the user's browser to the thank you page yet

I can access that mibbit from here http://embed.mibbit.com/?server=irc.freenode.net&channel=%23civicrm&forcePrompt=true

I'm not sure how different the process is for pxpay though
Make today the day you step up to support CiviCRM and all the amazing organisations that are using it to improve our world - http://civicrm.org/contribute

lucasbaker

  • I’m new here
  • *
  • Posts: 17
  • Karma: 0
Re: Payment Processor - PaymentExpress
August 13, 2008, 09:15:20 pm
Well, here is where things stand, as of this afternoon.

I have a working solution with DPS/Payment Express and CiviCRM.  It works with PxPay.

There is, however, a tradeoff.  Since this is a hosted payment page and since Payment Express uses a convoluted workflow for generating and validating transactions to it's servers, I've had to make some concessions to make it work.

I'll begin with a basic description of the DPS workflow for the PxPay system:

1.  The e-commerce website application must generate a valid XML-formatted request, which includes the username/key provided by DPS, the basic payment information (i.e. amount, transaction type, etc), the URLs to redirect to in the event of success or failure of a transaction), three fields which contain extra data specific to the e-commerce web application (these are optional) and few other bits and pieces and send this XML request off to the DPS web server, where it is validated and a custom, encrypted URL is returned to the e-commerce website application, embedded within a response XML stream.

2.  Using the custom URL provided in the response XML stream, the e-commerce website then redirects to the DPS hosted payment page, where the customer may enter in his or her credit card details for validation.

3.  Upon submission of their details, a success or failure screen is presented to the customer (still on the DPS web server) as well as a button which links back to the original e-commerce web application.  This link has a long encrypted hash attached to it which contains the complete results of the transaction including approval code, merchant id, the extra data provided in the original request XML document, etc as well as the DPS userid on the very end of the query string.  Considering that this is an encrypted string, the more information that is input into it, the longer the string will be.

4.  The encrypted querystring is passed back to DPS in the form of another XML Request so that it may be decrypted and all of the information within it made available to the e-commerce web application.

5.  The e-commerce web application displays the appropriate success or failure page to conclude the transaction.

It is with this long URL that comes into play in Step 3 that the issue becomes a bit more than just a nuisance.  As many of you may know, Internet Explorer automatically truncates URLs that are over a certain length.  Because of this, the long URL with the hash attached in the querystring is too long when we pass through all of the private data along with the transaction information.

I contacted DPS and their answer is that there is no work around for this issue except to pass in less data in the original request.

Soooo...this left me with no option but to pass through the minimal set of information I was going to require to complete the payment transaction and direct the customer back to the correct "thank you" page.  Namely, the qfKey and the component information.  As long as I limit passing only that information along to DPS, the generated URL is short enough to be recognized as valid by Internet Explorer.

At this point, my "in place" solution seems to be doing the job.  But, I think further work is needed to refine it. Additionally, the inclusion of the PxAccess functionality would also be beneficial.  So, I plan to continue work on this to get it a bit more refined. 

I've managed to get things working enough for my purposes, but I'm sure it can be improved.  Still...I've been pulling long hours this week to get to this point, so I'm taking a bit of a break for the next short while.  I will check in again soon.  Will be glad to share my code with anyone who wants to review it.

I've had to bypass some steps which relied on the presence of private data, but it does seem to be working.

That's the story from my side of the hill...at the moment.

Regards,
Lucas

Pages: [1] 2
  • CiviCRM Community Forums (archive) »
  • Old sections (read-only, deprecated) »
  • Developer Discussion (Moderator: Donald Lobo) »
  • Payment Processor - PaymentExpress

This forum was archived on 2017-11-26.