Ready to get started?Download WordPress

Plugin Directory

Paid Memberships Pro

The easiest way to GET PAID with your WordPress site. Flexible content control by Membership Level, Reports, Affiliates and Discounts

  • Firing activation hook on upgrade so menu doesn't disappear.


  • Updated PayPal Express/Standard/WPP gateways to throw an error when trying to cancel a subscription that is in pending or suspended status. A warning is shown to the user to contact the site owner or cancel the subscription through PayPal. The WP admin should also get an email about the failure. In the future, there may be a better way to handle these situations automatically, but PayPal doesn't advise how to "cancel" pending subscriptions.
  • Added optional $membership_id parameter to getLastMemberOrder() method of the MemberOrder class. So you can get the last member order of a specific level.
  • Added Slovakian translation. (Thanks, Peter Belko)
  • Added WP capabilities for each PMPro settings or report page. Admins are given these caps on plugin activation. Or you can set up other roles to use these caps. E.g. https://github.com/strangerstudios/pmpro-membership-manager-role/

  • Updated the Stripe API library to version 1.11.0.
  • Fixed issues where users upgrading or downgrading would have their subscriptions cancelled at Stripe.
  • Fixed issues where extra emails were being sent out when users cancelled a membership when using Stripe.
  • Generally made the Stripe integration better and ready for version 2.0.
  • The Stripe webhook will now add a 5 second delay before processing most requests. This is to ensure that PMPro has time to update the order during checkout (Stripe can sometimes receive a charge or cancellation, then send the webhook, and WP can process that in the split second it takes PMPro to save an order during checkout.). This prevents duplicate orders in the PMPro DB on some charges and fixes some issues with cancellations.
  • Setting constant PMPRO_STRIPE_WEBHOOK_DEBUG to true will send an email to the WP admin every time the Stripe Webhook is hit. You can also set it to an alternative email address or "log" to have it added to ../paid-memberships-pro/logs/stripe-webhook.txt.
  • Setting constant PMPRO_IPN_DEBUG to true will send an email to the WP admin every time the IPN handler is hit. You can also set it to an alternative email address or "log" to have it added to ../paid-memberships-pro/logs/ipn.txt.
  • Now showing the PMPro order ID/code in INVOICE emails instead of the Stripe order id when using the Stripe gateway.

  • Important fix for Braintree Payments users. Credit card information is now correctly updated in Braintree when users submit the form on the billing information page or checkout again on the site. (Thanks, Bryan Paronto and venrooy)
  • Updated Italian translation files. (Thanks, Angelo Giammarresi)
  • Fixed string wrapping in reports for translation.
  • Fixed PHP warning in membership stats report.


  • Added various hooks.
  • Updated the expiration field dropdown on the edit levels page to use translation strings. (Thanks, 24uurdates)
  • Fixed other missing strings for translation. Added Right-to-Left support. (Thanks, louy on GitHub.)
  • Added the pmpro_member_startdate filter to filter the pmpro_getMemberStartdate function. Passes $user_id, and $level_id as parameters.
  • Added pmpro.getMembershipLevelForUser and pmpro.hasMembershipAccess XMLRPC methods. Example usage: https://gist.github.com/strangerstudios/9099164
  • Moved the Terms of Service page/etc to right above the checkout button.
  • Now caching the pmpro_getAllLevels() function.
  • Added HTML wrappers to the JS on checkout.php. Helps with validation and potentially really old browsers.
  • Fixed warnings in includes/login.php.
  • Added pmpro_delete_discount_code and pmpro_delete_membership_level actions which run just BEFORE a membership level is deleted. Both pass the discount code ID or level ID respectively.
  • Added a third "short" parameter to the pmpro_getLevelCost() function. If set to true the "The price for membership is" text is left off the beginning. The new levels page uses this param.
  • Updated the table on the levels page to have one "Price" column showing the cost and expiration text. The text is generated using pmpro_getLevelCost and pmpro_getLevelExpiration instead of its own rules.
  • Updated level cost text to say $1/mo instead of $1 now and then $1/mo, etc. (Thanks, louy on GitHub.)
  • Added a debug by email method for the Authorize.net Silent Post handler. Add define('PMPRO_AUTHNET_SILENT_POST_DEBUG', true); to your wp-config.php. We will probably move the other services to debug by email as well.
  • PMPro will now only filter the from name and email if the default values are detected (WordPress wordpress@sitename.com). This fixes issues where the from name and email on form emails or other plugin emails were being swapped out with the PMPro settings, which was not always desirable. (Thanks, Helen Hou-Sandi and others.)
  • Added an "Only Filter PMPro Emails?" option to the email settings. If checked, only emails sent through the PMProEmail class will have their from name and email adjusted to match the PMPro email settings.
  • Added filter options to orders page in admin and export. (Thanks, HTCIA and Harsha Venkatesh)
  • Added Brazilian Portuguese translation. (Thanks, dballona on GitHub.)
  • Fixed some warnings. (Thanks, AlexBiddle on GitHub.)
  • Added pmpro_custom_advanced_settings hook to add settings to advanced settings page. Details on usage here: https://github.com/strangerstudios/paid-memberships-pro/pull/86 (Thanks, Jess Oros)
  • Updated addon categorization to reflect a lot of addons which have moved into the WordPress.org repository as well as updated versions.


  • Fixed bug where user_id = '' was breaking on some MySQL setups and keeping the pmpro_membership_orders table from being populated.
  • Updated "Joined" column in members list to use the WP date format setting.
  • Removed redundant phone number on checkout page if bphone is already set.
  • When adding extra columns to the Members List CSV export via pmpro_members_list_csv_extra_columns, we are now passing the original heading/field name to callback function. So you can use that in your callback functions. This generally means you can use one function that just dumps the meta value rather than requiring a separate function for each meta value.
  • Fixed bug where "Show Billing Fields" option was visible on the payment settings page for the testing gateway. (This option is only for Stripe.)
  • Fixed bug with choosing levels to hide ads from on advanced settings tab. (Thanks, Alain Fradette)
  • Fixed bug where PayPal Express was adding tax twice for subscription charges. (This does not fix existing subscriptions on the PayPal side.)
  • Fixed bug with the Stripe Webhook where non-PMPro orders were being added to PMPro via the webhook. If the customer_id cannot be found (i.e. it's a non-PMPro customer), the order is ignored. (Thanks, Jacob Glenn)
  • The getMemberOrderByPaymentTransactionID() function has been updated to return false if no payment_transaction_id is passed in (instead of finding the first order where the id is blank). This is inline with the getMemberOrderBySubscriptionTransactionID() function.
  • Fix to code that hides posts from search to NOT hide posts that a user has access to but might also be accessible by users of a different level. (Thanks, normanyung on GitHub)
  • Added a pmpro-en_GB translation that changes "State" to "County" on the billing address fields. (Thanks, alexbiddle on GitHub)


  • Added "Old Members" option to the members list page to view members who don't have an active membership, but did in the past. (Note that we don't differentiate between members who expired and who cancelled.)
  • The PayPal IPN Handler has been updated to process "subscr_cancel" messages from PayPal. This should cancel memberships in WP/PMPro when users or PayPal admins cancel a subscription at PayPal when using PayPal Express or Website Payments Pro. There are still known issues with syncing cancellations with PayPal Standard.
  • Fixed bug where "error cancelling subscription" emails were being sent out erroneously. These should only go out now if PMPro has trouble cancelling a subscription. If you got a lot of these before, you should get less. If you never got this, you might start getting it sometimes.
  • Orders are now set to "cancelled" status whether any attached subscriptions were cancelled or not. (Keeps us from trying again.)
  • Fixed bug where All Pages view in WP dashboard would sometimes redirect to the registration page if you had Theme My Login installed.
  • Setting startdate to NOW() when a user's level is changed via pmpro_changeMembershipLevel() using a level ID... also when admin's manually change a user's level. This fixes issues with PMPro Series where users who were given a level this way appear to have a start date in 1970, etc.
  • Fixed bug with the pmpro_save_discount_code_level filter where -1 was being passed as the code_id for brand new codes.
  • Updated "The ____ code has been applied to your order" message to it is wrapped for localization.
  • Now checking ICL_LANGUAGE_CODE instead of $_REQUEST['lang'] to support WPML using different language URL formats.
  • Unsetting $all_membership_levels[$user_id] at the bottom of pmpro_changeMembershipLevel().
  • Added $force parameter to pmpro_getMembershipLevelForUser($user_id, $force). If set to true, it will ignore the cached value and pull the level from the DB.
  • Added autocomplete="off" to credit card account number field on checkout and update billing pages.
  • Added an optional $seed parameter to pmpro_getDiscountCode() which will add $seed to the scrambled string. Useful when generating many discount codes quickly and time() might not have changed.
  • Now hiding "Change Membership Level" link from Member Links section of Membership Account page if PMPRO_DEFAULT_LEVEL is defined.
  • Clearing the AccountNumber value at checkout if it is XXXX..., e.g. when we mask the Stripe CC number. This way users will know they need to re-enter the credit card again. (Thanks, Gary)
  • Fixed bug on checkout page where html classes for the bstate field were being set based on the bcity value instead.
  • Fixed bug where there was no space after the "." in some level cost text. (Thanks, multiple observers ;)
  • Added some explanatory text to the payment settings page about taxes and SSL seals.
  • Added a pmpro_formatAddress() function to format billing addresses/etc.
  • Fixed bug where blank billing addresses were showing up in confirmation emails. If you use custom email templates, update them to use the !!billing_address!! variable instead of the full address section.
  • Design updates to checkout buttons, admin screens, etc, to work better with WP 3.8 and the TwentyFourteen theme.


  • Fixed all open bugs with 2Checkout gateway. You can now use this gateway for one time and recurring levels. We're still keeping the beta message though until we have further live testing.
  • The shortcodes for the PMPro pages (e.g. pmpro_levels/etc) will now work on multiple pages. Things may still act funny if you put the shortcodes on pages other than those set in the page settings, but you can do so if you know what you are doing. One limitation still in place is that you can only have one PMPro page shortcode per page. Whichever comes first will be used.
  • Added support for WPML. Simply make a copy of each PMPro page for each language. Set the PMPro page settings to the default language pages.
  • Updated pmpro.pot template along with a script gettext.sh that will allow us to easily update the pmpro.pot file when we need to.
  • Updated the pmpro_url function, should work the same but if you use addons or customizations and notice bugs around URLs, let me know.
  • Fixed bug where old membership data was being included in the members list export instead of the latest active membership data.
  • Filtering $morder->membership_level at checkout as well as $pmpro_level global.
  • When loading bemail and bconfirm email from user meta for existing users, just setting them both to $bemail so different emails don't show up.
  • Now sending a member's email address to Stripe when customers are created/updated.
  • No longer running wpautop on email via pmpro_send_email filter.
  • If first_name and/or last_name are passed at checkout, these are used to create a new user instead of bfirstname and blastname.
  • Added "view" links to the page settings page.
  • Fixed some potential warnings in adminpages/reports/login.php.


  • Updated PayPal IPN to use HTTP 1.1 and "Connection: Close" per recent PayPal IPN updates.
  • Fixed bug with slashes being added to the SSL Seal text when Payment Settings are saved.
  • Now applying the pmpro_checkout_level filter when a membership level is loaded from an order during the review step with PayPal Express checkouts. This will fix many customizations that might have not worked with PayPal Express.
  • Cleaned up PayPal Express API integration a bit. Fixes some bugs on sites with one-time payments and taxes calculated in.
  • Change the use_ssl payment setting. You can choose "No" now for gateways that require SSL. Just make sure you set it to Yes when going live or use another method to force SSL on your checkout page. You can also set it to Yes (use JavaScript redirect) to fix some issues that come up with infinite redirects on shared hosting with specific caching/proxy techniques.
  • Optimized the members list and orders CSV exports to run with less memory. Especially important for large sites.
  • Including Italian, French, Spanish/Peru, and Spanish/Chile language files contributed from the community. Thanks Mirco Babini (mirkolofio on GitHub) and Javier Monorové (zillionsk8 on GitHub)
  • Fixed the email template issue for admin emails as well. The email sent to admins for free checkouts won't include the empty billing address info anymore. (Thanks, inator on GitHub)
  • Now redirecting from /register/ to PMPro levels page when latest versions of Theme My Login are activated. Can still disable by returning false with the pmpro_register_redirect or pmpro_login_redirect filter.
  • Now showing a "renew" button for the current user's level on the levels page if their level is not recurring.
  • Fix in crons.php where in rare cases the pmpro_expiration_notice meta was not being set correctly for users, which might lead to multiple expiration warning emails.
  • Updated pmpro_next_payment to work for any cycle number or period. (Thanks, antonv and others.)
  • Now checking for a logged in user before trying to get a billing address to prepopulate at checkout.
  • Updated frontend.css to make sure that background gifs in error messages aren't repeated or applied to dropdowns.
  • Added some currencies: CNY, INR, IDR, KRW, TRY, VND, ZAR
  • All currencies now available to all gateways. You still need to make sure that your gateway supports the chosen currency.
  • Now sending all emails from the PMProEmail class from the pmpro_getOption("from_email") setting. Some were sent from the get_option("admin_email") setting before.

  • Using MySQL to calculate months since first order instead of date_diff, which is only available in PHP 5.3+


  • pmpro_longform_address and pmpro_international_addresses now default to true. See this gist to go back to US-specific address format: https://gist.github.com/strangerstudios/6478242
  • Added "Show Billing Address Fields" option for the Stripe payment gateway. Set to 'No' to hide billing address fields. Replaces the functionality of the "Stripe Lite" plugin.
  • Added language files for es_ES, es_CL, and es_PE. Thanks, Javier Monorové (zillionsk8 on GitHub).
  • Added language files for fr_FR. Thanks, Jérémy De la casa.
  • NOTE: Language files may not be complete. The get involved, join us on GitHub.
  • Added Cybersource and 2Checkout gateways in beta.
  • Added pmpro_paypal_button_image filter so you can override the URL of the PayPal button image.
  • Added a new report showing signups vs. cancellations, monthly recurring revenue, and lifetime value.
  • Fixed issue where the checkout_paid template was always being used for emails. It now checks if the level at checkout is free and sends either the checkout_free, checkout_paid, or checkout_trial templates accordingly. (Thanks, inator on GitHub)
  • Fixed sales report to not show $ when hovering over bars for "sales" vs. "revenue".
  • Fixed issue where PayPal Standard levels using a billing frequency > 1 (e.g. every 3 months) would have an extra payment charged after one period.
  • Fixed SQL error in discount code admin page that could result in cycle_periods of code levels saving incorrectly. (Thanks, Sam D'Amico)
  • Removed note that Payflow gateway doesn't support recurring payments. It does.
  • Now passing the membership level id in the $data var for checkout and cancellation emails. The key is "membership_id" so use $data['membership_id'] to check/access it.
  • No longer setting the subtotal property of orders when the "subscribe" method of the gateways is called. This will fix cases where an initial order or a subscription with a free trial showed a charge amount > $0.
  • Clicking enter in discount code box at checkout will no longer submit form and will click the "apply" button.
  • Hiding the "Apply" button on the checkout page if a discount code was passed in. Showing it if the text field is changed.
  • Authorize.net now supports CAD, GBP, and EUR currencies (for US merchants only) http://community.developer.authorize.net/t5/The-Authorize-Net-Developer-Blog/Authorize-Net-Expansion-into-Canada-the-United-Kingdom-and/ba-p/33690
  • Fixed notice in getfile.php
  • Fixed notices and expiration dates in login report.
  • Fixed notices in includes/notifications.php (Thanks, Nilesh)
  • Allowing dashes (-) in discount codes now.

  • Fixed warning when trying to load the "free" gateway on free level checkouts.
  • Fixed warning coming from login report tracking.
  • Changed all $wpdb->escape() calls to esc_sql() to fix notice.
  • Fixed another bug in revenue/sales report for daily charts. (backported to 1.7.2, but a few people who upgraded missed it)
  • Fixed bug on add/edit level page that was causing issues in some versions of IE.
  • Fixed bug where links in the email_header.html and email_footer.html templates were not being converted to true links.
  • Removed an extra $ from the PayPal Express confirmation emails.
  • Fixed loading of local (in the paid-memberships-pro/languages directory) translation files. (Should have some bundled with the plugin soon.)


  • Fixed the revenue/sales report to accurately track recurring sales and reports from earlier years.
  • Now trimming whitespace on any text field updated through the PMPro settings pages. This prevents issues like those that come up if you have whitespace in your Stripe API key, etc. Thanks, Scott Sousa.
  • Added discount code use tracking for PayPal Standard. Saving the use before the user goes to PayPal to pay.
  • Added discount code id and code columns to orders and members list CSV exports.
  • Changed default capability check to 'manage_options' (administrator), and added a filter named 'pmpro_edit_member_capability' to allow dev's to change this capability. Thanks, Scott Sousa.
  • Now removing empty (only includes the PMPro shortcode) PMPro pages when uninstalling PMPro. Thanks, Scott Sousa.
  • Now adding classes to the body tag (if the theme supports it through the body_class() function) to aid in design. Classes are pmpro-account, pmpro-billing, pmpro-cancel, pmpro-checkout, pmpro-confirmation, pmpro-invoice.
  • Adding $0 orders for free level checkouts (will help reporting).
  • Added pmpro_invoice_bullets_top and pmpro_invoice_bullets_bottom hooks to confirmation and invoice pages. Passes $pmpro_invoice.
  • Fixed members list CSV export for lists with search queries.
  • Added is_ssl() check to pmpro_https_filter so PMPro will add HTTPS to URLs even if the $besecure global hasn't been set yet. Thanks, Andrew Calaio at wpcurve.com.
  • Removed the pmpro_cron_trial_ending_warnings daily cron so trial ending emails will no longer go out. The function pmpro_cron_trial_ending_warnings() is still there if you want to call it yourself. There were issues on some sites where these emails were going out erroneously and also many ways of doing "custom trials" including setting the subscription start date back a certain number of days was not picked up as a trial by this script anyway.
  • Added the pmpro_cron_credit_card_expiring daily cron to send out warnings a month or so before credit cards on record are set to expire.
  • Updated pmpro_has_membership_access to return true if the $post_id is empty or cannot be found. This fixes issues where member warnings were being added to non-pages, e.g. the bbPress forums archive. To lock down "pages" like this, you'll need to use custom coding, URL detection, etc. Thanks, Scott Sousa (scottsousa on GitHub and WP.org) from Slocum Studio.


  • Design updates to frontend and backend pages.
  • Added Sales and Revenue Report.
  • Fix to Braintree webhook that should help get it verified by Braintree more easily.
  • Fix to PayPal IPNHandler to check both that either the primary or the business email address sent from PayPal matches the one stored in the payment settings.
  • Added pmpro_ajax_timeout hook to change the timeout limit from 2000 (2 seconds) to something else.
  • Fixed bug that occurred when the pmpro_register_redirect filter returned false or a blank link. Thanks, Vladimir Garagulya.
  • Added pmpro_paypal_standard_nvpstr and pmpro_set_express_checkout_nvpstr filters to change or add parameters to an name-value-pair string sent to PayPal in a couple cases.
  • Fixed checkout failure on Free level when in mySQL Strict Mode. (Thanks, inator on GitHub)
  • Only checking pmpro_checkForUpgrades in admin/dashboard now. (Thanks, topdown on GitHub)
  • No longer loading recaptcha library in the admin. Also wrapped the recaptchalib require in an init function to delay it a bit so we can check if other plugins have already loaded it.
  • PMPro-Mailchimp and WP-Bouncer have been moved into the WP repository. Other Add-on updates.
  • New users will now be set to the "default role" set in the General settings instead of spefically "subscriber". (Subscriber is the default default role though.) Thanks, Nabil Kadimi.
  • Wrapped strings in login report for translation.
  • Added indexes to the following columns in the pmpro_membership_orders table: status, payment_transaction_id, subscription_transaction_id, affiliate_id, affiliate_subid

  • Another database fix for new installs.

  • Fixed a performance issue added in

  • Fixed HUGE issue with the DB setup on fresh 1.7+ installs. If you installed version 1.7 or fresh (not upgraded from earlier version) then PMPro will not work until you upgrade to version
  • Removed from old PHP short tag use
  • Fixed generation of members only and non-logged in text on new installs.

  • Added the redirect away from wp-login.php page (was accidentally removed in version 1.7).
  • Added support for Theme My Login versions 6.3+
  • Fixed CSV downloads.
  • Fixed some warnings.
  • Fixed generation of cost text when using built in tax.
  • Added "pmpro_subscribe_order" filter.
  • Added an index to the user_id column of pmpro_memberships_users table which will help with performance of the new logins report and other user search functions.


  • Ready for localization efforts.
  • Addons tab in PMPro Settings in the dashboard.
  • Reports page in dashboard with login report.
  • Webhook code for Braintree Payments gateway.
  • If PayPal Standard is the active gateway, users without membership levels will be able to see the confirmation page with a message that PayPal is processing payment.
  • Fixed bug where PayPal recurring orders were being attributed to the wrong user (if no subscriber id was attached to the IPN message).
  • Fixed bug where users sometimes couldn't checkout with a discount code that made a level free.
  • Cleaned up code in base paid-memberships-pro.php file.
  • Updated the .pmpro_checkout tr.odd td line in frontend.css to use rgba with alpha transparency to work a bit better on dark background themes.
  • Fixed bug where a user's first_name and last_name meta fields might be overwritten by the billing name fields at checkout. It will still set them if the user's first and last name fields are blank. (Thanks, John Hamlin.)
  • Fixed bug where zipcode was shown instead of state in the members list CSV export. (Thanks, John Hamlin.)
  • Fix to show discount codes on free trial confirmation emails if one was used.
  • Added the pmpro_random_code filter so you can hook in and change invoice code/etc generation.
  • Correctly padding zeroes on credit card expiration dates like 09/2013 when using Stripe. This SQL statement should fix broken entries in your orders table: NOTE (1) Backup your database first. NOTE (2) Make sure you change the table name to match your WP prefix,etc. >>> UPDATE wp_pmpro_membership_orders SET expirationyear = CONCAT(SUBSTRING(expirationmonth,2,1), expirationyear), expirationmonth= CONCAT('0', SUBSTRING(expirationmonth,1,1)) WHERE expirationmonth > 12;
  • Wrapped some AJAX and service calls code in init() functions so they will more consistently work with hooks/filters. (Before if PMPro loaded before a plugin or bit of code that added filters/etc, the filters wouldn't get applied.)
  • Fixed Stripe JS to also send city to Stripe. (This is important because Stripe doesn't seem to show the address at all if the city is missing.)
  • Added 'pmpro_members_list_sql' hook to filter the SQL used on the members list page and CSV export.
  • Added 'pmpro_members_list_csv_heading' and 'pmpro_members_list_csv_default_columns' hooks to filter the default columns in the members list CSV. (e.g. to check role and remove columns)
  • Added 'pmpro_members_list_user_link' hook to filter the link and username displayed on the members list page. (e.g. to check role and remove link to edit user)
  • Checking that "status='active'" when finding subscriptions to cancel when deleting a level. This will keep PMPro from trying to cancel someone more than once... or trying to cancel inactive subscriptions.
  • Fixed bug where Sales Tax fields were hidden on the payment settings page if Stripe was chosen as the gateway.
  • No longer logging IPN activity to logs/ipn.txt by default. (Uncomment the lines at the bottom of services/ipnhandler.php to use the log to debug.)


  • Added recurring billing support to Payflow integration.
  • Fixed bug where an order's code was shown instead of the subscription ID on the edit order page.
  • Fixed some logic with determining if level settings are not compatible with the current gateway.
  • On notice and one DB query fix in upgradecheck.php submitted by pranjithkumar on GitHub. Thanks!

  • Fixed Braintree integration for production environments. Braintree needed to be told "production" instead of "live".
  • Removed !!field!! lines from a couple of admin emails.
  • Added login_link as data for the cancel_admin email template.


  • Added Braintree payments as a gateway option. This should be considered in "beta". Please get in touch if you are using Braintree payments with PMPro. Everything should function except that we're still working out an issue with the webhook handler.
  • Added a new dashboard page Orders to view all orders processed by PMPro with an option to export to CSV.
  • Fixed bug where "Your membership level has changed" emails were being sent out the first time a user's profile was edited, even if the level wasn't changing.
  • Removed the revenue estimate from the members list page. This causes performance issues on sites with many members. A new reports dashboard page is coming soon.
  • Not showing payment settings warning now when Payflow is setup with all values filled in.
  • Updated preheaders/billing.php to get the most recent successful order from the DB to use when updating. (ORDER BY id DESC in the query)
  • Added pmpro_stripe_subscription_deleted hook in stripe-webhook.php for when subscriptions are cancelled on the Stripe side. Use this code to cancel on your site as well: https://gist.github.com/strangerstudios/5093710
  • Now using $pmpro_currency_symbol when membership price is shown on the edit profile page in the dashboard/etc.
  • Added pmpro_authorizenet_post_url filter to use Authorize.net gateway class with a different post url, e.g. if you have a gateway that offers an Authorize.net compatibility mode.
  • Added pmpro_check_status_after_checkout filter so you can e.g. set the status to "pending" instead of "success" when a user checks out with the check gateway. They will still have access to the membership level, but you can update the status via the orders dashboard later.
  • Added pmpro_confirmation_order_status filter so you change which status the confirmation page looks for. Can return an array as well since the getLastMemberOrder method call on MemberOrder has been updated to support $status as an array.
  • Orders made via the check gateway now have PaymentType = "Check" and CardType = "".
  • Added a notes column to orders.
  • Fixed bug where discount codes were not showing up in checkout emails if the level was free.
  • Added some wpdb->escape() wrappers to the saveOrder method of MemberOrder which will fix some bugs with orders with fields with apostrophe's in them, etc.
  • Added checks for custom capabilities to the PMPro admin pages in case you want to give non-admins access. Caps are: pmpro_discountcodes, pmpro_emailsettings, pmpro_membershiplevels, pmpro_memberslist, pmpro_memberslist_csv, pmpro_orders, pmpro_orders_csv, pmpro_pagesettings, pmpro_paymentsettings
  • Added pmpro_memberslist_extra_cols_header and pmpro_memberslist_extra_cols_body hooks to add extra columns to the members list page.
  • Fixed pmpro_paypal_express_return_url_parameters filter to properly encode & and = so the params are properly added to the ReturnURL instead of being seen as extra params to the full PayPal Express URL. The PMPro Addon Packages plugin has been updated to take advantage of this to make that plugin more compatible with PayPal Express.
  • Fixed bugs with Strip webook: now listening for charge.succeeded and charge.failed, other fixes.

  • Fixed Members List bugs introduced in version

  • Revamped the ipnhandler code. It's much cleaner now and should be easier to support with all 3 PayPal APIs (Standard, Website Payments Pro, Express) working through the one handler.
  • Added Payflow Pro as a gateway option. Currently, only one-time charges is supported.
  • Added the pmpro_register_redirect filter to allow you to change the URL PMPro redirects wp-login.php?action=register to. Returning false or an empty string will result in no redirect from the register page.
  • Added pmpro_subscription_payment_failed hook that runs if a failed payment comes in through the IPN Handler, Authorize.net silent post, or Stripe web hook. do_action("pmpro_subscription_payment_failed", $old_order); $old_order is a MemberOrder object.


  • Fixed bug on Membership Billing page that was hiding the billing address fields.
  • Changed all of the instances of "firstpayment" order statuses to "success". Also running query to fix statues in the DB. This caused issues for levels with only a one-time payment, where the invoice wouldn't show up in their account page.
  • Fixed the PayPal Express gateway to correctly set the order transaction id to TRANSACTIONID instead of the PROFILEID.
  • Updated the IPN handlers to accept recurring_payment_id or subscr_id when checking for recurring payment orders.
  • Changed the site_url() in the javascript for discount codes on the checkout page to home_url(). home_url() is better to use in case users have their WP core files in a different directory.
  • You can now place email templates in a paid-memberships-pro/email folder in your theme and PMPro will use these before using the built in email templates. Just copy the file out of the wp-plugins/paid-memberships-pro/email folder, use the same filenames, and edit the file.
  • You can now place page templates in a paid-memberships-pro/pages folder in your theme and PMPro will use these before using the built in page templates. Just copy the file out of the wp-plugins/paid-memberships-pro/pages folder, use the same filename, and edit the file.
  • You can now place css templates in a paid-memberships-pro/css folder in your theme and PMPro will use these before using the built in page templates. Just copy the file out of the wp-plugins/paid-memberships-pro/css folder, use the same filename, and edit the file.
  • Fixed a bug where discount codes that reduced a level price to $0 were not being counted as "uses".
  • Added a pmpro_email_data filter to make it easier to add variables to edited email templates.
  • Added user_login to the data fields all of the emails for use by templates (use !!user_login!! in your template)
  • Added $wp_version to globals set in preheaders/checkout.php to properly compare versions later in the script and avoid a notice.
  • Added pmpro_email_filter hook to filter entire email object at once.
  • Warning fix: Updated email class to check if the template file exists before trying to load the template into the body. (Useful if you are using the PMProEmail class for your own emails.)


  • Fixed bugs with the Membership Billing page. (Thanks, adambware)
  • The getMembershipLevelForUser function and getMembershipLevel method of the MemberOrders class will now include expiration_number and expiration_period properties on the returned level. These are needed to properly extend membership levels when checking out for the same level.
  • Added pmpro_before_send_to_paypal_standard hook. This is executed at checkout before calling the sendToPayPal method on the order. The register helper plugin has been updated to update user meta fields during this hook in addition to the pmpro_after_checkout hook. (Because for PayPal Standard, when pmpro_after_checkout is called, the $_SESSION vars are unavailable to it. So other plugins relying on the pmpro_after_checkout hook may have issues with PayPal Standard.)
  • Re-Added !class_exists("Stripe") check before loading Stripe library. This assumes that other plugins using the Stripe lib are loading compatible versions and/or also checking first before loading the Stripe lib. (It's important that you test things if you are using multiple plugins loading Stripe. If the other plugins are loading old Stripe APIs first, PMPro may not work correctly.) The alternative is to namespace the Stripe library for PMPro which would take some more effort.
  • Now running email subject lines through html_entity_decode to avoid special characters for apostrophes/etc.
  • pmpro_is_login_page() now also checks if is_page("login")
  • The pmpro_login_redirect and pmpro_besecure functions, which handle HTTP/HTTPS logic have been updated. pmpro_besecure is now running on login_init instead of login_head to avoid a "cannot resend headers" error. pmpro_login_redirect will strip https from the URL if FORCE_SSL_LOGIN is set but FORCE_SSL_ADMIN is not set to avoid "need to login twice" bugs.
  • Updated code to support auto-hiding ads with newer versions of Easy AdSense.
  • Updated how the members list CSV is generated to avoid PHP notices when meta values are not found/etc. Also added a prefix to the enclose function in memberslist-csv.php (enclose => pmpro_enclose).
  • Now using get_option("date_format") when outputing a date in the admin, frontend, or in an email.
  • Proper trial support for Stripe. (We use the trial_period_days parameter of the Stripe plan object to push the first payment back - since the first payment is handled in its own transaction. We now also add days to this based on the # of trial subscriptions set for the level in the admin.
  • Added a pmpro_require_billing javascript variable when using Stripe. If a discount code changes the membership level to free, pmpro_require_billing will be set to false and the Stripe JS checks won't fire.


  • Ready for WordPress 3.5
  • Fixed issues in the PayPal IPN Handler that were leading to errors when users would checkout using the PayPal standard gateway.

  • Fixed "invalid gateway" bug when using PayPal Express option with the PayPal/PayPalExpress gateway.
  • Fixed some warnings.


  • Fixes in the new pmpro_getMemberStartdate and pmpro_getMemberDays functions.
  • Fixes to SQL queries for the expiration and trial ending crons.
  • Added a pmpro_required_user_fields filter similar to the pmpro_required_billing_fields filter.
  • Added a function pmpro_setMessage($message, $type) that sets $pmpro_msg and $pmpro_msgt globals if they aren't set already.
  • Added a function pmpro_getClassForField($field) that will return a string including "pmpro_error" or "pmpro_required" if applicable. You can filter the classes added to the fields via the pmpro_field_classes filter.
  • Showing * on required fields via javascript on the checkout page.
  • Updated checkout page to highlight in red fields that are related to the error message shown.
  • Added headers property to the PMProEmail object. You can add headers (e.g. to add a cc or bcc) to PMPro emails using the pmpro_email_headers filter.
  • Updated Stripe library to version 1.7.10. Updated PMPro to take advantage of new "interval_count" parameter in subscriptions, so you can now have subscriptions setup for "every 2 months", etc.
  • Fix to pmpro_checkout_start_date_keep_startdate filter added in 1.5.5
  • Added "Start Date" and "End Date" to emails sent to admins when a membership is cancelled.
  • Now checks for CSS files in a paid-memberships-pro subfolder of your active theme and uses those admin.css, frontend.css, and print.css files instead if they exist. (Going to move email and page template checks to that subfolder in the future as well.)


  • Updated pmpro_check_site_url_for_https function to cache the siteurl to limit DB queries.
  • Added includes/filters.php to store hacks/filters/actions that were originally developed outside of the PMPro core and brought in later... or just things that are cleaner/easier to impement via hooks and filters.
  • Added a "delay" property to the membership shortcode. E.g. [membership level="1" delay="7"]...[/membership] will show that content if a member has had level 1 for at least 7 days.
  • If a member checks out for the same level again (extending their membership), the startdate added to pmpro_memberships_users will be their old startdate.
  • If a member checks out for the same level again, the remaining days on their existing membership will be added to their new enddate. So e.g. if a user starts an annual membership in April 2013, then checks out again (extends) their membership in February 2014, their new enddate will be April 2015 instead of February 2015. (NOTE: if you were doing this through the custom code here - https://gist.github.com/3678054 - you should remove your custom code.)
  • Fixed bug where you couldn't remove all required membership levels from a page/post. (Thanks, lisaleague)
  • Updated the button CSS included in paid-memberships-pro/css/frontend.css. I added a pmpro_ prefix to these classes so they don't conflict with other .btn CSS rules. I also changed the rules a bit to show the buttons more consistently. If you relied on the old CSS rules, you may need to tweak your theme to get things looking right.


  • Added a gateway check to preheaders/checkout.php. Mischivous users used to be able to bypass payment by passing &gateway=check or something similar to the checkout page. PMPro would then use the check gateway to checkout. Now only the active gateway option in the payments settings or gateways added via the new pmpro_valid_gateways filter (1 parameter is the array of gateways, add/edit the gateways and return the array). It is important that all PMPro users upgrade to keep mischivious users from accessing your site for free. Any site currently enabling multiple gateway options will need to add code to set the valid gateways. More info here: http://www.paidmembershipspro.com/2012/06/offering-multiple-gateway-options-at-checkout/
  • Fixed bug where level restrictions would be deleted if a page were updated via quick edit.
  • Added if(!class_exists("Stripe")) to the Stripe class definition. This should help with some conflicts if other plugins have their own Stripe library. (Going to udate the Stripe library in the next version and work on supporting new Stripe functionality.)
  • Fixed a bug where copying a level didn't properly set recurring billing settings. (Thanks, AtheistsUnited)
  • Fixed some typos. (Thanks, AtheistsUnited)
  • Fixed some warnings.

  • Fixed bug in expiration warning cron query. (Backported to 1.5.3)


  • Added PayPal Standard Gateway
  • Added code to support using Stripe with the minimal billing fields. Use add_filter("pmpro_stripe_lite", "__return_true"); to enable this
  • Added an Email setting to send the default WordPress new user email(wp_new_user_notification) or not. By default this was being sent along with the PMPro checkout confirmation email. Now only the checkout confirmation email will be sent unless you check the new setting. You can still override this with the pmpro_wp_new_user_notification filter.
  • Fixed bug: Now re-hiding the "Processing..." message if there is a Stripe javascript error at checkout.
  • Updated MemberOrder method saveOrder to check for gateway and gateway_environment properties when inserting. If none are found, it will use what is set in your payment settings. This allows you to set the gateway on a MemberOrder object and save the order with that gateway instead of the default.
  • Now only showing the check instructions if the gateway is "check" AND the level is not free.
  • Added a check to the notification code in the settings header so it wouldn't display NULL in the notification space if WP passes that back.
  • Some warning fixes.
  • Fixed a bug in the PayPal Express gateway class where the pre-tax amount was being passed to PayPal instead of the tax-computed amount.
  • Added Canadian Dollars as a currency option for Stripe.
  • Fixed typo/bug with saving trial amounts in the memberships_users table after checkout. (Thanks, Badfun)
  • Fixed bug in initial and recurring revenue calculation on members list page.
  • Fixed bug when setting membership_level of current user after checkout that could cause various issues. (Thanks, drrobotnik)
  • Fixed bug in Stripe webhook that resulting in cancelation emails being sent to the 1st user in the DB vs. the user who cancelled. (Thanks, Kunjan of QuarkStudios.com)
  • The getLastMemberOrder() method of the MemberOrder class now returns the last order with status = 'success' by deafult. You can override this via the second parameter of the function. So getLastMemberOrder($user_id, "cancelled") to get the last cancelled order or getLastMemberOrder($user_id, false) to get the last order no matter the status.
  • Added pmpro_authnet_silent_post_fields filter and pmpro_before_authnet_silent_post and pmpro_after_authnet_silent_post hooks to the Authorize.net silent post handler. All hooks are passed the $fields variable built at the top of the script that mirrors the $_REQUEST array.

  • Fixed bugs with pmpro_hasMembershipLevel.
  • Added ability to use the 0 level (non-member) in arrays passed to pmpro_hasMembershipLevel. e.g. pmpro_hasMembershipLevel(0,1,2) = has no membership, level 1, or level 2.
  • Fixed bug with the pmpro_after_change_membership_level hook, where a level object was passed instead of the id. The object would be nice to have, but we've been passing the id in the past. I changed it back for reverse compatibility. (You can always look up the level by level_id and user_id.


  • Added "Pay by Check" as a gateway option. Users gain immediate access. You can show instructions for who to write the check out to, where to mail it, etc.
  • Added uninstall.php script. (Thanks, badfun)
  • Fixed bug where the "Use SSL" option reverted to "No" for Testing, Stripe, and PayPal Express gateways whenever the payments settings page was loaded.
  • Fixed bug where the IPN Handler URL was not showing up when PayPal Express was selected.
  • Fixed bug where PMPro was not sending the proper trial amount to PayPal when using Website Payments Pro or PayPal Express.
  • Added id and status fields to the pmpro_memberships_users table and updated all code to use these fields. This is important for allowing multiple membership levels and tracking cancelled orders. (Thanks, Zookatron!)
  • Appending ?level=# to the confirmation page URL after checkout to aid in analytics tracking.
  • No longer filtering pages/posts from search results if "show excerpts" is set to YES.
  • Showing tax on invoices if applicable.
  • Sending tax amount to PayPal Express again.
  • Added code to force HTTPS if the siteurl option starts with https:
  • Hiding billing information box on Membership Account page if the last invoice was by check or paypal express.
  • Added pmpro_email_days_til_expiration and pmpro_email_days_til_trial_end to change how many days before expiration/etc to send an email. The default is 7.
  • Fixed typo/bug in preheader/checkout.php RE the pmpro_stripe_verify_address hook. (Thanks, Oniiru!)
  • Updated the_excerpt filters to prevent PMPro messages from being added to an excerpt twice in some setups.
  • the_content filter removes any class="more-link" class from the content if showing an excerpt.


  • Fixed bug in getfile.php introduced in 1.5.
  • Fixed bug in the saveOrder method of the Member Order class. When "updating" vs. "inserting" the $id property of the class was being wiped out. This sometimes caused problems if the id was needed later, e.g. with PayPal Express updating orders.
  • Now checking if(!defined("WP_USE_THEMES")) instead of if(function_exists("get_userdata")) to see if WP is already loaded.
  • Added initial payment to the fee column of the members list.
  • Added initial payment as a column in the members list CSV export.
  • Added the pmpro_members_list_csv_extra_columns filter to add columns to the Members List CSV export. Sample usage here: https://gist.github.com/3111715


  • Very important security fix. Please upgrade to 1.5.
  • The Members List CSV export is now executed through admin-ajax.php and will only work if you are logged in as an admin (can manage options).
  • Fixed service scripts to work if logged in or logged out.
  • Changed the applydiscountcode service to going through the site_url() instead of admin-ajax.php to avoid HTTP/HTTPS issues.


  • Important: Fixed handling of services sent through admin-ajax.php. Your silent post/ipnhandler URLs, etc, may have been updated.
  • Added stripslashes() to membership description output on the checkout page.
  • The pmpro_getLevel() function may return the wrong level on the levels, checkout, or account page where another $pmpro_levels array was setup. (The array pmpro_getLevel uses used the level id as the array keys. The older $pmpro_levels used 0-n.) To fix this, I added a pmpro_getAllLevels($include_hidden = false) function and now use that function on the levels, checkout, and account pages. The function queries the database for all levels and then puts them into an array where the level ids are the keys.
  • Fix for !!billing_country!! in emails. (Somehow a previous fix for this got overwritten. My bad.)
  • Settings $pmpro_level->code_id to $discount_code_id if a valid discount code is applied to a level at checkout. This is useful for determining if/what discount code was applied to the level when processing it in hooks.
  • Added pmpro_getDomainFromURL() and using that to set PMPRO_URL.
  • New hooks when orders are added/updated: pmpro_update_order (before update), pmpro_updated_order (after update), pmpro_add_order (before add), pmpro_added_order (after add). (Thanks, zookatron!)


  • Fixed !!siteemail!! values for email templates.
  • Adjusted display of "processing" message next to checkout button when clicked.
  • Added billing_country to orders table in DB and the memberorder class. Handling countries better through the code.
  • Removing closing ?> at the bottom of various files while working through. This can avoid errors on some setups.
  • Using wp_enqueue_style to load plugin stylesheets now.
  • Added the pmpro_getCheckoutButton($level_id, $button_text, $classes) function and [pmpro_button level="1"] shortcode to add buttons with links to more easily level checkout pages into your pages and themes. Copied over btn and btn-primary styles from Member Lite theme.
  • Updated include/require statements to work if the wp-content folder has been renamed or moved.
  • Added code to load scripts in the services folder via admin-ajax.php. (Helps when the plugins folder is not where PMPro expects it to be.)
  • The discount code AJAX call is using the new service URL (/wp-admin/admin-ajax.php?action=applydiscountcode).
  • Added IPN/Silent Post/Webhook instructions to payment settings page.


  • Fixed some notices in the PayPal gateway code.
  • No longer calling Stripe JS at checkout if the level is free.
  • Fixed some HTTPS handling for ISS hosting. (IIS sets $_SERVER['HTTPS'] to "off" or "on" instead of TRUE or FALSE.)
  • Added #pmpro_processing_message to checkout page which is shown when the submit button is clicked. You can override the message with the pmpro_processing_message filter. You can tweak the CSS to show this differently as well.


  • No longer trying to setup a subscription with Stripe for levels with only an Initial Payment amount.
  • Updated recaptchalib.php, which fixes issues with using recaptcha.
  • Now setting the first_name and last_name meta fields at checkout to match the business first and last name. (Previous scripts to add additional first/last names to the checkout field should override these.)
  • Updated the save profile code to only null out the expiration date for a membership if a blank expiration is explicitly passed through the form. If you had other plugins allowing users to edit their profile, etc, it might not have been passing the expiration date and thus updating users expiration dates. Admins and users would have gotten emails.
  • Some updates to applydiscountcodes.php service to support plugging into how discount codes function. Added the pmpro_discount_code_level filter to applydiscountcodes.php.

  • Removed debug calls to krumo() which would cause fatal errors in certain situations. Please upgrade. (Note that PMPro versions that go three dots deep are usually the most important ones :)


  • Now setting a var "code_level" in javascript in applydiscountcode.php so it can be used to manipulate prices, etc after applying a discount code.
  • Added the pmpro_cancel_previous_subscriptions filter, which is set to false will skip cancelling the old membership level/subscription at checkout. This is dangerous, but is used by the pmpro-addon-packages plugin to have an addon charge without affecting the old subscription. This works because the user is checking out for the same membership level. (So they don't really have > 1 membership level.)
  • Trimming strings sent to the Authorize.net API in the subscribe and update calls.


  • Using get_admin_url instead of home_url in various places so the links will work on sites installed in a subdirectory. (Notifications, admin bar, pagination in admin screens, etc.)
  • Wrapping some XML fields in Authorize.net API calls in to avoid issues when non-text characters (e.g. &) are included in the level name, etc.


  • Fixed a bunch of notices and warnings on discount codes page in admin.
  • Added hooks for changing the discount code page: pmpro_save_discount_code_level, pmpro_save_discount_code, pmpro_discount_code_after_settings, pmpro_discount_code_after_level_settings. Look them up in discountcodes.php to see how they work.
  • Updated pmpro_send_html(), which filters emails, to use wpautop instead of nl2br. This will fix any extra double spacing you may have noticed in your emails.
  • Added a stripslashes around the membership level confirmation text on the confirmation page. Extra slashes were breaking links, etc.
  • Added membership level to subject of checkout confirmation email sent to admins.


  • Fixed bug that was added slashes into a level's description and confirmation when saving.
  • Removed wp_editor use is the blog is running a version of WordPress < 3.3. (Note: We will only officially support the latest version of WordPress with each release.)
  • Added the pmpro_pages_shortcode_{membership page} filter. This can be used to filter the content output by the pmpro_checkout and other page shortcodes. e.g. use pmpro_pages_shortcode_checkout to tweak the HTML output of the pmpro_checkout shortcode. The pages are "account", "billing", "cancel", "checkout", "confirmation", and "levels".
  • Added a "use_ssl" option. For the PayPal Website Payments Pro and Authorize.net gateways, this must be on. For Stripe, this will default to on, but can be switched off. For PayPal Express and the test gateway, it will default to off but can be switched on. When on, the checkout and update billing pages will be forced to be served over SSL. If off, those pages will redirect to non-ssl versions. The previous hooks/filters for overriding this will still work.
  • Added pmpro_save_membership_level and pmpro_membership_level_after_other_settings hooks to be able to add fields to the new/edit membership level page.
  • Fixed some more warnings and notices.
  • Updated checkout page to use pmpro_isLevelFree() in logic to display recaptcha or not.


  • Fixed critical bugs with PayPal Express.
  • When a PayPal cancellation returns error "11556" (The subscription must have status "active" or "suspended".) I am cancelling the membership without an error. Most likely the PayPal subscription was already cancelled on the P

Requires: 3.5 or higher
Compatible up to: 3.8.3
Last Updated: 2014-3-19
Downloads: 126,478


4 stars
4.4 out of 5 stars


79 of 173 support threads in the last two months have been resolved.

Got something to say? Need help?


Not enough data

0 people say it works.
0 people say it's broken.

100,1,1 100,1,1 0,1,0 100,2,2 67,3,2 0,1,0 100,1,1
100,1,1 100,1,1
100,1,1 100,1,1 100,1,1 100,1,1 100,1,1 100,1,1 100,1,1 100,1,1
100,1,1 50,2,1 0,1,0
100,1,1 100,1,1
100,1,1 100,1,1 100,2,2
100,1,1 100,1,1 100,1,1
100,1,1 100,1,1 100,1,1 100,1,1 67,3,2 0,1,0
0,1,0 50,2,1 100,2,2 100,3,3
100,1,1 100,1,1
100,1,1 100,1,1 50,2,1