Skip to content

Change log


  • 🐞 Require CiviContribute since without it things crash. (Thanks @ufundo for code.)

  • 💡 Re-implement falling back to other addresses (and phones and emails) choosing: billing location as first choice, then primary, and if neither of those, just the first other one given. This restores pre 2.0.0 behaviour. (Thanks @wmortada for funding.)

  • ⚙️ Implement supportsBackOffice(), supportsMultipleConcurrentPayments() and getPaymentFormFields() methods so that the class is no longer dependent on the interpretation of billing_mode by CRM_Core_Payment. This is a non-functional change.

  • ⚙️ Implement successUrl and cancelUrl; if these are set then they will be used as the return URLs. If unset then it behaves as before; generating its own URL for events/contribution flows. (setSuccesUrl() is used by WebForm.)

  • ⚙️ Implement CIVI_GOCARDLESS_FORCE_SANDBOX_ENVIRONMENT for development/testing. e.g. put the following in you civicrm.settings.php file


and now all calls to the GoCardless API will use the sandbox environment. Use of this will break your live payment processing; it is only for development use! This was added to support testing of WebForm which does not support test-mode payment processors, so by setting this constant and putting your test API secrets in the Live fields on the Payment Processor you can get it to do sandboxed payments.


This has been tested against CiviCRM 5.70 which has a bug that prevents some contributions from being entered from webhooks. Assuming you're using "Payment Shared (mjwshared)" to queue webhooks, take a look at your logs (Administer » CiviContribute » Payment Processor Webhooks) if you see lots of errors with:

FAILED: Had to skip webhook event. Reason: Expected one Contribution but found 0

then the bug has affected you, and this version should help. Installing this version should protect you from those failures in future. To fix the past ones, there's a script at cli/fix-issue-141.php that you could consider running from the command line, if you have that level of access. If you want to use the script, please do read it first, and of course, take backups. It can't solve all the problems but on one site it fixed over 90% of about 300 of them.

If you want to reprocess those webhook errors manually, it's a case of finding the payment ID (begins PM...) from the failed webhook's details, searching for it in a contribution's trxn_id (Transaction id) field: you should find it and it should be Pending. If so, you can delete it, and then click retry on the webhook. The webhook will be processed on the next cron run and hopefully then succeeds.

Details of the bug at issue/141 and the chat linked to from there.

If you're not seeing these errors, then you don't need to upgrade - it's unclear exactly what circumstances lead to the bug exhibiting. But upgrading from 2.0.0 should be safe and trouble free anyway as long as you're on 5.70+


Breaking changes for customisations

If you have built any special processes around this extension, especially if you have used any hooks it provides in a custom extension, read on, this could be a breaking change for you. If you are just using the extension without any custom hacks, then this upgrade should be straight-forward, boring - almost - and trouble free.

Changes everyone installing this should know about.

GoCardless deprecated their 'Redirect Flow' API. This means that new GoCardless customers can't use it (so can't use this CiviCRM extension to take new subscriptions), and that at some unspecified time in the future (as of Jan 2024), this API will be withdrawn from current customers.

Version 2 of this extension sidesteps to using their replacement API, called 'Billing Requests'. The user experience is pretty much identical for the standard Contribution Pages, but there are some improvements behind the scenes, and it also offers a much improved UX for other extensions (like Inlay Pay) to implement.

  • 🐞 Previously, the cancel_date was not set on the recurring contribution. For cancellations that come in after this version is installed, this will be set as well as end_date. If you want to correct past data, you can do an API4 call: GoCardless.fixCancelsPreV2 which will look for affected recurs and update them. Note that if you have any triggers/CiviRules on cancel_date on recurs, they will fire!

  • 🐞 Previously, a failed payment that came in after a subscription was cancelled would set the recurring contribution back from Cancelled to Overdue. This no longer happens; cancelled stays cancelled. If you want to correct past data, you can do an API4 call: GoCardless.fixCancelsPreV2 which will look for affected recurs and update them. Note that if you have any triggers/CiviRules on cancelling recurs, they will fire!

  • 🐞 Drupal 10 bugfix: This version (as with 1.14 which was never released) removes the custom logger which caused trouble in composer application environments like Drupal 10. Thanks to @Tony_Horrocks for reporting and to @ufundo for testing that this does fix. See

  • 💡 The optional Tagged Log extension may be useful to you if you spend any time using your logs to troubleshoot awkward cases. If you are developing for this extension and wish to use the phpunit tests, you'll need to install this extension. It is not required for just using this extension in a normal way. The Tagged Log extension builds on the ideas previously implemented in this extension, but which are now removed, the main advantage being that you can easily extract a particular thread of log messages from among others generated by separate requests.

  • ⚙️ We now store the day of month in the recurring contribution's cycle_day field. This will be 0 for don't care (subscriptions will start ASAP), 1-28 for a specified day, or magic value 32 meaning last day of month.

  • 📚 The documentation has been checked and updated, but if you've read this notice then there's no need to go back through it all unless you're really bored.

