artfulrobot / uk.artfulrobot.civicrm.gocardless

A CiviCRM extension providing GoCardless integration to handle UK Direct Debits.
GNU Affero General Public License v3.0
5 stars 18 forks source link

Extension does not work with CiviCRM Webforms with Contribution page #32

Open PJKerrigan opened 6 years ago

PJKerrigan commented 6 years ago

I am using civicrm_webform (7.x-4.19) in Drupal (7.52) and have a webform which uses a Contribution page on CiviCRM 4.7.30.

The GoCardless payment processor fails with the following notice:

Notice: Undefined index: description in CRM_Core_Payment_GoCardless->doTransferCheckoutWorker() (line 122 of /var/www/vhosts/my.site/dev/sites/all/extensions/uk.artfulrobot.civicrm.gocardless/CRM/Core/Payment/GoCardless.php).

I have tried to simply set the $params['description'] value by hard-coding it, but that led to the following error being displayed:

We can't load the requested web page. This page requires cookies to be enabled in your browser settings. Please check this setting and enable cookies (if they are not enabled). Then try again. If this error persists, contact the site administrator for assistance.

Error type: Could not find a valid session key.

I'm guessing that the description is used to create the session key, so changing it in CRM_Core_Payment_GoCardless::doTransferCheckoutWorker breaks it.

Does anyone have any ideas? Thanks.

artfulrobot commented 6 years ago

description is passed into the "redirect flow" (in GC you set one up, get a special URL to send the user to, then they come back to you and you have to refetch the redirect flow object from GC to complete the processing) and its existence is checked for on completion of the redirect flow.

(You should have been killed by an exception not the notice, patched that)

The description is used for the subscription's 'name' parameter, which is later used by GC as the public-facing 'description' for each payment. GC docs

This extension does require it. However I don't think it's your issue; I think manually setting it should work.

The session is handled by CiviCRM; I don't think the description is used. The quickform key, however, is used as a GC session token, which may be related. I've not actually tried this with webform, so I'm not familiar with the issues.

Could that be something else? When do you see that error - when presenting the webform, or when submitting the webform, or after having completed the off-site GC page?

PJKerrigan commented 6 years ago

Thanks for your quick response!

The error occurs after I've entered all of my details into GoCardless. It redirects me back to my site and displays that CiviCRM error message. White screen and the "We can't load the requested web page. This page requires cookies..." message.

Without setting the description manually, it just attempting to go to GoCardless and redirects to /civicrm.

I'll keep trying as it looks like I'm in the right area. Cheers!

artfulrobot commented 6 years ago

Hmmm.

The redirect page is set at https://github.com/artfulrobot/uk.artfulrobot.civicrm.gocardless/blob/master/CRM/Core/Payment/GoCardless.php#L111

So if it's not for an event, it's the generic contribute/transact. But note the qfKey is here - is that in use in a webform context?

reswild commented 6 years ago

I'm using this extension with civicrm_webform + a bit of custom code to set up the payment instead of using a CiviCRM Contribution page, and I had to hack the GoCardless.php page referred to above in order to insert a custom redirect to my own page instead of to the CiviCRM contribute/transact page.

So if you get really stuck, I could share my code with you, but it's a bit of an ugly hack, so you are probably better off if you can figure out how to do it the regular way.

The qfKey should be there also in a webform context, so it might only be a question of how to pass it onto the GoCardless extension.

artfulrobot commented 6 years ago

I wrote the extension so that it could be driven without contribution pages (which I never use, preferring a more custom and streamlined UX). So the methods to create a flow are available without using quickform (I am on a personal mission to rid CiviCRM of quickform!). @reswild I'd be interested in seeing your hack.

PJKerrigan commented 6 years ago

Would it be possible to get a look at your hack, please, @reswild? It could help a lot!

I'm not very familiar with CiviCRM yet, enough to solve this. I'm more Drupal oriented, so I'm not entirely sure whether this is the problem. Looking at the code, I'm inclined to agree that the description changing shouldn't be causing the problem with the session.

