I have 2 set of custom fields for contributions and certain items of that are not meant for donors to see, only for admin purpose. But they are automatically included in offline receipt. How Can I remove them from the offline receipt?

4 Answers 4


If you want to stop all custom fields appearing in receipts, you can edit the Contribution - Receipt (off-line) template directly, in 'Message Templates'.

Remove the section starting with {if $customGroup} through to the next {/if}, and give that a try.

If it turns out it's using the on-line receipt (I'm always getting confused as to which is used when), it's the same but with {if $customPost}.

  • 3
    If you don't want to turn off all custom fields, you may be able to check on a smarty variable. We use {if $customPost AND $contributionPageId != 25} to stop custom fields from a particular page being emailed automatically. I think you can put {debug} into your template to output the variables in the email so you can see if there are any likely candidates (wiki.civicrm.org/confluence/display/CRMDOC/…). Jul 21, 2015 at 13:15

As of September 2017 (4.7.25) this is now possible without any coding changes (see CRM-20507). Simply uncheck the "Is this Custom Data Set public?" box.

enter image description here


Access control on custom fields is at the level of custom field sets. One way to achieve what you want might be to put the fields that should be seen by donors in one custom field set and the admin-only fields in another set. Then use ACL to restrict who can see the admin-only custom field set. Test carefully to make sure that the access control is correctly applied for receipts.

  • 1
    the ACLs aren't applied to offline receipts (in 4.6 at least)
    – Ken West
    Oct 28, 2015 at 0:59

Here's a patch that screens out custom fields that belong to groups that are private. This code assumes that anonymous users are not granted the 'access all custom data' permission, and ACLs are used to make custom groups public.

--- a/CRM/Event/Form/Participant.php    2015-05-20 16:30:37.000000000 +1000
+++ b/CRM/Event/Form/Participant.php    2015-10-28 15:06:16.000000000 +1100
@@ -1602,9 +1602,28 @@

       $template = CRM_Core_Smarty::singleton();
       $customGroup = array();
+      // Assume the receipt is being sent to an anonymous user. This code emulates
+      // CRM_Core_Permission::customGroup() being called for an anonymous user, and
+      // assumes that anonymous users are not granted the 'access all custom data'
+      // permission. Anonymous users are only shown public custom data groups.
+      $publicGroups = CRM_ACL_BAO_ACL::group(
+        CRM_Core_Permission::VIEW,
+        0,
+        'civicrm_custom_group',
+        CRM_Core_PseudoConstant::get(
+            'CRM_Core_DAO_CustomField',
+            'custom_group_id',
+            array('fresh' => FALSE)
+        )
+      );
       //format submitted data
       foreach ($params['custom'] as $fieldID => $values) {
         foreach ($values as $fieldValue) {
+          if (in_array($fieldValue['custom_group_id'], $publicGroups) === FALSE) {
+            continue;
+          }
           $customValue = array('data' => $fieldValue['value']);
           $customFields[$fieldID]['id'] = $fieldID;
           $formattedValue = CRM_Core_BAO_CustomGroup::formatCustomValues($customValue, $customFields[$fieldID], TRUE);
  • Hi Ken. I think you should submit your code as a PR to civicrm to be included. It would be a nice fix. :-) Oct 29, 2015 at 16:43
  • I think my patch makes a few too many assumptions to go into Core. Essentially what is needed if for CRM_Core_Permission::customGroup() to be refactored so it can test the permissions of any contact, not just the current user. That in turn requires refactoring much of the CRM_Core_Permission class.
    – Ken West
    Nov 6, 2015 at 1:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.