What (recurring) Receipting options work for you?

2015-03-24 18:27
Written by

We get a steady trickle of requests regarding changes to what receipts go out when someone signs up for a regular payment. We use an extension to help with this 'norecurreceipt'. The extension basically prevents the is_email_receipt from being set to ON on the civicrm_contribution_recur table - thus allowing the inital mail to go out but not the subsequent ones.

I discussed this some time ago with Dave & he suggested I post a blog to see where other people are at with recurring receipting.

What happens now?

The built in CiviCRM receipt workflow is that when someone signs up for a recurring contribution or membership they get

1) A notification that a recurring receipt has started
2) A notification that the an initial payment has been made
3) A notification of each payment that is made
4) A notification at the end of the timeframe.

You either get all or none.

What do people want?

We have different customers wanting different things - these are the requests we are hearing
1) We want them to get the start and end emails and no others
2) We want them to get a receipt each payment - but not the start-end date ones
3) We want them to get a receipt each time - but we don't want it to always be the one associated with the contribution page they signed up for because that was a specific campaign
4) We want one-off payments to get receipts but all communication with recurring payees will be highly customised

5) We want them to get only the first payment receipt (I think I remember that request correctly)

Possible approaches?

1) Site-wide setting to specify whether or not to send out start - end notifications.


  • easy, not much code or risk
  • seems that core shouldn't be imposing an opinion on whether these should go out


  • yes, it's another setting in core
  • not clear how hookable it would be for custom cases (or how much that matters

Scale - trivial

2) Write custom extension to abort mail going out when it's using the start end mail template using hook_civicrm_alterMailParams.

Write different extensions for the various other requests


  • this is probably what will wind up happening :-)
  • No core code involved


  • This just feels hacky to me - having core force a set of assumptions & needing to install one or more extensions to counter them
  • My reading of the code suggested activities might still be created
  • The hook is called for every email in the system - so that could be a noticeable overhead for large civimails
  • From reading the code it is possible the hook doesn't have enough information as yet (TBD)

Scale - minor

3) Adjust core such that if a workflow_template is disabled then it will skip sending that mail out without error


  •  all do-able within configuration and fairly easy to do and maintain, plus can apply to other templates


  • - could be confusing as to why things aren't going out if disabled.
  • - might need a permission to allow them to be disabled

Scale minor

4) Allow per-contribution-page configuration of follow up workflow emails

-ie. the UI for contribution pages would have a select box for start, end, first and ongoing emails. If none set for an option then no email would go out.


  •  more configurable.
  •  Feels more robust
  •  existing recurring can be changed over time
  • Provides format for linking other 'template items' to contribution page - e.g pay_later_text as a template, moving fields from membership block


  • more work
  • could lead to templates not being set by over-sight
  • what happens for back-office?

Scale - major.

Here is what civicrm_entity_msg_template might look like



































Filed under



As always, I'm impressed by your work rate and your thoroughness. I might need a second coffee, before I fully understand your post ;-)

As for our needs, we're quite happy with "send them all". Though we hadn't thought about your scenario of "we don't want it to always be the one associated with the contribution page they signed up for because that was a specific campaign". That needs more thought...

Now, when you write "This just feels hacky to me - having core force a set of assumptions & needing to install one or more extensions to counter them" my initial reaction was "Isn't that what extensions are for?"

My feelings about your four options...

  1. Only solves part of the issue
  2. I think this is clean. The risk is whether the hook has enough information available to it to make the right decision.
  3. Only solves part of the issue
  4. Is the civicrm_entity_msg_template solving a separate issue? Perhaps a Phase 2 idea?

The reason #2 feels hacky to me is that you are not using an extension to add a behaviour but to interrogate every single email sent out by CiviCRM to block a few emails.


If it were the other way around. Core didn't assume you wanted things and you added them with am extension it wouldn't feel hacky.


#2 only solves the 'whole problem' to the exent that it is possible to write a fleet of extensions to acheive various things. ie. my current customer wants an extension to block start & end date emails - which I will write an extension to do - any of the others would solve this too.

I've only had 2 requests to alter the current behavior and they were both:


1) We want them to get the start and end emails and no others

#3 sounds like a good solution.

#4 is certainly the most complete approach. It may be a little overkill, if it was only to solve this particular issue... However, AIUI it actually addresses a much more fundamental problem as well: for instance, we already have had several people ask about using different event confirmation templates per event. So indeed this would be very appreciated...

Yes, #4 solves some other problems that are in my mind. For example it also offers a model to move long fields out of the event table. There is a hard-limit as to how many characters in total the fields in the event table can add up to, and at the moment we are unable to reliably offer more than 3-4 languages per site because the event table can crash. Although I hadn't been originally thinking about this - the model proposed in #4 might even be prefererable for fields like description. Certainly I had been thinking about the email receipt messages that are per-event being in a message_template type table