I've checked the resource URLs, base URLs in settings.php files, directories, cleared caches, etc, after other people with similar problems. But I can login to the site fine, so it doesn't seem like all sessions are broken. Just in this case.

reswild commented 6 years ago

I can upload my custom module to my GitHub account later this weekend - I just need to clean up the code a bit first.

When you use contribution pages with webform_civicrm, I believe they are just loaded through javascript, so your session isn't set the same way as when you use the contribution page from within CiviCRM. So you might need to go through a couple of extra steps in order for the qfKey to work correctly.

artfulrobot commented 6 years ago

@reswild ah, that makes perfect sense.

PJKerrigan commented 6 years ago

In the mean time we're just going to go with a modified Contribution page instead of the webform.

It would be good to look at your code, though. Cheers.

PJKerrigan commented 6 years ago

I'll be looking at this again over the weekend, as I'd love to finally solve it! It's been eating at me.

artfulrobot commented 6 years ago

This might help.

The process is

  1. create a 'GC redirect flow'.

    • This requires a session token of some sort which is passed into the create call and stored by GoCardless. It must also be kept by the CiviCRM server in session -see point 4.
    • It also requires a redirect URL.
  2. send user off to the GC site to set up the mandate. User submits GC form.

  3. GC tells user to redirect to the redirect URL you supplied in (1), appending the redirect flow ID as GET data.

  4. The CiviCRM server handles the redirect URL, extracts the redirect flow ID and calls GC to ask for the redirect flow object. It must then compare the token stored in the retrieved object with the token stored in session data in (1)

  5. The CiviCRM server then completes the redirect flow and sets up the subscriptions etc. and finally gives the user some thank you page.

Sounds like the problem is that the session token stored in (1) is not available when using webform in (4). Over to you to find out how webform and CiviCRM work together with session storage there!

As an alternative, you don't have to use CiviContribute's contribution pages. You can call the methods on GoCardlessUtils directly yourself, call getRedirectFlow() and store what's needed on your session, then make your own callback (or hook into a webform page) to call completeRedirectFlowWithGoCardless.

hope this helps, Rich

TomCrawshaw commented 6 years ago

Hi @reswild, did you get round to uploading your hack?.. I've got the same issue, and would love to be able to get webform working with GoCardless.

reswild commented 6 years ago

Yeah, sorry, I did look through my custom GoCardless module, but there was a lot of unrelated code there that I wanted to clean up first, and then I never got around to it. I'll see if I can set aside some time for this next week.

TomCrawshaw commented 6 years ago

Thanks for this. Looking forward to seeing your fix, but if you just want to let me have the "messy" version that's ok!

TomCrawshaw commented 6 years ago

Hi @reswild, did you get a chance to look at this? Although my coding isn't up to creating a webform/GoCardless solution from scratch, I might be able to use yours as a basis if I could see it please. Best wishes.

reswild commented 6 years ago

Yeah, I'm actually doing some work on my GoCardless integration this summer - my code is a bit of a mess at the moment, but I'll try to get something added to a public repo so you can have a look at it. I will also try to rewrite some of the code so it can be committed here (like support for Euro payments and pre-filling of customer data in gocardless.com).

Upperholme commented 5 years ago

Would love to see this working with webform_civicrm - just to add my vocal support.

artfulrobot commented 5 years ago

If you have a client who needs this I would be happy to do an estimate.

adshill commented 5 years ago

@artfulrobot Rich how much development would we be looking at to get this working with webform module? We need to migrate a site from the Veda extension but it uses webforms.

artfulrobot commented 5 years ago

@adshill I'm not sure. It's potentially a small change (to do with storing form keys in the session, and identifying a different redirect URL after completion of the redirect flow), but I need to find out exactly what's going on wrt webform compared to the normal civi proceses. It's at least 4-6 hours unless I get lucky ;-) If interested, drop me an email.