Changes that only developers and other technically enquiring minds need to read.

  • ⚙️ Custom integrators: This version supports future start dates. You can’t specify this as part of the normal Contribution Pages, but custom integrations could. Simply create the ContributionRecur with a future start_date before calling createBillingRequest().

  • ⚙️ The recurring contribution's processor_id field will now temporarily store a Billing Request ID (BRQ...). This exists from the moment the user clicks the contribute button until they successfully complete the mandate set-up, at which time it is swapped out for the subscription ID (SB....), as before.

  • ⚙️ Instant Payment support, with fallback. Not used by CiviContribute, but used by InlayPay

  • ⚙️ New CLI script, run with cv scr cli/lookup-id.php <GOCARDLESSID> uses the API to lookup Billing Request, Customer, Subscription, Mandate, Payment IDs. For investigation purposes.

  • ☑️ many tests updated/rewritten.


Fixes 1p error that could arise with certain amounts. See Thanks @pradeep for reporting.

Updates GoCardless library to 4.28.0. This is the last version that supports php 7.4

Updated core requirement to 5.63 due to security updates.


Prior to this release, using the admin UI to change the Campaign or Financial Type (but not the amount) on a recurring contribution would fail. Thanks @wmortada for reporting and testing the fix.


1.13.0 caused crashes on out of date systems running PHP 7.3. This version should be compatible with 7.3, but will be the last version to be compatible. 7.4 and 8+ will be supported for a little while longer.


  • For CiviCRM 5.57: The automated tests have been run and pass in 5.57. To support 5.57 some logic around receipting had to be modified. So if you run this version in 5.49 you may get extra or fewer recepts sent!

  • Support, and in places, require, template contributions. Previously, had anyone created a template contribution for a GC recurring contribution it would have caused trouble. Template contributions are a relatively new thing in recurring contributions; they hold the data that will be duplicated and added to when the next contribution is received.

  • Add supportsEditRecurringContribution(): Subscription amount changes are allowed. It now creates a template contributions when the subscription amount changes (e.g. using the core edit recurring contribution form). As well as helping with core functionality, this also allows the upgraderecur extension(which allows you to make amount changes to a load of recurring contributions at once) to function better with GoCardless.

  • Template contribution created in the case that the last contribution was failed, and where a template did not already exist. This is new logic in place of old logic for a work-around that hopefully won't be needed one day.

  • Bug fix: providing a country value breaks createRedirectFlow

  • Lots of behind-the-scenes stuff, like using new logging facility (logs should end up in same place as before).

  • Note: to visualise Contribution, ContributionRecur, Contact, Membership records for diagnosing problems, install This is not a dependency, just a suggestion. The code was originally developed as an aid to diagnosing GoCardless contributions, but it's of general use, hence it was moved out.

