LunpaCMS Whipping your website into shape! Introducing Lunpa, our mascot.  Her mother was a hamster and her father was Chilean M00se.  Oddly, neither smelt of elderberries.

LunpaCMS Membership Manager Documentation

A Quick Introduction

Membership Manager lets users subscribe to paid membership to your organization. Membership Manager supports manual payment by any means, and automatic payment via PayPal Manager.

Members can view their account balance and pay their membership directly from your website. They will receive automatic emails as their bill becomes due. Members will be automatically disabled if they fail to pay within a configurable grace period, and the site admin will be notified by email.

Admins can manually edit member information and send balance statements. Admins receive automatic emails when a member is disabled by the system, in addition to the automatic emails dispensed by PayPal Manager.

Configuring Membership Manager

Membership Manager is complex, and configuring it is a multi-step process.

  1. Install and configure PayPal Manager
  2. Configure profile templates
  3. Configure descriptors
  4. Configure maps
  5. Configure member types
  6. Searching for Members

Operating Membership Manager

Due to the breadth of functionality available in Membership Manager, and the importance of handling money correctly, we have provided a set of recipes that document standard procedures to handle proper money handling, complaints from members, automatic notifications, and other issues.

Configuring Profile Templates

The user profile form templates need to be integrated with Membership Manager. The form needs to display descriptors and payment options, and it needs to be submitted to Membership Manager scripts, which understand how to handle the additional fields.

In the templates profile_form-admin.template and profile_form-user.template, usermanager needs to be replaced with membershipmanager. For instance:

# Replace

<FORM NAME=register-edit_profile ACTION=/admin/usermanager/admin_register-edit_profile_action.cgi METHOD=POST>

# With

<FORM NAME=register-edit_profile ACTION=/admin/membershipmanager/admin_register-edit_profile_action.cgi METHOD=POST>

In the template profile_form.template, add a Membership Manager tag to automatically display membership form fields. The tag adds its own layout to the existing table, so it should go inside the <table> tag, but outside any table rows.

# Prints descriptor and payment fields

# Prints just descriptor fields

# Same as above

When finished, the bottom of profile_form.template should look similar to this:


For more flexible configurations, each field can be placed independently with a ::MEMBERSHIP_DESCRIPTOR:<descriptor>:: tag, which will resolve to the descriptors described in the local library (See below for more details on descriptors) as well as a few special descriptors.

Example: If there is a descriptor with the machine name "website" (as example below does) then the tag ::MEMBERSHIP_DESCRIPTOR:website:: will display that form field.

The special descriptors are payment and admin_fields. ::MEMBERSHIP_DESCRIPTOR:payment:: displays the payment options and ::MEMBERSHIP_DESCRIPTOR:admin_fields:: is where the admin only functions will appear if and admin is looking at the form.

Configuring Descriptors

Member descriptors are configured through a local library function, membership_manager_get_descriptors. It returns an array of hashes, where the specific fields determine the behavior of the descriptor manager-wide.

