Skip to end of metadata
Go to start of metadata


This specification is currently an incomplete draft. Section headings similar to those in the CiviContribute Specification spec have been roughed in. A data - centred view is mapped out starting at #Membership.

Phase 1 Scope / Assumptions

CiviMember Phase 1 will support the following functionality:

  • Memberships in one or more organizations
  • Customized types and status of membership by organization
  • Importing and exporting membership records
  • Self-serve membership sign-up and renewal pages
  • Basic Membership Search/Listings (search and list memberships by date, type, status, contact info including name and address)
  • Membership admin roles by groups, so that the privilege to view or edit membership information for the members of a group can be assigned to group leaders (eg. membership secretary for a precinct/riding)
  • Separate access control for financial information and other membership information
  • Logging of all Membership Activities (eg join, renew, payments, suspension)
  • Integration with CiviDonate for membership payments, including for contributions split between membership dues and some other purpose
  • Integration with CiviMail for membership appeal campaigns
  • Basic reports including details and summaries such as number, membership contributions, type and status of members by group as of a certain date
  • Exposure of an API to control all functionality

The following features are being considered for subsequent phases (and are NOT part of phase 1):

  • Membership pages are linked to one or more Projects/Campaigns

Menu / User Interface Elements

CiviMember Menu

Similar to CiviDonate menu CiviContribute Specification#Menu / User Interface Elements but for Membership information

Find Member

Import Members

Export Members

Configure Membership Page

1. Classes / Schemas

1.1 ModuleProfile


1.2 MembershipPage

Represents a specific instance of an online membership form.

2 Pages and Forms

2.1 Configure Membership Pages

2.2 Configure Membership Page

2.3 Preview Membership Page

2.4 Membership Page Flow

Classes / Schema for Memberships


Here are some ideas for a CiviCRM membership model. Comments welcome.


Identifies an Organization as one for which memberships are tracked.
MembershipOrganizationID: Unique primary key for this MembershipOrganization
contact_id: FK to Organization (see CiviCRM Data Object Model)

NB: A publication can be entered in an organizational record in order to handle publication subscriptions as memberships.


Membership is a Relationship_type Data Model with the following characteristics:
name_a_b: 'IndividualMember'
name_b_a: 'HasMember'
description: 'Membership relationship'
contact_type_a: 'Individual'
contact_type_b 'Organization'
is_reserved: 0