1.12.0 (also relates to 1.11.2 though this was never released)

  • Adds more logging output (This was supposed to be in 1.11.0 but got lost while moving the code from github to gitlab)

  • All logging now references the webhook ID and event IDs.

  • Messages that are normal/probably ok are prefixed with OK:
  • [error] is used only for things that will return a 400 error to GoCardless. These are typically prefixed FAILED:, too. These should be investigated.
  • [warning] is used when you might want to investigate as something unexpected has happened.
  • [notice] is used when something's slightly odd, but not a cause for concern. e.g. delayed events that are not out of date. Typically prefixed OK: for reassurance.
  • [info] is used for general info.
  • [debug] you can ignore these, unless debugging. GC sends a lot of events we do not need to process. The log message for this is even more explicit now, since it was previously a cause of alarm for anyone reading logs.

  • Now uses the standard 400 Bad Request HTTP response instead of the non-standard 498 Invalid Token response. As well as it being good to stick to standards, the 498 may get changed to a 200 (giving false hope that the request was successful to the untrained eye that doesn't spot it's supposed to be 204 for success) by the server. (This was supposed to be in 1.11.0 but got lost while moving the code from github to gitlab.)

  • Upgrades GoCardlessPro library to 4.14. Importantly, this version removes certificate pinning to a cacert file that they used to distribute with their code, which has expired. i.e. your site may be broken without this upgrade! The updated library also contains its own methods for parsing the webhook data, so we now use that. This meant a couple of tests could be removed.

  • Deprecating the old webhook URLs, in favour of standard CiviCRM core ones. A warning should show on the status screen if old ones are found to be in use.

  • Tests updated based on a clearer understanding of how membership renewals are supposed to work. Also see core PR and documentation.

  • Fixed bug that meant daysOfMonth setting was getting lost.

  • Support mjwshared: with this extension (v1.2+) installed alongside, webhooks will be queued instead of processed real-time. This fixes a problem with big webhooks. The mjwshared extension processes the queue by a Scheduled Job and includes a way to see the list of webhook events and their status. Try it out!

  • Thanks to... A lot of the work in this release has been funded by openDemocracy, the independent global media organisation. Also thanks to Matt Wire for helping us develop the cross-processor webhook event queue.


  • Settings are now better validated/checked. Every time settings are loaded (by Api4 Setting.get, or by our getSettings method directly) they are validated, missing defaults are applied, and these changes saved.

  • Receipt policy now defaults to 'defer', instead of 'never'. This is inline with normal CiviCRM behaviour, so if you're using a custom set-up you must ensure 'never' is configured if/when you rebuld/reinstall.

  • Bug in settings screen meant that you could not select 'defer' for receipt policy (it was previously storing recur which is an invalid value where it should have stored defer)

  • New hook added: civicrm_GoCardlessSubscriptionCancelled($contributionRecurID). This will fire after the IPN/webhook has processed a Subscription Cancelled event.

  • Note on core CiviCRM bugs: There are 2 known bugs in CiviCRM 5.39 - 5.41 (not tested beyond this) both affect memberships.

    • Membership start date gets set to 'today' when a payment is created via the API and skipStatusCal is set. This could lead to people being short changed on their memberships, but I suspect it mostly affects imports, test cases

    • Existing Membership status gets set to Pending whenever Order.create wants to add a membership contribution. There's a PR for this,, but it did not make it in until 5.42. This could result in people losing memberships while they're trying to renew.

  • Developers' notes: The tests have had a massive rewrite, thanks to funding from a-n. The tests no longer use the prophesy mock framework (since it is removed in later versions of phpunit). The tests acknowledge the core bugs and work around them or flag them up as Incomplete (with descriptions when run with phpunit -v).


  • A clean-up of code around handling completed payments; strip out work that is now done by core CiviCRM, and for the bits we still need to override (e.g. setting Contribution receive_date to the charge date of the completed payment) we do this with SQL not the Contribution.create as this sometimes seems to do too much resulting in errors like DB Error: already exists when Civi (5.31 at least) for some reason tries to add a duplicate row in the activity-contact table. See

  • Adds more logging output (it was assumed these were included, but actually they got missed off)

  • Now uses the standard 400 Bad Request HTTP response (it was assumed these were included, but actually they got missed off)

  • Added hook_civicrm_alterPaymentProcessorParams support to alter the params sent to GoCardless for creating subscription.

  • Introduces a hook to alter or override the completeRedirectFlowWithGoCardless. See CRM_GoCardless_Hook

  • Implement doPayment instead of the old, deprecated doTransferPayment. See

  • Fix trouble with receipt policy (duplicate receipts or none!) - see

  • Fix 'source' not populating in subsequent contributions. - see

  • New feature: day of month to take payments. Thanks to Matt Wire @mattwire for this contribution.

  • Note: the phpunit tests run successfully on 5.36 and 5.38 (current Civi version at time of release).


  • Improvement to the force recurring/renew option (see note in 1.10.0 and Settings). In 1.10.0 the auto-renew box was getting un-checked by CiviCRM core's code when you changed membership type. This release fixes that case.


  • New settings form. Administer » CiviContribute » GoCardless Settings

  • Option to send receipts (previously it just didn’t) (fix #61)

  • Option to prevent users from forgetting to tick the Recurring and Auto-renew boxes. (fix #72)

  • Stores CiviCRM contact, contribution and contribution recur IDs on subscriptions at GoCardless (fix #79)

  • Various fixes related to webhook URLs.

  • (Developers: new import script konp.php may be useful to study and adapt for special cases including importing membership)


  • Reduce timeout for changing "Pending" recurring contributions to "Failed" from 24 hours to 0.66 hours. See issue #76 You can still override this as a parameter, should you wish.

  • developers: fixed problem getting and setting the processor ID in import script. Thanks @jmdh for this. Also, there's been a massive refactor of the import script.

  • Use supplemental_address_1 and 2 when prefilling GC address fields. Thanks @TomCranshaw

  • Implement new doCancelRecurring and support payment propertyBag, needed in recent core versions. Thanks @mattwire

  • Exclude guzzle dependency of the GoCardless library: CiviCRM core already provides guzzle 6, so this extension bringing it in as well is not needed or helpful.

  • New docs!

  • Move to standard webhook URLs (old one still supported for now) and new helper page (Administer » CiviContribute » GoCardless Webhooks) to spell out the correct URLs to use.


  • Move to Payment.create API instead of older (and deprecated) Contribution.completetransaction API.
  • This is from PR #70 (Thanks @mattwire) which fixes issue #63 on some sites where the first contribution never gets completed.
  • Also this method is now used for repeat payments.

  • Fix some issues with the system checks (PR #69 thanks @mattwire)

  • Treat HTTP headers sent by GoCardless webhooks as case-insensitive, as now required by GoCardless (they changed the way they sent HTTP/1.1 headers).

  • Fix missing/invalid configuration for payment instrument and payment method.

1.9 For CiviCRM 5.19+

  • Do not install v 1.9 from - it's missing the important libraries! Use 1.9.1

  • Supports changing the amount and cancelling a subscription via CiviCRM main user interface (issue #6). It does not support letting supporters themselves change these things.

  • One-way-upgrade: we now store the GoCardless subscription ID in both trxn_id and processor_id in the civicrm_contribution_recur table. This is because some parts of CiviCRM's UI require us to reference the record via processor_id which was unused up to this point. An upgrade task should populate existing data.

  • Some membership dates logic was failing in the tests under CiviCRM 5.19. This version passes its tests again.

  • Fix issue when setting up a weekly membership (issue #59 - thanks to MJW Consulting for reporting and suggesting fix)

  • Improvements to code standards; better support for translation possibilities; move tests to phpunit6.

1.8 Big changes

  • Now with pictures showing the lifecycle of Contribution and ContributionRecur records. Lifecycle diagrams

  • Major change, possibly breaking: multiple GoCardless payment processors now allowed. Previous versions had assumed a single GoCardless payment processor, and that's fine for most organisations. However, some organisations have cause to use multiple GoCardless accounts with one CiviCRM instance.

This change should hopefully be invisible to you and existing sites should continue to work as before, with the possible exception of anyone who has done a custom (non-CiviCRM Contribution Page) donation form and used the GoCardless classes directly. If you have done this then you need to adjust your code, removing calls to:

  1. CRM_GoCardlessUtils::getApi
  2. CRM_GoCardlessUtils::getRedirectFlow
  3. CRM_GoCardlessUtils::getPaymentProcessor

In cases (1), (2), you should now be looking to find an appropriate CRM_Core_Payment_GoCardless payment processor object (e.g. use

// This assumes you only have one active GoCardless processor.
$processor_config = civicrm_api3(
    ['payment_processor_type_id' => 'GoCardless',
     'is_active' => 1, 'is_test' => 0]);
$processor = Civi\Payment\System::singleton()->getByProcessor($processor_config);
$redirect_flow = $processor->getRedirectFlow(...);
$gc_api = $processor->getGoCardlessApi();

) and call its methods which have the same names. In case (3) please just use CiviCRM's native methods for finding a payment processor.

Currently these methods are left in but will trigger E_USER_DEPRECATED errors to help you find use.

  • Now handles "Late Failures"

With BACS (and SEPA, although that's not yet supported here) payments can apparently be "Confirmed" one day, then next day they can still fail. This is just to keep you on your toes.

It's called late failure.

Until v1.8 we didn't know about late failures which would result in 'Completed' contributions being recorded which had actually failed the next day.

This new version of the extension handles late failures by changing the Contribution status to Refunded. Note that CiviCRM will not let us change a Completed Contribution to Failed, which is why it's processed as a refund.

  • Scheduled job for abandoned/failed mandate setups

When a user clicks submit and is redirected to the offsite GoCardless page to enter their bank details, a recurring contribution and a contribution record are created as Pending on their Contact record.

If the user gives up at this point then those records would stay in "Pending", which means you can't then easily differentiate between those abandoned ones and the ones that should complete soon.

v1.8 includes a scheduled job which will look for any Pending recurring contributions older than 24 hours and will mark them as Failed. The Pending Contribution record is marked as Cancelled.

So you can now find abandoned set up attempts by searching for Failed recurring payments.


  • Fixed issue in certain use cases that resulted in the First Name field not being pre-populated (issue #45). Also further thanks to Aidan for knotty discussions on membership.

  • Fixed issue that caused other payment processors' configuration forms to not save. (issue #49)

1.6 "stable"!

  • Membership now supported thanks to work by William Mortada @wmortada and Aidan Saunders @aydun, and this extension is in production use by quite a few organisations so calling this release stable.

  • GoCardless forms are now pre-filled with address, email, phone numbers if you have collected those details before passing on to GoCardless. Thanks to Vitiligo Society for funding this work.

  • Updated GoCardlessPro library to 1.7.0 just to keep up-to-date.


Should now respect a limited number of installments. Previous versions will set up an open-ended subscription. You may not have wanted that ;-) Also updated GoCardlessPro library from 1.2.0 to 1.6.0 GoCardlessPro changelog should not have broken anything.