sub membership_manager_get_descriptors {
  my ($FORM, %params) = @_;
  my (@descriptors);

  $descriptors[0] = {machine_name=>'website',

  return @descriptors;

Configure Maps

Membership Manager has an optional default membership fee. Membership fees are also configured in member types This is configurable in Map Manager.

Configure Member Types

Member types are configured much like member descriptors. They are set in a function called membershipmanager_member_types in the site's local library. This function defines the levels of memberships and the fees for each level. An option of "admin_only" means that users cannot sign up for that membership level, and can only be configured by an admin user on the site.


sub membershipmanager_member_types {
  my ($FORM, %params) = @_;

  return ({machine_name=>'lvl_1',
           display_name=>'Basic Member',
           display_name=>'Advanced Member',
           display_name=>'Complementary Member',

Configuring Member Warning Frequencies

Membership Manager will send reminders to members who are approaching the end of their membership period to remind when they should pay for the next period, when their membership has expired and when they are past due on payments. The default configuration is to warn 30 and 60 days before the member's expiration day, on the day of their expiration, and then 30 and 60 days after. On the last day, the user is marked as not a member and their balance is zeroed out.

To configure dates other than default (which are geared towards an annual membership), add a function similar to the membership descriptors and member types functions called membershipmanager_renewal_notices.

sub membershipmanager_renewal_notices {
  my ($FORM, %params) = @_;
  my ($query, $rv, $sth, $rowhash, @renewal_notices);

  $query = "SELECT DATE_FORMAT(NOW(), '%M %e, %Y') AS date_now,
                   DATE_FORMAT(DATE_ADD(NOW(), INTERVAL 7 DAY), '%M %e, %Y') AS date_7,
                   DATE_FORMAT(DATE_ADD(NOW(), INTERVAL -3 DAY), '%M %e, %Y') AS date_3_minus,
                   DATE_FORMAT(DATE_ADD(NOW(), INTERVAL -7 DAY), '%M %e, %Y') AS date_7_minus";
  ($rv, $sth) = &Library_global::do_standard_query($query, $Library_global::dbh);
  $rowhash = &Library_global::get_rowhash($sth);

  @renewal_notices = ({interval=>7,
                       title=>'First Notice: 7 Days Before Expiration',
                       custom_sentence=>"You have 14 days until your membership will expire on $rowhash->{'date_7'}!",
                       title=>'Second Notice: On Membership Expiration Day',
                       custom_sentence=>"Your membership will expire <b><font color=red>TODAY</font></b> on $rowhash->{'date_now'}!",
                       title=>'Third Notice: 14 Days After Expiration Day',
                       title=>'New Member Notice',
                       custom_sentence=>"We received your membership registration on $rowhash->{'date_3_minus'}!",

Searching Members

To search for members by specific fields, click "Search Members" on the admin index page. For each field you want to search, check the "Search By" checkbox, and enter the value you would like to find. Custom search links at the top of the page can be used for preset searches, or more complex reporting logic.

Search results can be exported to CSV by clicking the "Export to CSV" button at the top of any search results page. Additionally, one can export all information for all users by clicking "Export all Member Data".

The search page can be customized in several ways.

Advanced Search

Membership Manager supports more complex search queries, in what is formally known as "disjunctive normal form". You can search for any query of the form (A and B and C) or (D and E) .... The terms (A and B and C) and (D and E) would be individual "clauses" of the full search query. Advanced searches are iterative. As you build up a full search, intermediate results are still shown.

To begin an advanced search, select "Advanced Search" from the member search page. From top to bottom, the elements of the page are: current search parameters, controls to add a search parameter, and current search results. To add a search parameter, select the column to search for, then select either "AND" or "OR". The "AND" button will add the search term to the current clause, and the "OR" button will start a new clause. In this way, you can build up a complex search query like (site member AND in Virginia AND request local newsletter) OR (site member AND request all newsletters) from left to right. To see the results of your current search parameters at any time, select the "Search" button.

Additional Options

The template tag :::MEMBERSHIP_BALANCE::: can be used to let members quickly view and pay off their balance. This tag is ideal for use in a javascript pop-up interstitial.

The map LOCAL_MEMBERSHIPMANGER_POST_EDIT_TEMPLATE can be used to change the template seen by members after they sign up or edit their profile.

Mailman Integration

Membership Manager can take control of User Manager's Mailman integration, and add features above and beyond what would otherwise be possible. To enable the most basic level of functionality, set the LOCAL_MEMBERSHIPMANAGER_MAILMAN_LISTS map to 1. When this map is set, User Manager will no longer automatically subscribe new non-member users.

For more sophisticated and granular control, Membership Manager also provides per-member-type mailing lists that can be configured independently of the LOCAL_MEMBERSHIPMANAGER_MAILMAN_LISTS map. In your local library, you can add a field mailing_lists=>[qw(list1 list2 ...)] to a member type hash to specify a set of mailing lists. All members of that type will have those optional lists available to subscribe to. You may also add a field auto_subscribe_mailing_lists=>[qw(list1 list2 ...)]. Members will automatically be subscribed to these lists when they become that type of member.

Users vs Members

All members are users, but not all users are members. When a visitor signs up to become a member, they are given a user account at the same time. As such, almost all membership management administration takes place from the User Manager admin pages.

Using Coupon Codes

LunpaCMS has a relatively simple way of dealing with coupon codes. It will accept coupon codes that are then run as functions in the local library. i.e. If you want to have a user enter a BUY1GET1FREE coupon code, add a function called coupon_buy1get1free to the local library. This way, coupons are easily enabled and disabled by commenting out functions in the sites local library.

Use: :::COUPON_CODE:ARGS: input_size=15 ::: will place the coupon form with the action set to the correct submission script

Tag Options:

Example Coupon Function: This function checks some requirements and, if they are met, it credits back one of the items. Note: many of these kinds of situations should be dealt with by brute force.

sub coupon_buy1get1free {
  if ( *dont_meet_requirements* ) {
    return (0, $error);

  if ( *used_before* ) {
    return (0, $error);

  &Library_membershipmanager::record_user_membership_transaction($FORM, transaction_memo=>$memo, transaction_amount=>-30, transaction_item_number=>$trans_num, updated_by=>'1', user_id=>$user_id);

  return 1;


Membership Manager supports PayPal Subscriptions as an alternative to large up-front payments for many membership periods. To display a form to allow members to make recurring payments, use the tag :::RECURRING_PAYMENT_FORM:::.

PayPal does not allow for changing the payment date on a subscription. This means it is possible for a member to set a subscription that always pays late. In this event, an admin will be notified by email. The recommended way of resolving this issue is to pay for an additional single period of membership. This will shift your subscription from being late for this period, to being early for the next period.

Double-Entry Bookkeeping

Membership Manager uses a double entry book keeping system which is a very easy system. It keeps track of charges for everything in one location, with positive numbers indicating charges to the user and negative numbers indicating payments from the user. Thus, a user at a balance of $0 will have paid off anything they have agreed to paid for, whether it be registering for an event, membership dues, or any other miscellanea payments. A positive balance indicates that the user still owes money and a negative balance indicates a credit to the account.


You can access a member report with much of the information pertaining to each user's membership status by going to the user manager admin page and clicking on "User/Member Reports." The report lists how many users, members, and members who are current on their membership payments there currently are.

Membership Manager includes a monthly transaction report. The report is a summary of all transactions processed in the past month, categorized and arranged for verification against another accounting system. The report separates credits and debits, and categorizes event registrations, membership payments, and donations. At the start of each month, the report will be emailed to your website's PayPal account email address.

Every day, when members are checked for renewal payment status, an email is sent summarizing members who have let their membership lapse, and members who cannot be contacted by email. If no members have lapsed, and all members were able to be emailed, this report will not be sent. This email is sent to your website's PayPal account email address.

Rolling Membership Periods

Using Membership Manager to track membership dues allows you to have a rolling membership fee. That is, everyone receives an entire period starting on the day they pay instead of all members being charged on a single day. This avoids problems such as having, for instance, a yearly membership that dues are due on the 1st of January and one member paying on January 1st and another paying in December. Though the amount is the same, the member paying in December only receives membership for a month even though they pay the same amount as someone paying in January.

The way Membership Manager deals with this is by keeping track of 2 dates: The Membership Renewal Date and the Last Membership Charge date. The Membership Renewal Date is the date on which the member will be billed again, and the Last Membership Charge date was the date of the last charge. Once the Membership Renewal Date for any single member matches the current date, they are charged and their Last Membership Charge date is set to the current date. Therefore, if both of these dates are the same, the member is not currently paid up for their membership. Only when they pay does the Membership Renewal Date get pushed ahead for the amount of time they pay for and the cycle starts over again.

When will emails be sent?

Here is a list of every instance in where an email is sent by the membership management system (the combined features of PayPal Manager, Membership Manager, and Registration Manager):

How to Add a Member

Adding a member is as simple as going to admin usermanager page, clicking on "Create a User," and entering any necessary information. To make them a member, select the type of member they are supposed to be in the Admin Only Fields, and set the dates accordingly. This will engage the automatic billing code and email reminders when they are applicable to the user. For more information about managing a users transactions, see the "Managing a User's Transaction" section.

Managing a User's Account

To view and manage a user's transactions, go to the admin user manager page, find the user you want to edit and click "Edit" under actions. On the page where you edit their user information, there should be a link that says "View Transaction History" that will take you to their Transaction History. Once there, there are several options for managing the transactions:

  1. Add a New Transaction to User - Allows you to enter the following fields:
    • Transaction Memo - A note about what the transaction is for
    • Transaction Type - Debit is for charging the user, Credit is to indicate a payment of some kind
    • Transaction Amount - The amount the transaction is for
    • Change Member Type - Allows you to manually enter the member type and configure the various dates that control their membership. Member since is when they signed up for the account. Membership Renewal Date is the date the user will next be charged for membership. Last Membership Charge is the last time they were charged. If "Last Membership Charge" and "Membership Renewal Date" are the same, their membership has expired
    • Extend Current Membership Renewal Date by X - Easy way to extend the membership the appropriate amount. This field should be used over manually entering the renewal date if the user is submitted a membership payment.
    • Debit Account for Donation Received - This field is for entering a donation that is tacked onto another payment in order to keep their account balance at the appropriate level. See example below.
    If the membership for your website/organization is $20 a year. If a member sends a check for $25 (assuming the user has already been charged the $20 for membership, with $5 earmarked for donation), the procedure would be to enter:
    Transaction Memo: User membership payment plus donation to organization.
    Transaction Type: Credit
    Membership Type: Mark user as appropriate membership level
    Extend Current Membership Renewal Date by: 1 Year
    Debit Account for Donation Received: $5
    If you do not debit the account for the donation, the user's overall balance would be -$5.00.
  2. Send User Balance Notice Email - This sends the user an email reminding them of their balance, along with payment options
  3. Back to User Manager - takes you back to the admin user manager page.

Delayed Transactions

The Membership Manager, along with Paypal Manager, can deal with delayed transactions, mostly in the form of PayPal echecks. How this works is that PayPal will send two messages to the system, one that informs it that it is processing and another to let it know that it has been completed. This can take a few days to a week or more. There is no special action needed on the part of the admin, other than verifying that the payment came through. The user's balance will not be altered until the second PayPal message is received, so the system will take the appropriate action should the payments not come through on time, whether that is to not mark the user as a member or to disable their membership.

Advance Membership Payment

Admins can manually add multiple payment periods to a user, should they so desire. The way to enter this would be to add the amount of periods the user wishes to pay multiplied by the price of a single period as a positive transaction in the users transaction history. The user can then be sent a notification email, or the admin can manually enter the payment if they have already payed by entering the payment as a negative value.

Membership Discounts

Membership Manager has the ability to add a discount to a user's membership dues. To turn on the ability set the map LOCAL_MEMBERSHIPMANAGER_ALLOW_MEMBER_DISCOUNTS to 1. The user can be given a discount up to and including the total fee for their membership in $5 increments. If a user is pending payment, a transaction will appear in their transaction history deducting the amount set for them to discount. Users with completely deducted dues will not receive notifications and will remain members until manually changed.

How to use: If the map is set, a drop down box will show up in the user's profile in the admin section. Select a discount for the user and save their account information.

Email Warnings

The system will not send frivolous emails to admins. All warning emails are important and should be addressed as soon as possible. Warning emails should never be ignored. The reasons for a warning email to be sent to an admin include the following:

Performing an Audit

We do not provide any tools with assisting you with auditing and all payments recorded on the system should be checked against PayPal and other forms of payments received for any discrepancies.

Once a month an email will be sent with a transaction report that contains totals from all payments. This can be used to double check against your own records as an additional part of your own audits.

Multiple Membership Application Pages

Membership Applications can be split into two pages, user profile and then membership applications if desired.

Setting up multiple application pages:

  1. Add flag in profile_form that will trigger the membership form to be displayed after entering the user information: <input type='hidden' name='additional_member_template' value=1 >
  2. Create a template that will serve as the profile form for the membership fields. This is where :::MEMBERSHIP_DESCRIPTOR::: tags should be placed
  3. Add flag in the membership profile form to only process membership fields: <input type='hidden' name='member_form_only' value=1>
  4. Add hidden form field to pass the edit_id from the user profile form to the membership form in the admin profile form: <input type=hidden name=edit_id value=:::edit_id:::>
  5. Add the member_template parameter to the :::MEMBERSHIP::: tag in both the user and admin profile forms

1-Click Membership Resubscription/Grace Period

When a user is expired, there will be a link on the admin User/Membership index page that will resubscribe the user for a set number of days and allow them to easily pay for their membership. Note that this will reinstate the user to their full membership rights for the duration of the grace period, including adding them back to any mailing lists. If the user is within one period after their last membership due date, it will keep that same date and consider the next payment as a continuance of their regular membership, otherwise it will use the current date and will be as if they resubscribed today. For instance, if your membership period is one month and the user expired 5 days ago, if you use this feature it will use that same expiration date for the next month when they resubscribe, but if it is 35 days after the last expiration it will use the date you resubscribe them.

To set the number of days to allow this grace period, add or edit the map LOCAL_MEMBERSHIPMANAGER_RESUBSCRIBE_GRACE_PERIOD to the desired amount of days. The default for this map is 14 days.

Applying Transactions Requiring Attention to a User

Sometimes PayPal transactions are not automatically applied to a user for various reasons. To apply those transactions to proper users, refer Transactions Requiring Attention in LunpaCMS PayPal Manager documentation.

Add Your Comment

(Only a limited set of HTML tags such as <b>, <i>, <u> are allowed. Embedded flash video from Youtube or Vimeo are also supported.)

Copyright © 2023 Peregrine Computer Consultants Corp. All rights reserved.

About Lunpa, our mascot. Her mother was a hamster and her father was an ill-tempered Chilean M00se. Oddly, neither smelt of elderberries.
The artist is Jennifer Lomax.