Author: Predrag

  • Force VAT Field Visible And Default Customer Type To Business

    Summary

    Merchants using the MemberPress VAT add-on sometimes need to control the visibility and default behavior of the VAT Number field and Customer Type selector during checkout. Common requirements include always displaying the VAT Number field regardless of customer type selection, and defaulting the Customer Type to Business instead of Consumer to streamline VAT collection workflows.

    This document provides tested CSS and PHP customizations to achieve both behaviors. The solutions address edge cases where conditional field display logic interferes with business requirements for specific tax jurisdictions or compliance workflows. These customizations are not available through standard MemberPress settings and require code implementation via the WPCode plugin or child theme functions.

    Troubleshooting

    Implementing VAT Field Visibility And Customer Type Customizations

    The following implementation methods provide two distinct customization options that can be used independently or together. Option 1 forces the VAT Number field to always display and hides the Customer Type selector. Option 2 sets the default Customer Type selection to Business instead of Consumer.

    Method 1: Using WPCode Plugin (Recommended)

    1. Navigate to Dashboard > Code Snippets > + Add Snippet.
    2. Click Add Your Custom Code (New Snippet).
    3. Enter a title such as “Force VAT Field Visibility and Default Business Type”.
    4. Set Code Type to PHP Snippet.
    5. Paste the complete customization code provided in the Customization Snippet section below.
    6. Set Location to Run Everywhere.
    7. Enable the Active toggle.
    8. Click Save Snippet.
    9. Clear all site cache (plugin cache, server cache, and CDN cache if applicable).
    10. Test checkout flow while logged out to verify the VAT Number field displays immediately and Customer Type defaults to Business.

    Method 2: Using Child Theme Functions

    1. Access your site files via FTP or hosting file manager.
    2. Navigate to /wp-content/themes/[[CHILD_THEME_NAME]]/.
    3. Open the functions.php file for editing.
    4. Scroll to the end of the file and paste the complete customization code provided in the Customization Snippet section below.
    5. Save the file.
    6. Clear all site cache (plugin cache, server cache, and CDN cache if applicable).
    7. Test checkout flow while logged out to verify the VAT Number field displays immediately and Customer Type defaults to Business.

    Important: If the site frequently changes themes, using the child theme method may result in lost customizations. The WPCode plugin method is preferred for long-term maintenance and will persist across theme changes.

    Customization Snippet

    Add the following code block using either Method 1 or Method 2 above. Both Option 1 and Option 2 are included in this snippet. To disable either option, comment out the relevant section by adding // before each line in that section.

    /**
     * MemberPress - VAT Customer Type Customizations
     * 
     * PURPOSE:
     * - Option 1: Hide Customer Type field and always show VAT field.
     * - Option 2: Set "Business" as the default Customer Type selection.
     *
     * HOW TO USE:
     * - Keep both Option 1 and Option 2 enabled, or disable either by commenting it out.
     * - Prefer adding this via a code snippets plugin (e.g., WPCode) or an mu-plugin.
     *
     * REQUIREMENTS:
     * - MemberPress active.
     *
     * NOTES:
     * - CSS selectors rely on current VAT add-on markup:
     *   .mepr_vat_customer_type_row and .mepr_vat_number_row
     * - If markup changes in future versions, update selectors accordingly.
     */
    
    // -------- Option 1: Hide Customer Type field and always show VAT field --------
    function mepr_hide_customer_type_field() {
      ?>
      <style>
        .mepr_vat_customer_type_row { display: none !important; }
        .mepr_vat_number_row { display: block !important; }
      </style>
      <?php
    }
    add_action( 'wp_head', 'mepr_hide_customer_type_field' );
    
    // -------- Option 2: Set Business as default Customer Type selection ----------
    /**
     * Filter: mepr_vat_customer_type_default
     * Expected return values: 'consumer' or 'business'
     */
    function mepr_set_default_customer_type_business( $customer_type ) {
      // If no customer type is set (first load) or detected as consumer, default to 'business'.
      if ( empty( $customer_type ) || 'consumer' === $customer_type ) {
        return 'business';
      }
      return $customer_type;
    }
    add_filter( 'mepr_vat_customer_type_default', 'mepr_set_default_customer_type_business' );

    Understanding The Customization Options

    1) VAT Number Field Only Shows After Customer Type Selection

    By default, the MemberPress VAT add-on conditionally displays the VAT Number field based on the Customer Type selection. The field only appears after a customer selects Business from the Customer Type dropdown. This creates additional friction in the checkout process for businesses that primarily serve B2B customers or operate in jurisdictions where VAT collection is mandatory for all transactions.

    How to Test/Fix: Option 1 in the customization snippet uses CSS to force the VAT Number field to display immediately on page load by setting .mepr_vat_number_row to display: block !important. It simultaneously hides the Customer Type selector by setting .mepr_vat_customer_type_row to display: none !important. This ensures customers see the VAT Number field without needing to interact with the Customer Type dropdown first. After implementing Option 1, test the checkout page while logged out and verify the VAT Number field is visible before any form interaction. If the field does not appear, clear all cache layers and check browser console for CSS conflicts with theme or other plugin styles.

    2) Customer Type Defaults To Consumer Instead Of Business

    The MemberPress VAT add-on defaults the Customer Type selection to Consumer. This creates unnecessary steps for merchants whose primary customer base consists of businesses rather than individual consumers. In B2B-focused scenarios or regions with mandatory VAT collection requirements, defaulting to Business streamlines the checkout experience and reduces form abandonment.

    How to Test/Fix: Option 2 in the customization snippet uses the mepr_vat_customer_type_default filter to change the default Customer Type selection to Business. The filter function checks if the customer type value is empty or set to consumer, then returns business instead. This modification occurs before the checkout form renders, ensuring the Business option is pre-selected. If using Option 2 without Option 1, customers can still manually change the selection to Consumer if needed. After implementing Option 2, test the checkout page while logged out. Verify that the Customer Type dropdown shows Business as the selected option. If the Business option is not pre-selected, verify the filter name matches the exact hook used by your VAT add-on version. Clear all cache and test again.

    3) CSS Customization Not Applying After Code Implementation

    After adding the customization code, the VAT Number field may still not display or the Customer Type field may remain visible. This typically occurs when aggressive caching prevents the new CSS rules from loading, or when theme or plugin CSS specificity overrides the custom styles.

    How to Test/Fix: First, clear all cache layers including WordPress cache plugins, server-side cache, and CDN cache. If using a page builder like Elementor or Divi, regenerate CSS files from the builder settings. Test the checkout page in a private browser window to bypass browser cache. If the customization still does not apply, use browser developer tools to inspect the VAT Number field element. Check if the .mepr_vat_number_row class is present and verify which CSS rules are being applied. If theme or plugin styles have higher specificity than the custom CSS, increase specificity by adding the !important declaration or by prefixing the selector with body or html. For example, change .mepr_vat_number_row { display: block !important; } to body .mepr_vat_number_row { display: block !important; }.

    4) Filter Not Changing Default Customer Type Selection

    After implementing Option 2, the Customer Type dropdown may still default to Consumer instead of Business. This occurs when the filter hook name does not match the exact hook provided by the installed VAT add-on version, or when another plugin or theme function hooks into the same filter with higher priority.

    How to Test/Fix: Verify the exact filter hook name used by the VAT add-on by checking the add-on source code. Navigate to /wp-content/plugins/memberpress-vat/ and search for instances of apply_filters related to customer type defaults. Common variations include mepr_vat_customer_type_defaultmemberpress_vat_customer_type, or mpvat_customer_type_default. Update the filter name in the customization code to match the exact hook name found in the add-on files. If the correct hook is used but the filter still does not apply, add a third parameter to the add_filter call to set higher priority. Change add_filter( ‘mepr_vat_customer_type_default’, ‘mepr_set_default_customer_type_business’ ) to add_filter( ‘mepr_vat_customer_type_default’, ‘mepr_set_default_customer_type_business’, 99 ). This ensures the custom filter executes after other plugins or theme functions.

    Important Limitations And Considerations

    • The CSS selectors .mepr_vat_customer_type_row and .mepr_vat_number_row depend on current VAT add-on markup. Future add-on updates may change these class names, requiring selector updates in the customization code;
    • Option 1 completely hides the Customer Type selector. Customers cannot toggle between Consumer and Business after implementation. If business logic requires customer type selection, use Option 2 only;
    • Option 2 defaults to Business but allows customers to manually change selection if the Customer Type field remains visible. Combine with Option 1 to enforce Business-only checkout flow.
    • These customizations affect frontend display and default form behavior only. VAT calculation logic remains controlled by MemberPress VAT add-on settings under Dashboard > MemberPress > Settings > Taxes;
    • Aggressive cache plugins may prevent CSS changes from displaying immediately. Always clear cache after code implementation and test in private browser windows during verification;
    • Child theme customizations will be lost if the parent theme is changed or if the child theme is deactivated. WPCode plugin implementation persists across theme changes and is recommended for long-term maintenance.

    Public Facing Documentation / Additional References

    Public Facing Documentation

    Developer Documentation

  • How to Bulk-Refresh MemberPress Member Data via URL

    Summary

    This document explains how to rebuild MemberPress member data for a defined range of users using a URL-triggered admin action. This method synchronizes member statistics such as transaction counts, active transaction counts, and membership lists when the Members page or user profiles display incorrect data.

    The solution provided uses the MeprUser->update_member_data() method through a secure, admin-only PHP snippet. This approach is necessary when member data becomes desynchronized due to bulk imports, manual database edits, or custom integrations that bypass normal MemberPress workflows.

    Troubleshooting

    Understanding Member Data Desynchronization

    MemberPress stores calculated member statistics in user meta fields. These fields include transaction counts, active membership lists, and subscription statuses. When transactions or subscriptions are created outside normal MemberPress processes, these cached values become outdated.

    1) Incorrect Transaction Counts on Members Page

    The Members page displays inaccurate transaction totals or active transaction counts. Members show zero transactions when they actually have completed purchases, or the count does not match the actual number of transactions in the database.

    This typically occurs after bulk user imports, manual transaction creation via SQL scripts, or when third-party plugins modify transaction data directly in the database without triggering MemberPress update hooks.

    How to Test/Fix:

    1. Navigate to Dashboard > MemberPress > Members.
    2. Identify users with incorrect transaction counts.
    3. Note the user ID range that requires updating (visible in the browser URL when editing a user).
    4. Implement the bulk refresh solution described in the Implementation Steps section below.
    5. After execution, refresh the Members page and verify transaction counts are accurate.
    6. Compare the displayed counts with actual transaction records in Dashboard > MemberPress > Transactions.

    2) Missing or Stale Membership Lists After Data Migration

    After migrating from another membership plugin or importing user data from external sources, member profiles do not show accurate membership lists. The memberships and inactive_memberships meta fields are empty or contain outdated information.

    This occurs because MemberPress calculates membership lists based on active subscriptions and transactions. When these records are imported without proper MemberPress API calls, the cached membership data is not generated.

    How to Test/Fix:

    1. Access a user profile from Dashboard > Users.
    2. Scroll to the MemberPress section to view current memberships.
    3. If memberships are missing but transactions exist in Dashboard > MemberPress > Transactions, member data is desynchronized.
    4. Use the bulk refresh solution to rebuild membership lists for affected user ID ranges.
    5. After execution, verify that membership lists accurately reflect active and inactive subscriptions.

    3) Incorrect Active Transaction Counts After Corporate Accounts Setup

    When using MemberPress Corporate Accounts or manually creating parent-child user relationships, the active_txn_count field does not reflect sub-account transactions correctly. Parent accounts may show zero active transactions even when sub-accounts have active subscriptions.

    Corporate account relationships require special handling in MemberPress data calculations. When these relationships are created manually or through custom code, the member data calculation logic may not account for sub-account transactions.

    How to Test/Fix:

    1. Navigate to the parent user profile in Dashboard > Users.
    2. Check the MemberPress section for active transaction count.
    3. Verify sub-account transactions exist in Dashboard > MemberPress > Transactions.
    4. If counts are inaccurate, determine the user ID range for parent and sub-accounts.
    5. Execute the bulk refresh solution for the entire corporate account user range.
    6. Confirm that parent accounts now display correct aggregated transaction data.

    Implementation Steps

    Critical Warning: Always create a complete database backup before executing any bulk data operations. Test this solution on a staging environment first. Do not process more than 1,000 users per request to prevent server timeouts or memory exhaustion.

    Prerequisites

    Before implementing this solution, verify the following requirements:

    • You are logged in as an Administrator with manage_options capability;
    • MemberPress plugin is active and functional on your site;
    • The site is running in a staging environment or during low-traffic periods;
    • You have identified the specific user ID range that requires data refresh;
    • A complete database backup has been created and verified.

    Step 1: Create a Site-Specific Plugin

    1. Navigate to Dashboard > Plugins > Add New.
    2. Click Create a new plugin or manually create a file under wp-content/mu-plugins/.
    3. Name the plugin “MemberPress – Rebuild Member Data by Range”.
    4. If creating manually, name the file memberpress-rebuild-member-data.php.

    Step 2: Add the PHP Code Snippet

    Paste the following code into your plugin file:

     $end_id) {
        wp_die('Invalid user ID range. Please provide valid start_id and end_id parameters.');
      }
      
      // Enforce maximum range limit
      $max_range = 1000;
      if (($end_id - $start_id) > $max_range) {
        wp_die("Range too large. Maximum allowed range is {$max_range} users per request.");
      }
      
      // Define which member data columns to update
      $update_columns = ['txn_count','active_txn_count','memberships','inactive_memberships'];
      
      // Initialize tracking variables
      $processed_users     = 0;
      $successful_updates  = 0;
      $errors              = [];
      $start_time          = microtime(true);
      
      // Adjust PHP settings for bulk operation
      @set_time_limit(0);
      @ini_set('memory_limit','512M');
      
      // Process each user in the specified range
      for ($member_id = $start_id; $member_id <= $end_id; $member_id++) {
        try {
          // Verify user exists before processing
          $wp_user = get_user_by('id', $member_id);
          if (!$wp_user) { continue; }
          
          $processed_users++;
          
          // Create MeprUser object and update member data
          $user = new MeprUser($member_id);
          if ($user && !empty($user->ID)) {
            $user->update_member_data($update_columns);
            $successful_updates++;
          }
        } catch (Throwable $e) {
          $errors[] = "User ID {$member_id}: " . $e->getMessage();
        }
        
        // Add throttling delay every 50 users to prevent server overload
        if ($processed_users % 50 === 0) { usleep(100000); }
      }
      
      // Calculate execution time
      $execution_time = round(microtime(true) - $start_time, 2);
      
      // Build result message
      $message  = "MemberPress member data update completed!
    "; $message .= "User ID range: {$start_id} to {$end_id}
    "; $message .= "Users processed: {$processed_users}
    "; $message .= "Successful updates: {$successful_updates}
    "; $message .= "Updated columns: " . implode(', ', $update_columns) . "
    "; $message .= "Execution time: {$execution_time} seconds
    "; if (!empty($errors)) { $message .= "Errors encountered: " . count($errors) . "
    "; $message .= "First 5 errors: " . implode('
    ', array_slice($errors, 0, 5)); } // Display admin notice with results add_action('admin_notices', function() use ($message) { echo 'Member Data Update:
    '.$message.''; }); });

    Step 3: Save and Activate the Plugin

    1. Save the plugin file.
    2. If using the Plugins interface, click Activate.
    3. If using must-use plugins directory (mu-plugins), the plugin activates automatically.
    4. Verify the plugin appears in Dashboard > Plugins > Installed Plugins.

    Step 4: Execute the Member Data Refresh

    1. Determine the user ID range that requires updating. User IDs are visible when editing users in Dashboard > Users (check the URL parameter).
    2. Construct the admin URL using this format: https://yourdomain.com/wp-admin/admin.php?page=memberpress-members&update_member_data=1&start_id=[[START_ID]]&end_id=[[END_ID]]
    3. Replace [[START_ID]] and [[END_ID]] with your actual user ID range.
    4. Example: https://yourdomain.com/wp-admin/admin.php?page=memberpress-members&update_member_data=1&start_id=19900&end_id=19999
    5. Visit the constructed URL in your browser while logged in as an administrator.

    Step 5: Review Execution Results

    After the script completes, a green admin notice appears at the top of the page with the following information:

    • User ID range processed;
    • Total users processed (only existing users are counted);
    • Successful updates completed;
    • List of updated data columns;
    • Total execution time in seconds;
    • Error summary (if any errors occurred during processing).

    Step 6: Verify Data Accuracy

    1. Navigate to Dashboard > MemberPress > Members.
    2. Locate users within the processed ID range.
    3. Verify that transaction counts and membership lists display correctly.
    4. Check individual user profiles in Dashboard > Users to confirm the MemberPress section shows accurate data.
    5. Cross-reference displayed counts with actual transaction records in Dashboard > MemberPress > Transactions.

    Processing Large User Datasets

    For sites with thousands of users requiring data refresh, process users in batches of 1,000 or fewer. The built-in range limit prevents server overload and timeout errors.

    Batch Processing Example:

    1. First batch: start_id=1000&end_id=1999
    2. Second batch: start_id=2000&end_id=2999
    3. Third batch: start_id=3000&end_id=3999
    4. Continue until all affected users are processed.

    Wait for each batch to complete before starting the next batch. Monitor execution time and error messages to identify any persistent issues.

    Understanding What Gets Updated

    The update_member_data() method refreshes the following user meta fields:

    • txn_count: Total number of completed transactions for the user;
    • active_txn_count: Number of currently active transactions (non-expired, non-cancelled subscriptions);
    • memberships: Serialized array of active membership IDs;
    • inactive_memberships: Serialized array of expired or cancelled membership IDs.

    Important: This operation only updates cached member statistics stored in user meta. It does not modify, create, or delete any actual transaction or subscription records. All changes are safe and reversible by running the refresh again.

    Troubleshooting Execution Issues

    4) Script Execution Times Out Before Completion

    When processing large user ranges, the script may exceed the server’s maximum execution time limit, resulting in incomplete updates and timeout errors displayed in the browser.

    How to Test/Fix:

    1. Reduce the user ID range to fewer than 500 users per request.
    2. Contact your hosting provider to temporarily increase PHP execution time limits.
    3. Modify the script to add @set_time_limit(300); for a specific timeout value (300 seconds in this example).
    4. Process users in smaller batches and track progress manually.
    5. Consider using WP-CLI with wp eval-file for command-line execution without web server timeouts.

    5) Memory Exhaustion Errors During Bulk Processing

    The script may trigger PHP memory limit errors when processing user ranges on shared hosting environments with restricted memory allocation. The error message typically displays “Allowed memory size of X bytes exhausted”.

    How to Test/Fix:

    1. Reduce the user ID range to 250-500 users per request.
    2. Contact your hosting provider to temporarily increase PHP memory limits.
    3. Modify the @ini_set('memory_limit','512M'); line to a lower value like ‘256M’ if 512M is not available.
    4. Run the script during off-peak hours when server resources are more available.
    5. Disable unnecessary plugins temporarily to free up memory during execution.

    6) Admin Notice Shows Zero Users Processed

    The execution completes without errors, but the admin notice reports zero users processed even though the specified ID range contains valid users.

    This occurs when the user ID range does not contain any existing WordPress users, or when all users in the range have been deleted.

    How to Test/Fix:

    1. Navigate to Dashboard > Users and verify that users exist in the specified ID range.
    2. Edit a user to view their user ID in the browser URL (user_id=123 parameter).
    3. Adjust your start and end ID parameters to match actual user IDs on your site.
    4. Run a test query in phpMyAdmin or database management tool: SELECT ID FROM wp_users WHERE ID BETWEEN 1000 AND 2000;
    5. Use the returned IDs to construct an accurate user range for the refresh script.

    Security and Performance Considerations

    The provided code includes multiple security and performance safeguards:

    • Administrator-only access: Requires manage_options capability to execute.
    • MemberPress availability check: Verifies MemberPress is active before processing;
    • Input validation: Validates all URL parameters before execution;
    • Range limits: Enforces maximum 1,000 user range per request;
    • Error handling: Catches and logs exceptions without stopping execution;
    • Throttling: Adds 100ms delay every 50 users to prevent server overload;
    • Resource allocation: Adjusts PHP timeout and memory limits for bulk operations.

    Important Security Note: Remove or deactivate this plugin after completing your member data refresh. Leaving URL-triggered admin actions active creates potential security risks. Store the code in your documentation for future use if needed.

    When to Use This Solution

    This bulk refresh method is appropriate for the following scenarios:

    • After migrating from another membership plugin to MemberPress;
    • Following bulk user imports or database restoration from backups;
    • When custom integrations create transactions without using MemberPress API;
    • After manually editing transaction or subscription data in the database;
    • When member statistics appear incorrect after setting up Corporate Accounts;
    • Following server migrations or database synchronization issues.

    For individual user data issues or small numbers of affected accounts, use the built-in MemberPress tools in the user profile editor rather than bulk processing.

    Public Facing Documentation / Additional References

    Public Facing Documentation

    Developer Documentation

    Additional References

  • MemberPress Page Builder Post Filters Not Working with Protected Content

    Summary

    When using page builders to create custom post displays with category or tag filters, the filtering functionality may fail on sites with MemberPress-protected posts. The page refreshes without actually filtering the posts, preventing users from narrowing down content displays as expected.

    This article explains why this occurs and provides the solution to restore filtering functionality while maintaining content protection.

    Troubleshooting

    Page Builder Filters Refresh Without Filtering Protected Posts

    When a page builder (such as Elementor, Beaver Builder, Divi, or similar) creates a custom post grid or list with filter controls (category, tag, or custom taxonomy filters), clicking the filters may cause the page to refresh without applying the selected filter.

    1) Issue: MemberPress REST API Protection Blocks Page Builder Queries

    MemberPress includes REST API search discovery protection that prevents unauthorized access to protected content through the WordPress REST API. While this security feature is important, it can interfere with page builders that rely on REST API access for legitimate frontend functionality.

    Page builders typically use the REST API to dynamically load and filter post data on the frontend. When MemberPress’s REST API protection is enabled, it treats these page builder queries the same way it treats direct attempts to access protected content, blocking the requests even though the filtering functionality itself isn’t an attempt to bypass protection.

    How to Test/Fix:

    1. Navigate to WordPress Dashboard > MemberPress > Settings.
    2. Click the General tab.
    3. Locate the Enable WP Rest API search discovery protection setting.
    4. Uncheck this option.
    5. Click Save Options at the bottom of the page.
    6. Return to your page builder-created post display and test the filter functionality.

    The filters should now work as expected, allowing visitors to filter posts by category, tag, or other taxonomies without the page refreshing without results.

    Important Considerations

    When disabling REST API search discovery protection, keep in mind:

    • Protected post content remains secure through MemberPress’s standard access rules.
    • Only the REST API’s ability to discover protected posts in search results is affected.
    • Visitors still cannot view protected content without proper membership access.
    • The page builder can query post metadata for filtering purposes without compromising security.

    Docs / Additional References

    Public Facing Documentation

    Additional References

  • MemberPress Members Disappearing After WP Engine Automatic Backup and Restore

    Summary

    WP Engine hosting includes an automatic backup feature that creates site backups before plugin updates are performed. This safeguard prevents failed plugin updates from crashing sites by enabling automatic restoration to the pre-update state. However, this backup and restore process can cause MemberPress members and their associated data to disappear if they register during the backup window.

    This article explains how WP Engine’s automatic backup timing can result in member data loss. It provides diagnostic steps to identify when this issue has occurred and solutions to prevent future occurrences.

    Troubleshooting

    Understanding the WP Engine Automatic Backup Process

    WP Engine automatically creates backups before plugin updates execute. The backup duration varies based on site size, database complexity, and server load. Large membership sites with extensive transaction histories may require one to three hours for backup completion. During this window, the site remains operational and members can register, make purchases, and access content.

    If a plugin update encounters an error after backup completion, WP Engine automatically restores the site to the pre-update backup state. This restoration reverts all database changes that occurred after the backup timestamp, including new member registrations, subscription purchases, and profile updates.

    Identifying When Members Are Missing Due to Backup Restoration

    1) Member Reports Registration Completion But Account Does Not Exist

    A member completes the registration process and receives confirmation emails, but their account cannot be found in the WordPress user database. Payment gateway records show successful transaction processing, but no corresponding MemberPress subscription exists.

    How to Test/Fix:

    1. Navigate to Dashboard > Users > All Users and search for the member’s email address.
    2. Navigate to Dashboard > MemberPress > Subscriptions and search for the member’s name or email.
    3. Check the payment gateway dashboard for the transaction timestamp.
    4. Contact WP Engine support to request backup and restoration logs for the date in question.
    5. Compare the member’s registration timestamp with WP Engine’s backup and restore timestamps.
    6. If the registration occurred between backup start and restore completion, the account was lost during restoration.

    2) Multiple Members Missing From Same Time Period

    Several members report missing accounts, and all registrations occurred within a specific timeframe. Transaction records exist in payment gateways, but corresponding WordPress user accounts and MemberPress subscriptions are absent.

    How to Test/Fix:

    1. Document all reported missing member registration timestamps.
    2. Access the WP Engine hosting dashboard.
    3. Navigate to Backups section.
    4. Review backup history for automatic backups created during the reported timeframe.
    5. Look for restoration events that occurred after these backups.
    6. Check WP Engine email notifications for plugin update failure alerts.
    7. If restoration occurred after member registrations, all accounts created during that window were lost.
    8. Manually recreate affected member accounts using payment gateway transaction records.

    3) Member Data Exists in Payment Gateway But Not in MemberPress

    Payment processors show completed transactions with customer details, but MemberPress has no record of subscriptions or transactions. The WordPress user account may exist without associated MemberPress subscription data.

    How to Test/Fix:

    1. Access the payment gateway dashboard and export transaction records for the affected timeframe.
    2. Navigate to Dashboard > MemberPress > Transactions.
    3. Search for transaction IDs from the payment gateway records.
    4. If transactions are missing, navigate to Dashboard > MemberPress > Subscriptions.
    5. Search for subscriptions matching the payment gateway customer IDs.
    6. If no subscriptions exist, contact WP Engine support to verify restoration events.
    7. Manually create MemberPress transactions and subscriptions using the payment gateway data.
    8. Navigate to Dashboard > MemberPress > Transactions > Add New.
    9. Enter transaction details matching payment gateway records.
    10. Link transactions to the appropriate membership plans and user accounts.

    Preventing Future Member Data Loss

    Configure WP Engine Backup Settings

    1. Log into the WP Engine hosting dashboard.
    2. Navigate to the Backups section for your environment.
    3. Review automatic backup scheduling settings.
    4. Consider disabling automatic plugin update backups if member registration timing conflicts are frequent.
    5. Schedule manual backups during low-traffic periods instead.
    6. Enable WP Engine email notifications for all backup and restoration events.

    Important: Disabling automatic backups before plugin updates increases risk if plugin updates fail. Evaluate whether manual backup scheduling during low-traffic periods provides better protection for membership sites with continuous registration activity.

    Implement External Backup Solutions

    WP Engine backups serve hosting infrastructure needs. Membership sites with high registration volume should implement additional backup strategies to capture member data changes in near real-time.

    1. Install a dedicated WordPress backup plugin that supports incremental backups.
    2. Configure backup schedules that align with peak registration periods.
    3. Store backups offsite using cloud storage services.
    4. Test restoration processes regularly to ensure member data integrity.
    5. Document backup and restoration procedures for support team reference.

    Monitor Payment Gateway Webhooks

    Payment gateway webhooks provide independent records of transaction completion. These records can identify discrepancies between payment processing and MemberPress subscription creation.

    1. Navigate to Dashboard > MemberPress > Settings.
    2. Click the Payments tab.
    3. Select the active payment gateway.
    4. Verify webhook configuration is correct.
    5. Review webhook delivery logs in the payment gateway dashboard.
    6. Implement monitoring to alert when webhook delivery failures occur.
    7. Cross-reference payment gateway transaction logs with MemberPress transaction records daily.

    Recovering Lost Member Data

    Manual Member Account Recreation

    When WP Engine restoration causes member data loss, manual recreation using payment gateway records is necessary. This process restores member access and maintains transaction history accuracy.

    1. Export transaction records from the payment gateway for the affected timeframe.
    2. Navigate to Dashboard > Users > Add New.
    3. Create user accounts using email addresses from payment gateway records.
    4. Set temporary passwords and enable Send User Notification option.
    5. Click Add User.
    6. Navigate to Dashboard > MemberPress > Subscriptions > Add New.
    7. Select the member’s username from the Member dropdown.
    8. Select the appropriate membership plan from the Membership dropdown.
    9. Enter subscription start date matching the payment gateway transaction timestamp.
    10. Configure subscription status as Active.
    11. Click Create.
    12. Navigate to Dashboard > MemberPress > Transactions > Add New.
    13. Link the transaction to the newly created subscription.
    14. Enter transaction details matching payment gateway records.
    15. Set transaction status to Complete.
    16. Click Create.
    17. Notify the member that their account has been restored and provide login credentials.

    Note: Manual transaction creation bypasses normal payment processing workflows. Ensure payment gateway records confirm successful payment completion before creating MemberPress transactions. Do not create transactions for refunded or failed payments.

    Public Facing Documentation / Additional References

    Public Facing Documentation

    Developer Documentation

    Additional References

  • How to Configure MemberPress Brexit VAT Rules for UK Merchants

    Summary

    MemberPress includes a default Brexit VAT rule that applies specifically to UK merchants. This rule automatically hides VAT fields and prevents VAT calculations for all non-GB (non-UK) customers, including EU customers. While this addresses Brexit-related tax changes, it can create limitations for UK merchants who need more flexible VAT handling.

    This document provides step-by-step instructions for overriding the default Brexit VAT rule using the mepr_vat_should_apply_gb_brexit_rule filter. The solution allows UK merchants to handle VAT like EU merchants, enabling proper VAT exemptions for EU businesses and providing greater compliance flexibility for complex tax scenarios.

    Troubleshooting

    Understanding Brexit VAT Rule Behavior

    The default Brexit VAT rule affects how MemberPress handles VAT for UK merchants. When active, this rule simplifies tax handling but may not meet all business requirements for EU customer interactions.

    Default Brexit Rule Behavior:

    • VAT fields are hidden for all non-GB customers;
    • VAT calculations are disabled for EU customers;
    • EU businesses cannot enter VAT numbers for exemptions;
    • All non-UK customers are treated the same regardless of location;

    1) EU Business Customers Cannot Claim VAT Exemption

    UK merchants may need to provide VAT exemptions to EU businesses with valid VAT numbers, but the Brexit rule prevents this functionality by hiding VAT fields for all non-UK customers.

    How to Test/Fix:

    1. Navigate to Dashboard > Plugins > Add New and search for WPCode (recommended method).
    2. Install and activate the WPCode plugin.
    3. Go to Dashboard > Code Snippets > Add Snippet.
    4. Select Add Your Custom Code (New Snippet).
    5. Set the code type to PHP Snippet.
    6. Enter the title: “Override MemberPress Brexit VAT Rule”.
    7. Add the following code in the code editor:
    // Override UK Brexit VAT condition to allow EU business VAT exemptions
    add_filter('mepr_vat_should_apply_gb_brexit_rule', '__return_false');
    1. Set the snippet to Active.
    2. Click Save Snippet.
    3. Test with an EU customer account to verify VAT fields appear.

    2) Adding Code to Child Theme Functions.php

    Users who prefer to add custom code directly to their theme files can use the child theme’s functions.php file instead of a plugin.

    How to Test/Fix:

    1. Navigate to Dashboard > Appearance > Theme Editor.
    2. Select your active child theme from the dropdown menu.
    3. Click on functions.php from the file list.
    4. Scroll to the bottom of the file.
    5. Add the following code before the closing PHP tag (if present):
    // Override UK Brexit VAT condition to allow EU business VAT exemptions
    add_filter('mepr_vat_should_apply_gb_brexit_rule', '__return_false');
    1. Click Update File.
    2. Clear any caching plugins.
    3. Test VAT functionality with different customer types.

    Important: Always use a child theme when editing theme files. Changes to the parent theme will be lost during theme updates.

    VAT Behavior After Applying Override

    Once the Brexit VAT rule is disabled, UK merchants will handle VAT calculations similarly to EU merchants, providing more granular control over tax applications.

    UK Customers:

    • Can select Consumer or Business customer type;
    • VAT is charged at the standard rate (typically 20%) for both Consumer and Business purchases;
    • Business customers cannot claim VAT exemption within the UK;

    EU Customers:

    • Can select Consumer or Business customer type;
    • Consumer customers are charged VAT at the standard rate (20%);
    • Business customers with valid VAT numbers receive 0% VAT rate;
    • VAT validation occurs automatically when valid VAT numbers are entered;

    Non-EU Customers:

    • Behavior remains unchanged from the default Brexit rule;
    • No VAT is applied to non-EU purchases;
    • VAT fields may still appear but calculations remain at 0%;

    3) Code Not Working with Stripe Tax Integration

    The Brexit VAT override only functions with MemberPress’s default VAT settings and does not affect Stripe Tax configurations.

    How to Test/Fix:

    1. Navigate to Dashboard > MemberPress > Settings.
    2. Click on the Payments tab.
    3. Verify that Stripe Tax is not enabled in your payment gateway settings.
    4. If using Stripe Tax, VAT rules must be configured directly in your Stripe Dashboard.
    5. For Stripe Tax configurations, navigate to Stripe Dashboard > Tax Settings.
    6. Configure Brexit-related tax rules within Stripe’s tax management interface.
    7. Test checkout process to ensure proper tax calculations.

    Warning: This only works with the default VAT settings (Setting Up VAT Taxes), not Stripe VAT (Using Stripe Tax With MemberPress). Stripe taxes must be configured on the Stripe account, not MemberPress.

    Public Facing Documentation / Additional References

    Public Facing Documentation

    Developer Documentation

  • How to Add Section Completion Indicators in MemberPress Courses

    Summary

    By default, MemberPress Courses highlights individual lessons and quizzes when completed, but it does not provide visual indicators when an entire section is complete. This can create confusion for learners who need a clearer overview of their overall progress through course sections.

    This document provides a custom code solution that adds visual completion indicators (green background highlight and checkmark) to course sections when all lessons, quizzes, and assignments within that section are completed.

    Troubleshooting

    Prerequisites and Setup Requirements

    Before implementing section completion indicators, ensure your site meets the following requirements:

    • MemberPress plugin installed and activated;
    • MemberPress Courses add-on installed and activated;
    • Access to edit your theme’s functions.php file or ability to create a site-specific plugin;
    • Basic understanding of PHP code implementation;

    1) No Visual Indicator When Entire Course Section Is Completed

    Users complete all lessons and quizzes within a course section, but the section header does not show any visual indication that the entire section is finished. Individual lesson completion is visible, but section-level progress tracking is missing.

    How to Test/Fix:

    1. Navigate to Dashboard > Appearance > Theme Editor or access your site files via FTP/cPanel.
    2. Locate and open your active theme’s functions.php file.
    3. Add the following complete code snippet at the end of the file, before the closing ?> tag:
    /**
    * MemberPress Courses - Section Completion Indicators
    *
    * This code adds visual indicators (green background + checkmark) when 100% of a section's
    * lessons/quizzes/assignments are completed.
    *
    * Add this to your theme's functions.php file.
    */

    // Add CSS styling for completed sections
    add_action('wp_head', 'mpcs_completion_styles');

    function mpcs_completion_styles() {
    ?>
    <style>
    /* ===== CUSTOMIZE COLORS HERE ===== */
    /* Background: #e8f5e8 (light green) */
    /* Border: #28a745 (green) */
    /* Checkmark: #28a745 (green) */

    .mpcs-section.completed .mpcs-section-header {
    background-color: #e8f5e8 !important;
    border-left: 4px solid #28a745 !important;
    }

    .mpcs-section.completed .mpcs-section-title-text::after {
    content: " ✔" !important;
    color: #28a745 !important;
    font-weight: bold !important;
    margin-left: 8px !important;
    }
    </style>
    <?php
    }

    // Add JavaScript to check completion status
    add_action('wp_footer', 'mpcs_add_completion_script');

    function mpcs_add_completion_script() {
    ?>
    <script>
    jQuery(document).ready(function($) {
    function updateSectionCompletion() {
    console.log('Checking for sections...');

    $('.mpcs-section').each(function() {
    var $section = $(this);
    var sectionTitle = $section.find('.mpcs-section-title-text').text().trim();
    console.log('Processing section:', sectionTitle);

    var $lessons = $section.find('.mpcs-lesson');
    var totalLessons = $lessons.length;
    var completedLessons = 0;

    // More precise completion detection
    $lessons.each(function() {
    var $lesson = $(this);
    var hasCompleteIcon = $lesson.find('.mpcs-ok-circled, .mpcs-lesson-complete').length > 0;
    var hasIncompleteIcon = $lesson.find('.mpcs-circle-regular, .mpcs-lesson-not-complete').length > 0;
    var hasStartButton = $lesson.find('a[href*="lessons"], .btn').text().toLowerCase().includes('start');

    console.log('Lesson:', $lesson.find('.mpcs-lesson-link').text().trim(),
    'Complete icon:', hasCompleteIcon,
    'Incomplete icon:', hasIncompleteIcon,
    'Start button:', hasStartButton);

    // Only count as completed if it has complete icon AND no start button
    if (hasCompleteIcon && !hasStartButton) {
    completedLessons++;
    }
    });

    console.log('Section', sectionTitle, 'has', totalLessons, 'lessons,', completedLessons, 'completed');

    if (totalLessons > 0 && completedLessons === totalLessons) {
    $section.addClass('completed');
    console.log('Marked section as completed');
    } else {
    $section.removeClass('completed');
    }
    });
    }

    updateSectionCompletion();
    setTimeout(updateSectionCompletion, 500);
    setTimeout(updateSectionCompletion, 1000);
    setTimeout(updateSectionCompletion, 2000);
    });
    </script>
    <?php
    }
    1. Click Update File to save the changes.
    2. Navigate to a course page where students have completed entire sections.
    3. Verify that completed sections now display a light green background and checkmark.

    2) Section Completion Indicators Not Appearing After Code Implementation

    The code has been added correctly, but section completion indicators are not displaying on course pages, even when all lessons in a section are completed.

    How to Test/Fix:

    1. Clear any caching plugins on your site (WP Rocket, W3 Total Cache, etc.).
    2. Check browser developer tools for JavaScript errors that might prevent the completion script from running.
    3. Test with a different browser or incognito mode to rule out browser-specific issues.
    4. Ensure jQuery is properly loaded on course pages by checking the page source.
    5. If issues persist, temporarily deactivate other plugins to check for conflicts.

    3) Indicators Appear Incorrectly or On Wrong Elements

    The completion indicators appear on elements other than course sections, or they display incorrectly due to theme conflicts or custom CSS overrides.

    How to Test/Fix:

    1. Inspect the course page HTML to verify MemberPress is using standard CSS classes (.mpcs-section.mpcs-lesson, etc.).
    2. If your theme uses custom CSS that overrides MemberPress styles, add !important declarations to the completion styles.
    3. Test the code on the default WordPress theme (Twenty Twenty-Three or similar) to isolate theme conflicts.
    4. Modify the CSS selectors in the code if your theme uses different class names for course elements.
    5. Check that the completion indicators only appear on course-related pages by testing other site pages.

    Important: Always create a backup of your site before adding custom code. Test the functionality thoroughly on a staging site before implementing on your live website. This code modification is not officially supported by MemberPress and may require updates if the plugin structure changes.

    Expected Results

    When all lessons, quizzes, and assignments within a course section are completed:

    • The section header background changes to light green (#e8f5e8);
    • A green left border (4px solid #28a745) appears on the section header;
    • A green checkmark (✔) appears next to the section title;
    • The indicators update automatically when lesson completion status changes;
    • Visual changes only appear on course pages, lesson pages, and classroom templates;

    Public Facing Documentation / Additional References

    Public Facing Documentation

    Developer Documentation

  • How to Use YellowPencil Plugin to Customize MemberPress Elements Without CSS Knowledge

    Summary

    YellowPencil is a visual CSS editor plugin that allows users to make styling changes to their MemberPress elements without writing code. This plugin provides a WYSIWYG (What You See Is What You Get) interface for hiding elements, repositioning content, changing colors, adjusting text sizes, and applying other visual modifications directly from the frontend.

    This document provides step-by-step guidance for using YellowPencil to customize MemberPress elements, including common troubleshooting scenarios when the plugin conflicts with themes, caching systems, or MemberPress-specific functionality.

    Troubleshooting

    Setting Up YellowPencil with MemberPress

    1. Navigate to Dashboard > Plugins > Add New.
    2. Search for YellowPencil Visual CSS Style Editor.
    3. Click Install Now and then Activate.
    4. Go to any page or post containing a MemberPress element to be modify.
    5. Look for the YellowPencil button in the WordPress admin bar or frontend interface.
    6. Click the YellowPencil button to launch the visual editor.
    YellowPencil editor button highlighted in WordPress admin bar

    Note: YellowPencil is a third-party plugin. MemberPress support cannot troubleshoot YellowPencil-specific functionality, but can help identify if MemberPress elements are causing conflicts.

    Common MemberPress Element Customizations

    1) Hide MemberPress Elements (Login Forms, Pricing Tables, Member Content)

    Users frequently want to hide specific MemberPress elements on certain pages or for specific user groups, but lack the specific CSS knowledge to target the correct selectors.

    How to Test/Fix:

    1. Open YellowPencil editor on the page containing the element.
    2. Click directly on the MemberPress element to hide (pricing table, login form, etc.).
    3. In the YellowPencil sidebar, locate the Extras panel.
    4. Set Visibility to none (appears as crossed-out eye icon) or use the Opacity slider to set to 0.
    YellowPencil Extras panel with Visibility set to none (crossed out eye icon) and Opacity slider controls
    1. Click Save.
    2. Click Live Preview (dual squares icon near Save button).
    3. Test the page in a new tab to verify the element is hidden.
    4. Clear any caching if changes don’t appear immediately.

    2) Reposition MemberPress Elements

    MemberPress elements may not align properly with theme layouts, requiring repositioning of pricing tables, member dashboards, or account forms.

    How to Test/Fix:

    1. Launch YellowPencil editor on the target page.
    2. Click on the MemberPress element to move.
    3. Navigate to the Positioning panel in YellowPencil sidebar.
    4. Change Position from static to relative for minor adjustments or absolute for precise positioning.
    5. Use the TopLeftBottom, or Right controls to adjust position, or drag the element using on-screen handles.
    YellowPencil Positioning panel with Position dropdown set to relative and drag handles for element positioning
    1. Click Save.
    2. Click Live Preview and test across different screen sizes.

    3) Customize Text Appearance in MemberPress Forms

    Default MemberPress text styling may not match theme design, requiring color, size, or weight adjustments for labels, buttons, or error messages.

    How to Test/Fix:

    1. Open YellowPencil on the page with MemberPress forms.
    2. Click on the specific text element (form label, button text, error message).
    3. Select the Text panel in YellowPencil sidebar.
    4. Modify Font SizeColorFont Weight, or Font Family as needed.
    5. For button styling, also check the Background and Border panels.
    YellowPencil Text panel with Font Size, Text Color, and Font Weight controls for customizing MemberPress form elements
    1. Click Save and test with Live Preview.

    4) Changes Not Appearing or Reverting

    YellowPencil modifications may not display due to caching conflicts, theme overrides, or MemberPress conditional content logic.

    How to Test/Fix:

    1. Clear all caching plugins, CDN cache, and browser cache.
    2. Test changes in an incognito/private browser window.
    3. Check if theme or plugin updates have overridden custom styles.
    4. Verify changes work for different user states (logged in vs. logged out).
    5. In YellowPencil, check if styles are applied globally or page-specific.
    6. Use browser developer tools to confirm CSS rules are not being overridden by higher-specificity selectors.
    7. Test on different devices and screen sizes for responsive behavior.

    Important Limitations and Considerations

    • YellowPencil only modifies CSS styling, not PHP functionality or MemberPress business logic
    • Changes are page-specific unless applied globally through YellowPencil’s global settings
    • Some advanced features (like color picker) are only available in YellowPencil Pro
    • Responsive design changes require testing across multiple device sizes
    • MemberPress conditional content may require separate styling for different user states
    • Theme updates may override custom modifications
    • Caching plugins can delay or prevent changes from appearing

    Public Facing Documentation / Additional References

    Public Facing Documentation

    Additional References