Uploaded image for project: 'CiviCRM'
  1. CiviCRM
  2. CRM-7137

Auto-renew Option for Memberships (Authorize.net)

    Details

    • Type: New Feature
    • Status: Done/Fixed
    • Priority: Major
    • Resolution: Fixed/Completed
    • Affects Version/s: 3.3.0
    • Fix Version/s: 3.3.4
    • Component/s: CiviMember
    • Labels:
      None

      Description

      NOTE: This functionality will only be available when Authorize.net is used as the payment processor, and is dependent on completion of CRM-. However, we should review of the PayPal Pro API so that the implementation is general enough to support extending this functionality to PayPal Pro and other processors with recurring billing / subscription support.

      ========
      Summary
      ========
      This issue adds support for self-service and back-office creation of automatically renewing memberships. When an auto-renew membership is created, a recurring contribution (payment) is submitted to Authorize.net with instructions to repeat the payment on the membership end date. When Authorize.net notifies the CiviCRM site of a successful recurring payment, the associated membership record is renewed.

      Site administrators will be able to indicate which membership types "allow" auto-renwal. Separate Membership Renewal Reminder templates can be configured for manual vs. auto-renew memberships.

      When configuring online contribution pages for self-service membership signup - administrators can set auto-renew options for each membership type included in the block (options are "Not available", "Optional", "Required").

            • Auto-renew memberships are open-ended for this implementation (i.e. they will continue to renew until the member or admin staff cancels the auto-renew option). This assumes that Authorize.net allows an open-ended recurring billing / subscription (i.e. one that does NOT have an end date or fixed number of installments). PayPal Pro does allow this - so I assume we're ok. If this is NOT the case, then we will need to either add an interface for users to choose an End Date OR pass an end date to Authorize.net that is very far in the future. Please raise this for discussion if we can't request an open-ended "subscription".

      =============
      Implementation
      =============

      1. Schema Changes
      ----------------------------
      1.1 civicrm_membership
      Add column - contribution_recur_id, INT, default NULL, FK to civicrm_contribution_recur.id

      1.2 civicrm_membership_type
      Add column - auto_renew TINYINT(4), default 0
      values: 0 = No auto-renew option; 1 = Give option, but not required; 2 = Auto-renew required;

      Add column - autorenwal_msg_id, INT, default NULL, FK to civicrm_msg_template.id, User message template for sending renewal reminders to auto-renew memberships for this membership type.

      1.3 civicrm_membership_block
      Enabled membership type IDs for the block are currently stored in 'memberships' column (comma separated list of INTs). We need a way to store an auto-renew flag (INT) along with each of the membership types. We could store these in a new column OR transform 'membership' column into a serialized array. Depending on the solution - consider whether the selected default membership type (currently stored in 'membership_type_default') should be merged into the new data storage method.

      1.4 Upgrade
      Add columns / values set to default for 1.1 and 1.2.
      Convert values for membership_block.memberships if necessary (depending on design solution), and set auto-renew flag to 0 for all enabled membership types.

      2. Configure Membership Types
      --------------------------------------------
      Add / edit membership type form - new fields.

      2.1 Label = "Auto-renew Option"
      fieldname: auto_renew
      Field label is always displayed.

      If Authorize.net is an enabled processor display input field radio button:
      [ o] No auto-renew option [ ] Give option, but not required [ ] Auto-renew required

      Else display status div instead of input field:
      "You will need to select and configure a supported payment processor (currently Authornize.net) in order to offer automatically renewing memberships. (learn more...)"

      "learn more" link directs to wiki Payment Processor configuration main page.

      NOTE: The auto_renew flag at this level determines if auto-renew should be offered for back office and online membership signup and renewal, and set's a default value when configuring online membership blocks.

      2.2 Label: "Auto-renew Reminder Message"
      fieldname: autorenewal_msg_id

      Display this field conditionally in the "Renewal Reminders" fieldset (below renewal_msg_id) if auto_renew value = 1 or 2.

      3. Configure Contribution Page - Membership Settings
      -------------------------------------------------------------------------
      (Member/Form/MembershipBlock)
      If a processor which supports auto-renew is configured for this contribution page, extend the Membership Types table to include another column (placed to the left of the "Default" column).

      Column Header: "Auto-renew"
      For each membership_type[$i] row:

      • If membership_type.auto_renew = 0, cell in this table displays "(not available)"
      • If membership_type.autlo_renew = 1 or 2, cell in this table is drop-down with the following values
        <option value="0">Not offered
        <option value="1">Give option
        <option value="2">Required
        Default = 1 if membership_type.auto_renew =1
        Default = 2 if membership_type.auto_renew =2

      4. Online Membership Signup and Renewal
      -----------------------------------------------------------
      If user selects a membership type during signup OR renewal with auto_renew option = 1, inject a checkfox field as the last row in the membership_listings table:

      [ ] Please renew my membership automatically.

      If selected membership_type has auto_renew option = 2, inject hidden auto_renew field, and status mesage div: "Your membership will be renewed automatically."

      NOTE: Let's put the text for the displayed field prompt (for option 1) and status message (for option 2) in the template rather than in the PHP class so folks can adjust the text in the tpl file.

      See item 6. below for postProcess notes

      5. Offline Membership Signup and Renewal
      -----------------------------------------------------------
      If a supported auto-renew processor is selected in the "Submit Credit Card Membership" form (mode=live or mode=test), check for membership_type.auto_renew value after user selects membership type.

      If auto_renew = 1 (optional), add auto_renew checkbox field to form below the End Date field.
      [ ] Membership renewed automatically

      If auto-renew = 2 (required), include the auto_renew checkbox as a "checked" frozen field.

      6. Create Auto-renew Membership : postProcess Notes
      ---------------------------------------------------------------------------
      If auto_renew is selected when creating a new membership or renewing a membership which was NOT previously auto-renew:

      • insert contribution_recur record
        • set frequency_unit and frequency_interval to match membership type, installments is NULL
      • insert contribution record
      • insert or update membership record, setting membership.contribution_recur_id
      • insert membership_payment record

      The ARB request should be sent in the above sequence at the same point as we currently send the contribution API request for "regular" recurring contributions. Status assigning rules should be the same.

      Payment schedule sent to Authorize.net should trigger next payment on membership end date.

          • Please determine what we can / should send in the request to enable us to properly update the contribution_recur and (if needed) membership record when Authorize.net sends us IPNs. Is contribution_recur.id sufficient? Should we also pass membership.id?
          • I'm not sure what we currently do when the recurring billing request fails at Auth.net side? What records are created? Any notifications sent? Ping me to discuss once you've verified current behavior for the recurring contribution functionality.

      7. Canceling Membership Auto-renewal Option
      ---------------------------------------------------------------

          • Option 1 (preferred):
            We need to determine if there's an API / URL option which we can invoke to cancel an existing ARB. This will allow us to offer organization staff AND end-users (members) a CiviCRM URL to access that will cancel the ARB at Authorize.net AND update the contribution_recur status in the DB so we know this membership is no longer setup for auto-renew.

      If this option is available —
      7.1 Include the CiviCRM link for cancelling auto-renew at the bottom of the Online and Offline Membership Confirmation and Receipt templates. This link should probably include the contact authentication checksum. Link directs to a confirmation page: "Click the button below if you want to cancel the auto-renewal option for your $membershipType membership? This will not cancel your membership. However you will need to arrange payment for renewal when your membership expires."
      [ Cancel My Membership Auto-renewal ] <a href="$ufBaseUrl">Go to home page without canceling auto-renewal</a>

      NOTE: Page has 1 button and a link as shown above. (No "Cancel" button, since that would be confusing.)

      7.2 New action on membership selector for any row that is an auto-renew membership:
      "Cancel Auto-renewal"

      Action goes to same page as above, but replace "Go to home page" link with a simple "Back" link.

          • Option 2:
            If Cancelation can only be done by the user interacting with a form / page on Authorize.net –
            7.3 Include link to this page at the bottom of the Online and Offline Membership Confirmation and Receipt templates.

      DB Processing:
      Whether the cancellation is done via API (by CiviCRM code) or by the end-user at Auth.net, hopefully we get some IPN type notice and can set the civicrm_contribution_recur.status_id to Cancelled.

      Cancelation Notifications:
      I "think" that Authorize.net sends notification email to member (person who is being billed) with a cc: to the merchant account holder when an ARB is cancelled. If this does NOT happen, we should consider whether we can trigger a notice from our side (using a new System Message Template).

      8. Edit Membership record
      -------------------------------------
      I don't think we should allow back-office users to modify fields that affect membership fee or status if the membership is setup for auto-renew. Freeze the following fields:

      • Membership Type
      • End Date
      • Status Override

      ... and display the following status message div at the top of the form:

      {ts 1=$cancelAutoRenew}This membership is set to renew automatically on $end_date. You will need to cancel the auto-renew option if you want to modify the Membership Type, End Date or Membership Status. <a href="%1">Click here</a> if you want to cancel the automatic renewal option.{/ts}

      NOTE: Do not include the "click here to Cancel" sentence unless we are able to implement API-based back-office cancellations (see #7 above).

      9. Renew Membership / Renew Credit Card
      -----------------------------------------------------------
      We'll allow users to do back-office renewals in either mode for auto-renew memberships. However, we should alert them that they are manually renewing an "Auto-renew Membership". Put this message status div on top of the form if the membership has auto-renew (membership.contribution_recur_id NOT NULL and contribution_recur status is not Cancelled):
      {ts 1=$cancelAutoRenew}

      This membership is set to renew automatically on $end_date. If you continue and renew manually, the next automatic renewal will add an additional membership period to the end date. <a href="%1">Click here</a> if you want to cancel the automatic renewal option.

      {/ts}

      NOTE: Do not include the "click here to Cancel" sentence unless we are able to implement API-based back-office cancellations (see #7 above).

      10. View Membership
      ---------------------------
      Add display row to this page below End Date:
      Label: Auto-renew
      Values: Yes or No

      11. Membership Selector
      --------------------------------
      Contact tab, and membership search results / dashboard:

      • add column, header = "Auto-renew?"
      • if true for that record, display checkmark icon

      12. UpdateMembershipRecord.php script
      ------------------------------------------------------
      Administrators have the option to configure auto-renew reminder message by membership type (#2 above). Modify this script to use the configured autorenewal_msg_id message template when sending reminders IF the membership being processed is an auto-renew membership - determined by:

      • is membership.contribution_recur_id NOT NULL
      • contribution_status_id of the linked contribution_recur record is NOT Cancelled

        Attachments

          Activity

            People

            • Assignee:
              deepak Deepak Srivastava
              Reporter:
              dgg David Greenberg
            • Votes:
              0 Vote for this issue
              Watchers:
              0 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:

                Time Tracking

                Estimated:
                Original Estimate - Not Specified
                Not Specified
                Remaining:
                Time Spent - 5 weeks, 2 days, 3 hours Remaining Estimate - 2 days
                2d
                Logged:
                Time Spent - 5 weeks, 2 days, 3 hours Remaining Estimate - 2 days
                5w 2d 3h