It extends the Relationship entity (see Data Model. The contact_a field is the Member, and contact_b is the MembershipOrganization.

FirstMembership: date (year contact joined)
is_suspended: boolean: membership privileges suspended due to overdue payments (should be a calculated value available through API but not stored in table)
MembershipPaymentStatus: value from MembershipPaymentStatus table (see below) (should be a calculated value available through API but not stored in table)


There needs to be a way of geolocating a member to various levels of regions/jurisidictions. I suggest building separate 'groups' for this, and having a hook interface that would accept geolocating information such as an address or lat/long and return a particular value for each such geographic level (eg riding/constituency ID). We currently track FederalRiding, ProvincialRiding, and MunicipalWard. Others such as PublicSchoolWard might be useful. We don't currently have map layers or postal code lookups for all lower level jurisdictions. Associated with each level would be a table providing names of region/jurisidiction/riding/constituency for a given ID. Given the need to redistrict, it would useful for there to be a date associated with each level, so users could specify either old or new boundaries in the leadup to an election under new boundaries. Manual override of the actual geolocation is necessary to accomodate people who wish to keep their membership in ridings other than where they live.

While we do not yet have map layers for this, we do track FederalPoll, ProvincialPoll and MunipalPoll using information from voters lists.

Access Control

Associated with each regional group would be some entries in an Access Control List (ACL). In particular, for us, we would want Membership Secretaries for each federal riding and provincial riding to be able to view information, enter offline membership payments for people in their riding, and run reports detailed below. Note that membership in the federal party is the same as membership in the provincial party for our purposes. Perhaps other organizations would like the ability to track membership separately for different jurisdictional levels in the same database.

Separate ACL entries would allow central provincial and federal administrators to change data in any riding.

Individuals should be able to view their own membership status. People should have the option of exposing their membership to either other members or the general public for the purposes of grassroots up organizing through events, etc. I'm not sure how fine-grained this should be: perhaps separate permissions for anonymous site email, email, IM, postal address, phone, cell, etc., with an option of setting all at once for convenience. Administrators should have option of setting the default for these permissions.


Entries (configurable by admin)
Initializing: first payment has not cleared bank
New: first year of membership
Renewed: membership has been paid for current year
Grace: membership has not been paid for current year but membership privileges still extended
Unrenewed: membership has not been paid for current year and grace period if any is over
Lapsed: membership has not been paid for current or previous year
Inactive: membership has not been for current or two previous years


Entries (configurable by admin)
Calculated value of Current status is set through admin interface. Default values for current:
Grace (??)



Sample entries (configurable by admin)

Individual $25
Student / Not gainfully employed $5
Senior $5
Family $0
Lifetime $0 - never expires
Complimentary $0
Sponsor $100
Benefactor $1000
Patron $2500


Membership: FK to Membership
Payment: FK to Contribution (


Set values for days through the admin interface; maybe allow creation of more categories of late payments
PaidInFull - fully paid up
PaymentUpToDate - recurrent payments up to date but full amount not yet received
PaymentLate- recurrent payments are 0 - 60 days overdue
PaymentOverdue - recurrent payments are > 60 days overdue

A member's PaymentStatus is determined by checking whether there are unpaid pledges associated with membership. These pledges need to be created when setting up memberships for pre-authorized credit card payments, pre-authorized chequing account payments, and for post-dated cheques.

Business rules

Need hook(s) to do things like the following:
Family membership records must be linked to head of household record, who must have a non-Family membership type
Status of family memberships is the same as that of the head of household record
Status of lifetime members is always Renewed
Benefactors and Patrons are automatically renewed once.

Membership Year Admin

In an admin interface, it would be useful to be able to set the following:
Membership Year Type: enum: rolling (default - means at date of payment), fixed
Fixed Membership Year Start: date (default January 1)
Fixed Membership Payments after this date cover following calendar year as well (default to December 31, ie no extra coverage; my organization uses October 31)
Grace period: Unrenewed membership privileges extend for this length of time, renewals in this period include grace period when calculating membership expiration date (integer: months: default 0)

It is necessary to support membership payment dates different than entry dates for payments (already in donation payment spec).

Year End

Currently a batch job is run to update membership status once all year end data has been entered and validated through returns of bank deposit data. There is a need to support year end processing where not all transactions can be entered before the end of the year. Through this period it is necessary to be able to produce reports based on a report date of either the old year (eg December 31) or the new year (eg January 10), with membership status appearing correctly. I imagine this could be implemented by having the report do some special calculations for membership status using report date, current date, and an indicator about whether year end processing was completed.


Detail Reports options:

  • in addition to having ACL for membership reports, perhaps have access control lists for individual field level elements of other reports dealing with membership information
  • include or exclude each of the membership statuses and types
  • set a report date other than the current date
  • for those with appropriate access privileges, include membership $ amounts
  • include membership status and type as available fields in reports on donations
  • integrate with work planning module (like Basecamp) to allow eg. renewal phoning to be assigned to volunteers and tracked
  • formats: 8.5" x 11", 3 up mailing labels, envelops

Sort orders (sample):
last name, first name, middle name
street name, street type, street direction, street number, street number suffix, apartment number
allow odd and even number street numbers to be sorted separately for reports
group by household or not

Potential sort orders:
postal code

Summary reports:
Membership totals and percentage by month by MembershipType
Membership totals and percentage by month by MembershipType compared to previous and second previous years
Option to include payment type (perhaps other things too) in previous reports.

Integration with email and mail and phone campaign reporting to determine success ratios for membership signups and renewals, and tracking of this into future years (eg we're having trouble renewing the tsunami inspired members, but not with all our other members).

Logging / Audit Trail

Changes to membership information and payment information need to be tracked including the users who made them and the date.

To Do's

  • incorporate Neil's suggestions re: geolocation and especially Access Control
  • incorporate dave's use case of $20 membership / $80 donation for $100 payment
  • incorporate Howard's suggestion re: 'chart of accounts' to provide several default configurations for different uses: eg. different kinds of US charitable orgs, US political party, Cdn political party, Cdn charitable org, etc.

Commercial Systems


  • None
  1. Oct 27, 2005

    We are eBase users and have some interesting other fields and values having to do with membership.

    Besides Lapsed and Legacy (we call that Inactive) there is also Grace which extends for a while after their renewal date (3 months in our case) where they continue to get membership benefits but when they finally renew, they only get to the end of their official next year, not a full year. New and Renewed makes searchs for current members unnecessily hard. The field should contain Current and the new/renew option stored somewhere else. We also have Complimentary members, Prospective members, and explicitly non-members in the database. The non-member status needs to be in the value list along with Lapsed, etc. Both Complimentary and Prospective need to have expire dates so they are either re-Comp'ed or demoted to NotInterested, so I think these are potential values in the status list, but Complimentary is also Current so that is a complication so perhaps it belongs in the membership type field. It is also useful to have Deceased as a possible value. We retain them in the database because they have interesting history which is sometimes very useful, but we don't want them to get mail, etc.

    One of the administrative options on year administration needs to be rolling (we send out renewal notices on a monthly basis to spread the staff workload).

    The distinction between Membership and Donors needs to be clarified. For many there is no distinction, a paid membership is a donation. We have membership levels, sponsor, benefactor, etc. which are mostly subtrifuges to encourge steady donations. For bigger donors, we mark them as fully paid even if they forget to respond to a membership renewal request. Others distinguish membership and donors and want to account for them separately.

    Many organizations have "honor" societies for various levels of donation, which get them extra services. These tend to get a bit complicated because they are usually based on total annual payments, rather than single payments.

    There are also variations (need admin options) to deal with payment plan members or pledges. For example, letting people pay for a Lifetime membership over 3 years. Do you give them instant credit for their intentions or wait until they have paid in full? Some of this decision depends on how you do accounting. Is accounting builtin or done externally? If external, you need some export options to give the accounting system what it needs.

    Membership committees and development people love statistics, e.g. how many members are there on a monthly basis so they can track membership growth. There need to be cronjobs that record the right info at the right time. There also need to be reports or queries that allow them to correlate the growth with various actions/campaigns that they have undertaken. This means that every user needs to be tagged with the source of action, e.g. the blue form sent with the annual appeal (rather than the red form which made some other offer). Even payment method is interesting, credit card via internet vs credit card number on mailed form.

  2. Oct 27, 2005

    To take this beyond political parties perhaps there needs to be a way of handling different things to be a member of. For example an organization could have general membership and a magazine membership.

    This also brings up the issue of non jan-dec membership periods. Most magazine subscriptions start from when payment is received for 1 year. Perhaps subscriptions need to be handled completely differently from memberships. Though I'm just making this one up so there might not be anyone who would use this.

    I like the idea of giving members the option to publicly expose their data. There is also Drupal's messaging module (can't remember offhand what it's called) that can handle user-to-user communication. Though perhaps this needs to be handled more anonymously like "Allow anyone in my area to send me an anonymous message without exposing my email address". I think the Dean campaign did something like that. Though perhaps that is something for CiviCRM core instead of CiviMember (working title?).

    In regards to the membership type I think it should be a type and only a type. By that I mean "standard, complimentary, lifetime, non-member" and perhaps "potential" (But it might be better to handle that somewhere else). The status of the membership (current, new, lapsed, inactive) should not be a field, but rather calculated.

    In regards to donations I think that needs to be handled completely seperate from membership. In our organizations non-members will donate and not want to become members, and some members do not donate more than their membership fees.

    It is a good point however that we need to share some functionality/interaction with CiviDonate for monthly payments.

    To avoid runing Cron jobs to handle reporting the number of new members/month perhaps it would be better to simply add a field to the membership table for last paid date.

    Or if we really want to get fancy prehaps instead of a 1 to 1 relationship between individual and membersip it should be 1 to many to store all renewals with their payment types. The first membership date would not exist as this would instead be the paid date of the first record. But prehaps this just becomes the tracking of information for no purpose.

    Anyway I like where this is going.

  3. Oct 28, 2005

    Thanks, Walt and dave. I've changed the page to reflect most of your comments. Some that I'm still unsure about I haven't changed.

    Here's the breakdown for Walt:

    Included Grace as a new MembershipStatus value. It gives a name to functionality described in Membership Year Admin, which I've updated as well.

    Created a calculated Status field for Membership API that can be set to a MembershipStatus table entries. Created an is_current field for Membership. Created a new CurrentMembershipStatus table that maps several specific statuses to current status (eg. renewed, complimentary). I too am not yet convinced this is a great design for calculated values - let's hear what other people think and do.

    Added Complimentary Members to MembershipType table. Regarding non-members: they would be in CiviCRM database but not have any Membership (or at least current membership) data about them. Regarding Prospective and NotInterested 'memberships' - I suspect this is better tracked through groups and tags on general CiviCRM contacts.

    Deceased is tracked at the Contact level in the is_deceased field (

    Added distinction between fixed membership year and rolling membership year to Membership Year Admin.

    I put in sample honor membership levels, but I think this is likely better handled through CiviDonate. At least, it needs to be in CiviDonate as well as CiviMember.

    There are lots of ways organizations could handle what constitutes acceptable payment for member privileges. I've added a MembershipPaymentStatus table and associated field in Membership API as well as is_suspended field in Membership API.

    Reporting: incorporated all comments.

    dave's comments:

    added MembershipFor table to handle multiple memberships in same CiviCRM database

    added rolling memberships

    adopted CiviMember as name

    MembershipStatus: changed from value in Membership table to value returned through API but not stored.

    Membership type: I'm not sure what the value is of having a non-member entry.

    Donations: yes, I'm assuming these are separate, but some organizations may have 'membership' levels that are akin to honor donation levels. The design allows these, but assumes there will be donations separate from membership payments. I'm assuming all payments including membership ones will be tracked by CiviDonate.

    Calculating non-payment of monthly payments in order to suspend membership status is even more complicated than just tracking them.

    I'm leaving optimization of things like running cron jobs or not til later. Currently I haven't added a last payment date field, but I have added API functionality to determine MembershipPaymentStatus of an individual and whether is_suspended is true for them.

    FirstMembership is needed for historical purposes, and is relevant long after the payment records will have been purged. Some go back 50 or 75 years.

    Glad to hear you like where it's going! Further refinement will be necessary. More comments welcome!

  4. Oct 28, 2005

    From crm-dev:
    Date: Wed, 26 Oct 2005 16:50:52 -0400
    From: Neil Adair <>
    Subject: Re: Crm-dev Membership functionality
    To: CiviCRM: General discussion around development
    Message-ID: <>
    Content-Type: text/plain; charset="iso-8859-1"

    Joe Murray wrote:

    >After CiviDonate, the next big effort will be a membership module. I've
    >posted some ideas that could be the basis of a spec at
    >Comments welcome.
    Hi Joe

    This is similar to what we are thinking. Can't location.module be used
    for the geolocation?
    We need a file, I'm looking at building one with the
    Postal Code Conversion File from StatsCan

    Do you know if there are any correspondences between Census subdivisions
    and polling divisions?

    I'm concerned about the admin implications of separate permissions for
    hundreds of groups. I've posted a proposal at the bottom of the ACL page
    and I'm attaching it

    I think it would be flexible enough to accommodate multiple levels of
    jurisdictions without becoming overloaded with admin.

    -------------- next part --------------
    CRM access control

    Fine-grained permissions are an essential feature for CRM. The problem with comprehensive permissions is administration. The admin overhead is so high that users are often granted permissions they don't want or need or they share accounts. Data security, user tracking, and productivity are all compromised.

    The following is a suggested approach to providing comprehensive acccess control to CRM with a minimum of administration required.

    Role - Drupal access control roles
    sets CRM permissions

    Administer CRM
    Access CRM Profile
    Access CRM
    Add Contacts
    Edit Contacts
    View Contacts

    Profile - CRM Profile with ability to apply different profile to each role and set access fields

    Currently CRM Profile can be set for "Public" or "User and User Admin" only. If it were extended to apply a profile for each role and to set an "access" field similar to "match" field setting, administration can be simplified. Profile is used to set the CRM fields visible to a role and the field to use (if any) to control access to contacts for that role (in addition to its' other functions).

    Groups - dynamic
    Users in a role which has the access field set in its' profile will have all searches restricted to contacts who match the content in the users access field. For example if "state" is the access field then users can only access contacts in their state. Note that roles with no access field set can view/edit all contacts, roles with "email" set as access can only view their own contact data. This is not limited to geographic groups as any field can be set as the access field, a custom "group" field set as the access field can be used to form groups.

    This scheme embeds the access rules in the profiles configuration and requires only the assignment of roles to users. Administration of a website requires setting roles for users and this scheme simply adds a few additional roles, no other tasks.

    Another advantage of controlling access in this way is leveraging of saved searches. A saved search for "all members" will return all members in different states, districts, or other divisions depending on the user who runs it. This can significantly reduce the number of saved searches and the ease of selecting the correct one.

  5. Oct 28, 2005

    from crm-dev:
    Message: 3
    Date: Thu, 27 Oct 2005 11:04:20 -0700
    From: Dave Greenberg <>
    Subject: Re: Crm-dev Re: Crm-dev Membrs and Donors
    To: CiviCRM Developer Community <>
    Content-Type: text/plain; charset=ISO-8859-1

    Dave -
    This is good input for subsequent phases. We might handle this particular use case (membership fee=20; donation=80) as part of the premiums/thank-you gifts implementation - which will allow folks to configure premiums offered based on contribution levels and optionally apply market-values for deductibility adjustments, etc.


  6. Oct 28, 2005

    from crm-dev:
    Message: 7
    Date: Thu, 27 Oct 2005 15:05:23 -0400
    From: Howard Johnson <>
    Subject: Re: Crm-dev Re: Crm-dev Membrs and Donors
    To: CiviCRM: General discussion around development
    Message-ID: <>
    Content-Type: text/plain; charset=us-ascii

    Hi All,
    With this level of complexity you are almost inventing an accounting system.
    Based on two kinds of transactions, e.g things coming in (receipts) and things going out (expenditures) and a chart of accounts, in an accounting system I can classify things, split items across accounts, etc etc. Are you really expecting to 'keep the books' inside the CRM app? Yes, I know that if you're using the web to capture the money you need to keep all the correct information for legal and other purposes, but it's going to be tough to create a structure ahead of time that everyone can use (different organizations, etc). Back to the 'keep it simple' approach, maybe, with a set of transaction types and categories that can be extended by the user. Also let people write their own Description for any type or category. You might look at how an app like Quickbooks takes the user through configuring a chart of accounts as an example.

  7. Nov 10, 2005


    I'm looking forward to using this! Just what we need.

    One thought - we have two quite distinct type of member: 'members' and 'fellows'. Members are basically supporters, whereas Fellows are actively working with and for the organisation, eg available as consultants, trainers etc. I'd want Fellows to be able to display their profiles to any visitor to the website - but not allow members to do this.

    A) Not quite clear if this funcationality is available
    B) Would the profile section have a text area (with Wysiwyg editor) for each fellow to create a basic homepage?



  8. Nov 15, 2005

    I must say I'm a little confused. It is easy to see that there are a bunch of business rules around members and that it makes perfect sense to have a class of folks called "members" and that their identity is tied into their donation history. However, from a systems' point of view I'm not sure what the difference is between donors and "members". It would be helpful if someone could write up a paragraph or two to say why "membership dues" should not just be a different kind of donation.

    Here's what I've heard so far (and I may have missed something) -

    1) A "membership" is tied to a particular type or series of donations.
    2) membership often implies a recurring committment to dontate (pledge).
    3) membership = belonging to an instance of a CiviCRM "group".
    4) membership is a kind of "premium" for giving a donation.
    5) There is cause to track "membership" as a unique data set for the contact.

    It seems a little over-engineered to create a new module for functionalty that seems to be 80-90% covered by the dontation module and base CiviCRM.



  9. Nov 15, 2005

    CiviCRM is trying to provide CRM for non-profits. Part of this is providing functionality in the form and packaging that make sense to end users in the non-profit domain.

    A number of non-profits make a strong distinction between members and donors in their operations and how they think about the two groups. Members of political parties get certain privileges where I'm from like voting for policy and who will become a candidate for the party that donors do not get. Members of non-profits that I'm familiar with often get benefits that donors do not get, for example, publications mailed to them. Certain membership classes like life members or honorary members do not have to be donors to be members. A very large number of Canadian political donors are not members of the party they donate to, and might be unwilling to donate if that required them to be members. (For example, it is common to require members to not support other parties, which is impossible for those individuals who donate to more than one party.) So payments for memberships have to be separate for business reasons from any old payment. So from the user perspective of menus and screens, it makes sense to have separate functionality, or ways of accessing the same functionality, for members and donors.

    At a slightly more detailed level, there is a need to provide some extra information on top of CiviContribute regarding status (which can be suspended for non-financial as well as financial reasons) and type of membership (eg family membership, though payment is never from a household). Further, groups of related organizations sharing a CRM database may want to have separate memberships that they track separately. For example, in a provincial or federal or municipal level of a loosely coupled organization like a political party, or in different shoestring grassroots organizations that are part of a coalition sharing admin things like a membership system.

    From a systems implementation perspective, as people have noted, handling memberships can leverage a great deal of stuff already in CiviCRM. The primary implementation focus for me as I start looking through things is not CiviContribute but creating custom Relationships. These relationships would be heavily dependent on CiviContribute for much of their functionality.

    As to whether this deserves to be separate module or not, my sense is that it would help to simplify things for non-membership based non-profits if it was not there. Configuring and using membership functionality would be separate from general contributions, which would assist most of those organizations that have significant business rules and culture around memberships.

    From a marketing perspective, CiviMembership is an attractive plus for some of my clients, even if it is a relatively thin layer of code.

  10. Nov 16, 2005

    I don't understand why geolocation and ACL are in here and not in CiviCRM as a whole, from my point of view it would be useful to know what riding all contacts are in, whether they be a member, volunteer, donor or non of the above.

    Likewise for ACL, a regional membership coordinator would need to see info on all contacts in their region.

  11. Nov 16, 2005

    ACL is a general CiviCRM functionality (but I can't find the page for it at the moment). I agree that the geolocation stuff should be part of CiviCRM as a whole in the groups functionality, and CiviMembership should just be using it.

  12. Dec 20, 2005

    (From Rich Cowan on the CS Community list)

    Correct me if I am wrong, but I don't think that the CiviMember spec contains the most important thing that we are looking for:
    Some very clear linkage between someone's membership expiration status and their access to certain areas of the web sites installed on a given instance of Civicspace.

    Here is an example "use case":

    – Nonprofit has civicspace installed with a civicrm database
    – The "sites" folder has 2 sites, i.e. the code is used to power two sites simultaneously
    – Both of the sites are run by the same nonprofit
    – Sites would likely share the same Civicrm database.
    – One of the sites is a basic community site open to everyone
    – the other site is a special service run by the nonprofit, a service that is sold on a fee
    for service model. Most people using this service are not actually "members" of or
    donors to the nonprofit.

    I think to support this it might require some modifications to the user login / access control features of Drupal. I.e. it will be necessary to be able to define a user as having Permission Level X by Default, but Permission level Y if certain conditions defined within the CiviCRM module are met. I.e. the person has paid up their membership fully, or is within a grace period before those services are cut off.

    Aside from these suggestions on OC's specific needs, my only other suggestion for the membership model is that:

    a) you make the assumptions explicit within the documentation what your default membership model looks like, and

    b) you do testing with two or three organizations that fit this membership model fairly well, for a full six months to a year, to be able to refine and streamline the software, and develop accompanying materials, before advertising the software as ready for general consumption.

    By doing this I suspect that you uncover a lot of complexity and situations that is not be anticipated in your original specifications – and that it might be a good idea to continue making small refinements for a year or more before adding bells and whistles, so that the core needs are met.

  13. Apr 22, 2006

    One thing I would love to see in CiviMember is that members with different levels of status will have access to different pages on the website. For example a "basic" member would only have access to a limited number of pages whilst an "advanced" member would have access to all pages (once they log in).

     I was wondering whether CiviMember would be able to integrate into Joomla enough to allow this. Essentially CiviCRM and CiviMember would take care of memberships (storing details, collecting fees, expiring old members etc.) and then would "inform" joomla about which members have rights to specific pages.

Creative Commons License
Except where otherwise noted, content on this site is licensed under a Creative Commons Attribution-Share Alike 3.0 United States Licence.